객체 지향 코드를 작성할 때 항상 디자인 패턴을 따라야합니까?


37

객체 지향 프로그램에 대해 생각할 수있는 디자인 패턴이 있습니까? 최근에으로 Door클래스 의 구현을 보았 기 때문에 이것을 묻습니다 Lock. 테스트의 일부였으며 코드가 Null Object 패턴을 따른다고 답했습니다.

class Lock
{
public:
    virtual void close() = 0;
    virtual void open() = 0;
    virtual bool is_open() const = 0;
    virtual ~Lock() { }
};

class DummyLock
    : public Lock
{
private:
    DummyLock();
    DummyLock(const DummyLock&) = delete;
    DummyLock& operator=(const DummyLock&) = delete;

private:
    void close() { }
    void open() { }
    bool is_open() const { return true; }

public:
    static DummyLock m_instance;
};

class Door
{
public:
    Door() : m_lock(DummyLock::m_instance) { }
    Door(Lock &lock) : m_lock(lock) { }

public:
    Lock& get_lock() const { return m_lock; }

private:
    Lock &m_lock;
};

이것은 내가 생각하게 만들었습니다 : 설명이 너무 간단 하더라도이 코드는 좋은 디자인 패턴을 따릅니다 (이 클래스는 잠금 장치가있는 도어 클래스를 설계하고 있습니다).보다 복잡한 코드를 작성하는 경우 항상 디자인 패턴이 있어야합니다 팔로 잉?



51
당신은 전적으로 관용구로 말할 수 있다고 생각합니까? 아니? 그런 다음 디자인 패턴을 결합하여 프로그램을 구성해서는 안됩니다.
Kilian Foth

4
귀하의 예에서 Null 객체 패턴은 학업 목적으로 만 추가되며이 코드에 "좋은 디자인"을 도입하지는 않습니다.
Doc Brown

4
@djechlin : 즉, "두 단어"디자인 패턴 : 사용
마이클 쇼

11
문제는 너무 많은 사람들이 디자인 패턴이 사고를 대신 할 수 있고 경험을 대신 할 수 있다고 믿는다는 것입니다 (일정한 시행 착오를 의미 함). 디자인 패턴으로 가득 찬 책을 가져와 Tinker Toys와 같이 모아서 크기가 작고 복잡하고 품질이 좋은 응용 프로그램을 만들 수는 없습니다. 숙련 된 프로그래머조차도 2 개 또는 3 개의 디자인을 시도하여 작동하는 것을 찾아야합니다.
Daniel R은

답변:


143

내가 따르는 디자인 패턴이 항상 있어야합니까?

신 이시여!

내 말은, 임의의 코드가 임의의 XYZ 패턴을 따르고 있다고 말할 있지만, 내 컴퓨터 의자의 왕이라고 주장하는 것보다 더 유용하지 않습니다. 그 의미 가 무엇인지, 그리고 내 주장을 정확하게 존중하지 않는 사람들도 실제로 아는 사람 은 없습니다.

디자인 패턴은 의사 ​​소통 도구이므로 프로그래머는 다른 프로그래머에게 반복적으로 많은 시간을 소비하지 않고 수행 된 작업 또는 수행해야 할 작업을 알릴 수 있습니다. 그리고 그것들은 여러 번 나오는 것들이기 때문에, 프로그래머들이 "이봐, XYZ가 좋은 / 유용하기 때문에 항상 등장하는 것"을 배우는 데 유용한 개념이다.

그것들 당신이 스스로 생각하고, 당신 앞에있는 독특한 문제에 대한 패턴을 맞추거나, 멋진 양동이에 맞지 않는 모든 피할 수없는 것들을 다룰 필요를 대체하지 않습니다.


5
첫 번째 단락은 내가 이것에 어떻게 대답 할 것인가의 일부입니다. 반복되면 무언가가 패턴이 됩니다. 통신이 필요할 정도로 반복되는 경우 패턴 이며 이름의 이점이 있습니다. 심지어 일부 추상화가 누락되어 패턴이 개발된다는 주장도 있습니다. 패턴을 추구 하는 것은 잘 알려진 카고 컬트의 일원으로서 불명예스러운 길입니다.
Magus

11
@Cerad : 물론 신 수업도 쓰지 않겠다고 약속하는 한!
yatima2975

9
John Doe-기술 엔지니어, 일반 코드 원숭이 및 컴퓨터 의자의 왕
hjk

1
논쟁의 여지가 있지만, 디자인은 적절한 곳에 패턴을 사용해야하고 클래스의 이름을 지정해야합니다. 그들은 중요한 도구입니다. the_cult(tm)을 두려워하는 것은 위험합니다.
Gusdor

25
좋은 답변입니다! 내 비판은 "하나님 아냐!" 충분히 크지 않습니다.
tobyink

37

아니.

이것은 Gang of Four (원래 디자인 패턴을 대중화 한)가 그들의 책 에서 그것에 대해 말한 것입니다 .

"디자인 패턴 을 사용 하지 않는 방법에 대한 몇 마디없이 디자인 패턴을 사용하는 방법에 대한 논의는 완료 되지 않을 것입니다. 디자인 패턴은 무차별 적으로 적용되어서는 안됩니다. 종종 추가적인 수준의 간접적 인 도입을 통해 유연성과 가변성을 달성하므로 디자인이 복잡해질 수 있습니다. 디자인 패턴은 유연성이 실제로 필요한 경우에만 적용해야합니다. "

당신이 보여주는 예제는 실제로 많은 것을하지 않습니다 (나는 그것이 의도 된 것이라고 생각하지 않습니다, 나는 단지 예제라고 생각합니다). 그 자체로는 null 객체 패턴이 필요하지 않습니다. 더 큰 프로그램의 맥락에서 볼 수 있습니다.

잘못된 접근 방식은 "디자인 패턴"이라는 레이블이 붙어 있기 때문에 좋은 패턴이어야하고 더 많은 패턴을 넣을 수있는 더 많은 장소를 찾는다고 가정합니다. 프로그램에 적합하고 실제로 문제를 해결할 때 사용하십시오.


7
이 책은 Erich Gamma, Richard Helm, Ralph Johnson 및 John Vlissides의 Design Patterns : Reusable Object-Oriented Software의 요소입니다 .
developerwjk

4
+1 실제로 디자인 패턴의 소스를 인용합니다.
Pharap

29

더 복잡한 코드를 작성하는 경우 항상 따르는 디자인 패턴이 있어야합니까?

디자인 패턴은 점이다 : 패턴 객체 사이의 관계이다. 다시 말해서, 자주 사용되고 재사용되는 관계는 누군가가 "이봐, 우리는이 일을 많이하고있는 것 같습니다. 디자인 패턴 목록은 OOP 시작시 한 번에 결정되지 않았 으며 GOF ! 그것들은 발견되어 결국 문서화되었으며, 그 책에 의해 대중화되었습니다.

즉, 디자인 패턴의 이점 중 큰 부분은 소프트웨어 디자인에 대해 더 높은 수준에서 더 쉽게 생각할 수 있다는 것입니다. 구현 세부 사항에 대한 걱정을 피하고 큰 그림에 대해 더 많이 생각할 수 있습니다. 그런 의미에서 그들은 당신을 사소한 것으로부터 자유롭게 해주지 만, 당신이 알고있는 단어로 자신을 표현하는 방식이 제한 될 수있는 것과 같은 방식으로 당신을 제한 할 수도 있습니다. 이 때, 시간이 올 수 있습니다 당신은 당신이 알고있는 패턴은 당신이 생각하는 조건이 간단하기 때문에하는 일의 대부분을위한 디자인 패턴. 패턴을 남용 할 수있는 경우와 더 나은 방법에 대해 더 깊이 생각해야하는 경우에주의하십시오.

또한 실제로 는 객체 프레임 워크와 같은 기존 코드의 패턴을 인식 할 정도로 주어진 디자인 패턴을 구현 하지 않는 경우가 많습니다 . 일반적인 디자인 패턴을 알고 있으면 이미 이해 한 용어로 클래스 간의 관계를 볼 수 있으므로 프레임 워크 사용 방법을 훨씬 쉽게 배울 수 있습니다.


10

디자인 패턴에는 두 가지 장점이 있습니다

  1. 사람들은 일반적으로 패턴이 무엇인지에 동의하기 때문에 다른 개발자에게 설명하기 쉽습니다.
  2. 그들은 우리의 전임자들에 의해 꽤 신중하게 구타당한 경향이 있으므로 그들의 강점과 약점을 잘 이해합니다.

모든 프로그램의 목표는

  1. 효과가있다. 최종 목표가 무엇이든 상관없이 사용하거나 얼마나 많은 디자인 패턴을 사용하는지는 중요하지 않습니다. OO 디자인 패턴을 사용하면 문제를 이해하기 쉬운 비트로 쉽게 파악할 수 있으므로 작동 여부를 쉽게 입증 할 수 있습니다.
  2. 읽기 쉽다. 디자인 패턴이 좋은 곳입니다. 그들이 해결하는 OO 문제는 복잡하다. "표준"방식으로 해결하면 다음 개발자가 더 쉬워집니다.
  3. 성장하기 쉽습니다. 모두가 계획 한 곳에서 거의 0 개의 현대 프로그램이 끝납니다. 모든 프로그램은 최초 릴리스 이후에 커집니다. OO 패턴은 성장에 호기심이 좋은 것으로 알려져 있습니다.

OO 디자인 패턴에 대한 모든 언급은 "그들이 잘하고있다"는 점에 유의하십시오. 그들은 완벽하지는 않지만 틈새 시장을 매우 효과적으로 채 웁니다. 그들이 일할 때 사용하고, 그렇지 않을 때는 피하십시오.

예를 들어 질문에 언급 한 "복잡한 코드"의 예는 내가 작성한 스크립팅 언어를 사용하십시오. 그것의 대부분은 어디서나 디자인 패턴을 가진 OO입니다. 그러나 가비지 수집기를 작성하는 데 실수로 모든 OO의 범위를 떨어 뜨 렸습니다. 왜냐하면 내가해야 할 특정 작업은 좋은 방식의 비트 비트 싱으로 더 잘 모델링 되었기 때문입니다. 최종자를 작성하기 전까지는 OO 패턴이 없습니다. 다시 한 번 OO가 유용한 모델이되기 시작했습니다. 화려 함이나 환경이 없다면 코드는 갑자기 OO 기술을 다시 사용하게되었습니다.

제품을 개선 할 때마다 디자인 패턴을 사용하십시오. 그들이 당신의 제품을 악화시킬 때 피하십시오.


2
마지막 문장은 굵게 또는 요약으로 맨 위에 있어야한다고 생각합니다.
Pharap

5

답변이 다른 답변에서 허용하는 것보다 더 미묘하기 때문에 트렌드를 조금 강화할 것입니다. 여러분이 작성하는 모든 수업은 디자인 패턴을 채택해서는 안되지만, 작성하는 대부분의 사소한 프로그램 은 가능해야합니다.

디자인 패턴이없는 사소한 프로그램은 다음을 나타냅니다.

  • 귀하의 프로그램은 매우 독창적이기 때문에 프로그래머가 전에 겪었던 일반적인 문제와 비슷한 부분이 없습니다. 또는
  • 귀하의 프로그램에는 이러한 일반적인 문제가 포함되어 있지만 이전에는 아무도 생각하지 못한 더 나은 방식으로 문제를 해결했습니다.

두 시나리오 모두 공격 가능성이 거의 없습니다.

그렇다고해서 디자인 패턴이 디자인을 주도해야하거나 그렇지 않은 경우 디자인이 나쁘다고 생각하기 때문에 디자인을 무차별 적으로 삽입해야한다는 의미는 아닙니다. 잘못된 디자인 패턴이없는 것보다 나쁩니다.

이것이 의미하는 바는 전체 프로그램에서 디자인 패턴이 부족하다는 것을 코드 냄새로 봐야한다는 것입니다. 디자인을 정리할 수없는 경우 다시 한 번 검토하고 재평가 할 수있는 것. 이 시점에서 디자인 패턴을 프로그램에서 제외하기로 결정한 경우 이는 의도적이지 않고 신중한 결정이되어야합니다.

예를 들어 "문과 자물쇠를 모델링해야하는데 어떤 디자인 패턴을 사용해야합니까?"라고 말하지 않습니다. 그러나 디자인 패턴을 사용하지 않고 처음으로 디자인했다면 나중에 "이 코드에 널 검사가 너무 많아서이를 관리하는 데 도움이되는 디자인 패턴이 있는지 궁금합니다."

차이점을 보시겠습니까? 미묘하지만 중요한 차이점입니다.


5
디자인 패턴보다 더 많은 일반적인 문제 (및 일반적인 솔루션)가 있습니다. 디자인 패턴은 모든 공통 솔루션 세트가 아니라 공통 OO 솔루션의 카탈로그 된 하위 세트입니다.
Michael Shaw

1
'사소하지 않은'이라는 의미를 정의 할 수 있습니까? '사소하지 않은'이라는 용어가 주관적이라는 인상을 받았습니다.
Pharap

1
주관적입니다. 나는 당신이 직장에서 팀에 쓸 종류의 프로그램을 의미하며, 지속적으로 여러 관리자가 필요합니다.
Karl Bielefeldt

운이 좋으면 나중에 문제 를 수 있습니다. 널 확인합니다. 보안 취약점? 유지 관리에서 프로그램이 중단되는 다른 교활한 방법? 다음 엔지니어 만이 발견 할 수있는 문제는 무엇입니까? 훨씬 더 Yucky.
djechlin

"문과 잠금을 모델링해야합니다. 인터페이스는 무엇입니까? 성능은 계약의 일부입니까? 서비스 나 라이브러리를 사용해야합니까? 리소스는 어떻게 전달됩니까?" 모두 요청해야하며 기본적으로 디자인 패턴으로 간주되는 답변이 있어야합니다.
djechlin

4

깨진 질문입니다. GoF에서 제공하는 많은 손상을 취소 할 수있는 디자인 패턴에 대한 새로운 정의를 드리겠습니다. 디자인 패턴은 좋은 코딩 방식 입니다. 그게 다야.

합리적으로 복잡한 모듈에는 여러 가지 디자인 패턴이 있습니다. 캐시 할 때마다 플라이급 패턴 일 것입니다.하지만 그것을 부르지 않으면 프로그래밍 학위를 취소하지 않을 것입니다. 콜백이있을 때마다 일종의 이벤트 / 화재 / 콜백 패턴에 있습니다. "정적"이라는 단어가 있다면 싱글 톤입니다. 정적 생성자가 있으면 팩토리 패턴이 있습니다. 리소스가 모듈로 전달되면 종속성 주입을 사용하는 것입니다.

"디자인 패턴"은 GoF에 의해 인기가없는 용어로, 모든 패턴이 같은 레벨에있는 것처럼 들리거나 수업 당 3 ~ 5 명의 의사가 권장해야합니다. 다른 사람이 옳은 일을 할 때마다 디자인 패턴 입니다. 예를 들어 A for(;;)는 무한 루프를 나타내는 데 사용되는 일반적인 패턴입니다.

많은 디자인 패턴을 배우려고 시도해서는 안됩니다. 프로그래밍 지식은 디자인 패턴으로 색인되지 않습니다! 오히려 당신은 책, 블로그를 읽고 당신의 분야에서 회의에 참석하여 좋은 코드를 작성하는 방법을 배워야합니다 . 예를 들어, 이미 의존성 주입을 사용하고 있지만 레이블을 지정하지 않은 경우 항상 DI를 사용하거나 IoC 프레임 워크를 사용하는 것이 좋습니다. 또는 이벤트와 콜백에서 바로 코드를 작성하는 데 어려움을 겪고 있다면 Haskell을 배우면 기능적인 디자인 패턴에 익숙해지기 쉬워집니다.

그리고 전체 학급이 다른 사람이 옳은 일을 한 가지 큰 것으로 읽은 경우 왜 바퀴를 재발 명합니까? 그냥 물건을 사용하십시오.


2
for(;;)관용구 는 어떤 언어로되어 있습니까? 아마도 누군가가 "올바른"일을하는 가장 좋은 예는 아닐 것입니다.
Telastyn

1
@Telastyn C, C ++, Java, Javascript, C #.
djechlin

2
나는 본 적이 누구든지 그 이상 선호 while(true)(또는 while(1)프로그램의 나의 20 년에서 C, C ++, Java 또는 C #에서 참조).
Telastyn

1
@Telastyn stackoverflow.com/a/2611744/1339987 fwiw 더 읽기 쉬운 동안 while (true) 선호하기 시작했습니다.
djechlin

1
나는 항상 (;;)에 사용합니다. 특별한 이유는 없지만 아마 어딘가에 읽었습니다. 변수 나 상수가 없다는 사실이 마음에 듭니다. 어쨌든 @Telastyn은 이제 누군가를 만났습니다 .
앤트

0

OO 설계 원칙 (예 : 모듈성, 정보 숨기기, 높은 응집력 등)을 항상 준수해야합니다 . 특히 KISS 원칙 을 고려할 경우 설계 패턴은 OO 설계 원칙의 비교적 세련된 틈새입니다 .

패턴은 일반적인 디자인 문제에 대한 솔루션입니다. 이러한 문제는 문제 공간 (예 : 회사에서 인사 관리를위한 소프트웨어)과 솔루션 공간 중 하나에서 발생 합니다. OO 프로그램은 솔루션 영역 내의 인스턴스입니다 (예 : HR 관리를 용이하게하기 위해 OO 프로그램을 설계 할 수있는 여러 방법 중 하나).

패턴을 언제 사용해야하는지 쉽게 알 수 없습니다. 일부 패턴은 저수준이며 코딩 및 솔루션 공간에 더 가깝습니다 (예 : Singleton, Null 개체, 반복자). 다른 것들은 문제 공간의 요구 사항에 의해 동기가 부여됩니다 (예 : 실행 취소 / 다시 실행을 지원하기위한 명령 패턴, 다중 입력 / 출력 파일 유형을 지원하기위한 전략).

미래에는 다양한 소프트웨어를 지원해야 할 필요가 있습니다. 이러한 변형을 할 필요가 없으면 패턴이 과도하게 설계되었을 수 있습니다. 기존 외부 HR 데이터베이스 작업에 어댑터 패턴을 사용하는 것이 그 예입니다. 현재 데이터베이스가 Oracle과 작동하고 향후 NoSQL을 지원할 수 있기 때문에 Adapter를 적용하기로 결정했습니다. NoSQL이 조직에 오지 않으면 해당 어댑터 코드는 쓸모가 없을 수 있습니다. YAGNI를 참조하십시오 . 오지 않는 변형에 대한 지원은 디자인 패턴을 잘못 사용하는 것입니다.


0

패턴은 일반적인 문제에 대한 일반적인 솔루션입니다. 우리는 항상 몇 가지 패턴을 따르고 있습니다. GoF의 패턴은 가장 반복되는 패턴을 해결합니다. 즉, 소프트웨어 엔지니어에게 알려진 이해와 공유 접근 방식이 있습니다.

내 대답은 '아니오'입니다.하지만 네 자신은 항상 어떤 패턴을 따르고 있습니다. GoF가 올바르게 말했듯이

한 사람의 패턴은 다른 사람의 기본 구성 요소입니다.

좋은 인용문.


이것은 이전의 7 가지 답변에서 제시되고 설명 된 포인트를 넘어서는 실질적인 것을 제공하지 않는 것 같습니다
gnat

좋아. 참고로, 나는 이론적 논의로서 디자인 패턴에 적용 할 수 있다는 것을 지적했다.
Syed Priom

"이 사이트는 답변을 얻는 것에 관한 입니다. 토론 포럼이 아닙니다 ..."( tour )
gnat

나는 그 질문에 대답했다. 감사합니다. 이 대화는 여기서 끝납니다.
Syed Priom 2011

@gnat 그것은 훨씬 더 간결합니다.
djechlin

0

코드를 작성할 때 가능한 한 많은 디자인 패턴을 의도적으로 사용하지는 않습니다. 그러나 무의식적으로 코딩 문제가 발생하면 디자인 패턴 중 하나가 맞는 것처럼 보이며 그냥 사용합니다. 때로는 아무것도 맞지 않습니다. 나에게 더 중요한 것은 작업을 수행하고 유지 관리 및 성장이 쉬운 코드를 작성하는 것입니다.

다음은 디자인 패턴을 사용하여 OOD 원칙을 적용 하는 방법에 대한 기사 이며 코드 예제도 있습니다 (C ++). 깨끗한 코드를 작성하기 위해 일부 디자인 패턴을 적용하는 방법과시기를 보여줍니다.


2
그 기사는 어제 쓰여졌습니다. 블로그와 관련이 있습니까? 그렇다면 해당 제휴사를 공개 하십시오 .
Martijn Pieters
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.