문제

내 소프트웨어 개발 프로그래밍 수업에서는 RSS 피드용 "피드 관리자" 유형의 프로그램을 만들기로 되어 있었습니다.FeedItems 구현을 처리하는 방법은 다음과 같습니다.

훌륭하고 간단합니다.

struct FeedItem {
    string title;
    string description;
    string url;
}

나는 그것에 대해 표시를 받았습니다. "올바른"예제 대답은 다음과 같습니다.

class FeedItem
{
public:
    FeedItem(string title, string description, string url);

    inline string getTitle() const { return this->title; }
    inline string getDescription() const { return this->description; }
    inline string getURL() const { return this->url; }

    inline void setTitle(string title) { this->title = title; }
    inline void setDescription(string description){ this->description = description; }
    inline void setURL(string url) { this->url = url; }

private:
    string title;
    string description;
    string url;
};

지금 나에게 이것은 어리석은 것 같습니다.나는 솔직히 내가 감점을 받았다는 것을 믿을 수 없습니다. 이것이 훨씬 더 많은 오버헤드로 수행하는 것과 정확히 동일한 작업을 수행할 때입니다.


C#에서 사람들이 항상 이렇게 하는 방법이 생각납니다.

public class Example
{
    private int _myint;

    public int MyInt
    {
        get
        {
            return this._myint;
        }
        set
        {
            this._myint = value;
        }
    }
}

내 말은 내가 얻다 왜 그렇게 하는지, 나중에 setter에서 데이터의 유효성을 검사하거나 getter에서 데이터를 증가시키고 싶을 수도 있습니다.그런데 너희들은 그냥 이렇게 하는 것이 어때? 까지 그런 상황이 나오나요?

public class Example
{
    public int MyInt;
}

죄송합니다. 이것은 일종의 호언장담이고 실제로 질문은 아니지만 중복성이 저를 화나게 합니다.필요하지 않은 게터와 세터가 왜 그렇게 사랑을 받는가?

도움이 되었습니까?

해결책

"모범 사례"와 스타일의 문제입니다.

  • 데이터 구성원을 직접 노출시키고 싶지 않습니다. 당신은 항상 그들이 접근하는 방법을 제어 할 수 있기를 원합니다. 나는이 경우 약간 말도 안되는 것처럼 보이지만, 그 스타일을 가르쳐서 익숙해지기위한 것입니다.
  • 클래스의 일관된 인터페이스를 정의하는 데 도움이됩니다. 당신은 항상 무언가를 얻는 방법을 알고 있습니다 -> get 방법을 부릅니다.

그런 다음 재사용 문제도 있습니다. 도로 아래로 누군가가 데이터 구성원에 액세스 할 때 발생하는 일을 변경해야합니다. 클라이언트가 코드를 다시 컴파일하도록 강요하지 않고도 그렇게 할 수 있습니다. 클래스의 메소드를 단순히 변경하고 새로운 논리가 사용되도록 보장 할 수 있습니다.

다른 팁

주제에 대한 좋은 시간이 있습니다. 왜 게터와 세터를 사용하는지.

당신이 스스로에게 물어보고 싶은 질문은 "당신이 깨달았을 때 3 개월 후에 일어날 일 FeedItem.url 하다 검증되어야하지만 이미 287 개의 다른 클래스에서 직접 참조되어 있습니까? "

필요하기 전에이 작업을 수행 해야하는 주된 이유는 버전 작성입니다.

필드는 속성과 다르게 행동합니다. 특히 LValue로 사용할 때 (특히 C#에서는 종종 허용되지 않는 경우). 또한 나중에 속성 get/set 루틴을 추가 해야하는 경우 API를 끊어야합니다. 클래스 사용자는 새 버전을 사용하려면 코드를 다시 작성해야합니다.

이 작업을 수행하는 것이 훨씬 안전합니다.

C# 3, BTW는 이것을 더 쉽게 만듭니다.

public class Example
{
    public int MyInt { get; set; }
}

나는 당신에게 절대적으로 동의합니다. 그러나 인생에서 당신은 아마도 옳은 일을해야 할 것입니다. 학교에서는 좋은 자국을 얻는 것입니다. 직장에서는 사양을 충족시키는 것입니다. 완고하고 싶다면 괜찮습니다. 괜찮습니다. 자신을 설명하십시오. 댓글의 기지를 다루어 손상을 최소화하십시오.

위의 특정 예에서는 URL을 검증하고 싶을 수도 있습니다. 어쩌면 당신은 제목과 설명을 소독하고 싶을 수도 있지만, 어느 쪽이든 이것이 수업 디자인 초기에 말할 수있는 일종이라고 생각합니다. 의견에 당신의 의도와 이론적 근거를 언급하십시오. 검증이 필요하지 않으면 getter와 setter가 필요하지 않으면 절대적으로 맞습니다.

단순성 지불, 귀중한 기능입니다. 종교적으로 아무것도하지 마십시오.

무언가가 간단한 구조라면, 그것은 단지 데이터이기 때문에 말도 안됩니다.

이것은 실제로 사람들이 여전히 수업에 대한 아이디어를 얻지 못한 OOP의 시작으로의 후퇴 일뿐입니다. getId ()를 언젠가 허블 망원경으로 원격 호출로 변경할 수있는 경우를 대비하여 수백 가지의 GET 및 설정 방법을 가질 이유가 없습니다.

당신은 정말로 그 기능을 최상위 수준에서 원합니다. 맨 아래에는 무가치합니다. 즉, 당신은 순수한 가상 클래스를 전송하는 복잡한 방법을 가지고있을 것입니다. 모든 구조물에 무작위로 배치하는 것은 농담이며, 포드에 대해서는 절대로 수행해서는 안됩니다.

클래스의 어느 버전에도 행동이 없기 때문에 두 옵션 모두 약간 잘못되었을 수 있습니다. 더 많은 맥락없이 더 말하기는 어렵습니다.

보다 http://www.pragprog.com/articles/tell-dont-ask

이제 당신의 상상해 보자 FeedItem 클래스는 훌륭하게 인기를 얻었으며 모든 곳에서 프로젝트에서 사용되고 있습니다. 귀하는 (다른 답변이 제안한대로) 제공된 URL을 검증 할 필요가 있다고 결정합니다.

행복한 날, 당신은 URL에 대한 세터를 작성했습니다. 이를 편집하고 URL을 검증하고 유효하지 않은 경우 예외를 던집니다. 새 버전의 클래스를 릴리스하고 사용하는 모든 사람이 행복합니다. (이 트랙을 유지하기 위해 확인되지 않은 예외를 무시하자).

제외하고, 당신은 화난 개발자로부터 전화를받습니다. 응용 프로그램이 시작될 때 파일에서 Feeditems 목록을 읽고있었습니다. 그리고 이제 누군가가 구성 파일에서 약간의 실수를한다면, 새로운 예외가 발생하고 전체 시스템이 시작되지 않습니다. 하나의 프리깅 피드 항목이 잘못 되었기 때문입니다!

메소드 서명을 동일하게 유지했을 수도 있지만 인터페이스의 의미를 변경하여 종속 코드를 중단했습니다. 이제, 당신은 고지대를 가져 와서 프로그램을 다시 작성하도록 지시하거나 겸손하게 추가 할 수 있습니다. setURLAndValidate.

"모범 사례"를 코딩하는 것은 종종 프로그래밍 언어의 발전으로 쓸모 없게됩니다.

예를 들어, C#에서 Getter/Setter 개념은 속성 형태로 언어로 구워졌습니다. C# 3.0은 자동 속성을 도입하여 컴파일러가 자동으로 Getter/Setter를 생성합니다. C# 3.0은 또한 객체 초기화기를 도입했는데, 이는 대부분의 경우 더 이상 속성을 초기화하는 생성자를 선언 할 필요가 없음을 의미합니다.

따라서 당신이하고있는 일을하는 표준 C# 방법은 다음과 같이 보일 것입니다.

class FeedItem
{
    public string Title { get; set; } // automatic properties
    public string Description { get; set; }
    public string Url { get; set; }
};

그리고 사용법은 다음과 같습니다 (객체 이니셜 라이저 사용) :

FeedItem fi = new FeedItem() { Title = "Some Title", Description = "Some Description", Url = "Some Url" };

요점은 당신이 사용하는 특정 언어에 대한 모범 사례 또는 표준적인 방식이 무엇인지 배우고 더 이상 의미가없는 오래된 습관을 복사하지 말아야한다는 것입니다.

C ++ 개발자로서 저는 회원들이 항상 일관되도록 개인을 비공개로 만듭니다. 그래서 나는 항상 px가 아닌 px ()를 입력해야한다는 것을 알고 있습니다.

또한 보통 세터 방법을 구현하지 않습니다. 객체를 변경하는 대신 새 개체를 만듭니다.

p = Point(p.x(), p.y() + 1);

이것은 캡슐화도 보존합니다.

캡슐화가 말도 안되는 지점이 절대적으로 있습니다.

코드에 도입되는 추상화가 많을수록 최신 교육 교육이 커지면 학습 비용이 발생합니다.

C를 아는 모든 사람은 기본 언어 C 표준 라이브러리 만 사용하는 끔찍하게 쓰여진 1000 줄 함수를 디버깅 할 수 있습니다. 모든 사람이 발명 한 프레임 워크를 디버깅 할 수있는 것은 아닙니다. 도입 된 모든 레벨 캡슐화/추상화는 비용에 대해 무게를 측정해야합니다. 그것은 그만한 가치가 없다고 말하는 것은 아니지만, 항상 당신은 당신의 상황에 대한 최적의 균형을 찾아야합니다.

소프트웨어 산업이 직면한 문제 중 하나는 재사용 가능한 코드의 문제입니다.큰 문제입니다.하드웨어 세계에서는 하드웨어 구성 요소가 한 번 설계되면 나중에 구성 요소를 구입하여 함께 사용하여 새로운 것을 만들 때 디자인이 재사용됩니다.

소프트웨어 세계에서는 구성 요소가 필요할 때마다 계속해서 디자인합니다.매우 낭비적입니다.

캡슐화는 생성된 모듈을 재사용할 수 있도록 보장하는 기술로 제안되었습니다.즉, 모듈의 세부 사항을 추상화하고 나중에 해당 모듈을 더 쉽게 사용할 수 있도록 명확하게 정의된 인터페이스가 있습니다.인터페이스는 또한 객체의 오용을 방지합니다.

클래스에서 작성하는 간단한 클래스는 잘 정의된 인터페이스의 필요성을 적절하게 설명하지 않습니다."하지만 왜 사람들은 그 상황이 발생할 때 까지이 일을하지 않습니까?" 작동하지 않습니다 실생활.소프트웨어 엔지니어링 과정에서 배우는 것은 다른 프로그래머가 사용할 수 있는 소프트웨어를 엔지니어링하는 것입니다..net 프레임워크 및 Java API에서 제공하는 것과 같은 라이브러리 작성자에게는 이 원칙이 절대적으로 필요하다는 점을 고려하세요.캡슐화가 너무 많은 문제라고 판단하면 이러한 환경에서는 작업하기가 거의 불가능할 것입니다.

이러한 지침을 따르면 향후 고품질 코드가 생성될 것입니다.자신뿐만 아니라 다른 사람도 혜택을 받을 수 있기 때문에 해당 분야에 가치를 추가하는 코드입니다.

마지막으로, 캡슐화를 사용하면 모듈을 적절하게 테스트하고 모듈이 작동하는지 확실하게 확인할 수 있습니다.캡슐화가 없으면 코드를 테스트하고 검증하는 것이 훨씬 더 어려울 것입니다.

물론 getters/setters는 모범 사례이지만 글을 쓰고 더 나쁘게 읽기에 지루합니다.

우리는 수십 명의 회원 변수와 동반 getters/setters를 가진 클래스를 몇 번 읽었습니까? x ','y의 값 가져 오기 ','y의 값을 설정 ','z ','zzzzzzzzzzzzz의 값을 설정하십시오. 때림!

이것은 매우 일반적인 질문입니다."그런데 너희들은 그 상황이 발생할 때까지 그냥 이렇게 하는 게 어때?"이유는 간단합니다.일반적으로 나중에 수정/재테스트/재배포하는 것이 아니라 처음에 올바르게 수행하는 것이 훨씬 저렴합니다.오래된 추정에 따르면 유지 관리 비용은 80%이며 유지 관리 비용의 대부분은 귀하가 제안한 것과 정확히 같습니다.누군가가 문제를 겪은 후에야 옳은 일을 하는 것입니다.처음부터 올바르게 수행하면 더 흥미로운 일에 집중하고 생산성을 높일 수 있습니다.

엉성한 코딩은 일반적으로 수익성이 매우 낮습니다. 고객은 제품을 신뢰할 수 없고 사용 시 생산성이 떨어지기 때문에 불만을 나타냅니다.개발자들도 만족하지 않습니다. 그들은 패치 작업에 80%의 시간을 소비하는데 이는 지루합니다.결국 고객과 훌륭한 개발자 모두를 잃게 될 수 있습니다.

나는 당신에게 동의하지만 시스템에서 살아남는 것이 중요합니다. 학교에있는 동안 동의하는 척. 다시 말해서, 표시되는 것은 당신에게 해롭고 당신의 원칙, 의견 또는 가치를 위해 표시되는 것은 가치가 없습니다.

또한 팀이나 고용주에서 일하는 동안 동의하는 척합니다. 나중에, 자신의 사업을 시작하고 당신의 방식으로 그렇게하십시오. 다른 사람들의 길을 시도하는 동안 침착하게 그들에게 열린 마음을 사로 잡으십시오. 이러한 경험이 당신의 견해를 다시 형성한다는 것을 알 수 있습니다.

내부 구현이 변경 될 경우 이론적으로 캡슐화가 유용합니다. 예를 들어, 객체 당 URL이 저장된 값이 아닌 계산 된 결과가되면 geturl () 캡슐화는 계속 작동합니다. 그러나 나는 당신이 이미이 쪽을 들었다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top