GoF 디자인 패턴-실제로 사용하는 패턴은 무엇입니까? [닫은]


16

디자인 패턴 분야에서 동료들을 교육하려고합니다. 원래 Gang of Four 패턴 중 일부는 약간 난해하기 때문에 모든 프로그래머가 알아야 할 "필수"패턴의 하위 그룹이 있는지 궁금합니다. 목록을 살펴보면 아마도 내가 사용한 것 같습니다-

  • 추상 공장
  • 공장 방법
  • 하나씩 일어나는 것
  • 다리
  • 정면
  • 명령

실제로 실제로 어떤 것을 사용합니까?

패턴 목록을 원하는 사람들을위한 링크


7
IMHO, 질문이 너무 모호하여 유용한 토론을하기가 어렵습니다. 패턴 당 하나의 답변 또는 패턴 조합 당 하나의 답변을 원하십니까?
Macke

이러한 패턴을 사용하는 몇 가지 이유가 유용합니다. 그렇지 않으면 개념을 나열하는 것입니다. "어떤 키워드를 사용하십니까?"라는 질문을 상상해보십시오. 그리고 " for, if, while...등"의 목록을 모으는 것 -그것이 얼마나 무의미한지를 측정하는 것은 어렵다.
ocodo

1
Slomojo에 동의하지 않습니다. 일반적으로 사용되는 키워드와 언어에없는 키워드를 아는 것이 매우 편리 할 것입니다. 예를 들어 기본 클래스도 마찬가지입니다.
Craig Schwarze

1
좀 더 공정하게 수정했습니다. 이제 더 나은 토론을 할 수 있기를 바랍니다.
크레이그 슈 워제

1
실제로 어떤 종류의 과일을 먹습니까? 이 질문에서 무엇을 얻고 싶은지 알고 싶습니다. 3 ~ 4 명이 사용했지만 아직 사용하지 않은 패턴이 보이면 사용하도록 하시겠습니까?
Marcie

답변:


4

실제로 사용하거나 본 것들의 목록은 다음과 같습니다.

Singleton-ASP.Net의 응용 프로그램 개체가 대표적인 예입니다.

어댑터-데이터베이스에 연결하는 것은 일반적으로 적어도 내 .Net 영역에서 Adapter 클래스를 포함 할 수 있습니다.

팩토리-객체 생성에 대한 일반 사항하지만 그 당시의 일부 오래된 클래식 ASP에서 더 많이 보았습니다.

전략-각 유형의 장치에 대해이 패턴의 구현을 고려할 클래스와 유사한 구조를 가진 응용 프로그램이 있습니다.

Facade-몇 가지면에서 이것은 일반적으로 몇 개의 시스템을 하나로 묶는 점에서 어댑터 패턴과 유사합니다.


1
모든 유효한 용도. 이 글을 읽는 사람에게는 이러한 패턴이 반드시 이것들에 국한되지 않는다는 것을 명심하십시오.
보리스 얀 코프

5

저자는 실제 응용 프로그램에서 찾은 관찰 된 디자인의 패턴을 편집했습니다. 어느 누구도 그들 모두를 사용하지는 않지만 모두 사용됩니다.


Smithco를 사용한 것은 무엇이며 무엇을위한 것입니까?
크레이그 슈 워제

@CraigS 나는 그들 중 많은 것을 사용했습니다. Design Patterns의 저자는 설명하는 각 패턴과 함께 좋은 예를 가지고 있습니다. 내가 줄 수있는 가장 좋은 제안은 책을 철저히 읽는 데 시간을 보내는 것입니다.
smithco

3

데코레이터 .

편집 : '사소한'단계를 넘어서는 거의 모든 프로젝트에서 IAction 인터페이스로 끝납니다 (세부 사항은 다를 수 있음).

// Programming Language does not matter
interface IAction {
     bool operateOn(Foo* target);
     string getDisplayName(); // useful for debugging and logging
};

다음 시간에 나는 IAction을 구현하는 작고 사소한 많은 클래스를 작성하는 데 소비합니다. 결합하면 매우 강력하고 유연합니다.

예를 들어, LogAction(IAction을 기록하고 수행하기 위해 쓰기), NullAction(아무것도하지 않고 true를 반환), ActionList(IAction 목록을 수행하고 bool의 AND를 반환합니다). 어떤 경우에 AndAction(즉, 두 가지 작업과 - 보내고을 반환 단락 여부 될 수있다) OrAction, NotAction메이크업 감각뿐만 아니라.

위의 예에서 기술적으로 LogAction 만 Decorator (다른 하나는 정확히 1 IAction에서 작동하지 않음)이지만 IActions LogActions의 ActionList를 만들 때 여전히 Decorator 패턴의 일반화로 간주합니다.


무엇을 위해 사용합니까?
크레이그 SCHWARZE

1
요청시 @CraigS 예제가 추가되었습니다.
Sjoerd

실제로 Decorator와 Composite의 혼합과 비슷해 보입니다. 패턴의 어려움은 패턴을 독립적으로 사용하는 것이 아니라 함께 혼합하여 발생한다는 어려움을 완벽하게 보여줍니다. :)
Matthieu M.

예, 이것은 고전입니다. 명령으로 합성 된 복합입니다. 이 패튼의 이름은 실제로 "사양"( en.wikipedia.org/wiki/Specification_pattern )이라고합니다.
Martin Wickman 23.09에

2

나는 당신이 질문을 자신의 코드 / 프로젝트 (클래스 라이브러리 및 타사 프레임 워크 없음)에서의 패턴 사용으로 제한한다고 가정합니다.

다른 사람들과 마찬가지로 팩토리 패턴도 가장 자주 사용했습니다. 그때

  • 싱글 톤 : 요즘은 그리 많지 않지만 때로는 전역 구성 데이터에 필요합니다.
  • 전략템플릿 방법 : 예를 들어 앱에서 다양한 종류의 계산을 나타내는 경우
  • 빌더 : (이 텍스트 구문 분석 및 대형 개체의 계층 구조를 만드는의 큰 거래를 포함하는 경우에) 출력 객체로 메인 프레임 시스템과 거래의 결과의 정렬 화를위한
  • Command : 몇 년 전에 한 번만 구현했지만 요즘 Java 프로젝트에서는 Callables를 사용하고 있습니다. 기본적으로 Commands라고 생각합니다.

2

나는 이미 언급 한 다른 것들 (싱글 톤, 팩토리, 빌더, 명령, 전략 등)을 많이 사용했습니다.

아직 언급하지 않은 것은 Flyweight인데, 많이 사용하는 경향이 있습니다. 아래에 구현 예제를 제공했습니다.

/**
 * Flyweight class representing OCR digits.
 * 
 * @author matt
 *
 */
public class Digit {
    /** Static flyweight map containing Digits which have been encountered. **/
    private static Map digits = new HashMap();

    /** The block of text representing Digit. **/
    private String blockRep = null;

    /** A map representing acceptable blocks of characters and the string representation of their
     * numerical equivalents.
     */
    public static final Map VALID_DIGITS;

    /** Enum of valid digits. **/
    public static enum DigitRep {
        ZERO    (   " _ \n" +
                    "| |\n" +
                    "|_|"       ),

        ONE (       "   \n" +
                    "  |\n" +
                    "  |"       ),

        TWO (       " _ \n" +
                    " _|\n" +
                    "|_ "       ),

        THREE   (   " _ \n" +
                    " _|\n" +
                    " _|"       ),

        FOUR    (   "   \n" +
                    "|_|\n" +
                    "  |"       ),

        FIVE    (   " _ \n" +
                    "|_ \n" +
                    " _|"       ),

        SIX     (   " _ \n" +
                    "|_ \n" +
                    "|_|"       ),

        SEVEN   (   " _ \n" +
                    "  |\n" +
                    "  |"       ),

        EIGHT   (   " _ \n" +
                    "|_|\n" +
                    "|_|"       ),

        NINE    (   " _ \n" +
                    "|_|\n" +
                    " _|"       );

        private String blockRep;

        DigitRep(String blockRep) {
            this.blockRep = blockRep;
        }

        @Override
        public String toString() {
            return blockRep;
        }
    }

    static {
        /* Initialize the map of acceptable character blocks. */
        Map tmpMap = new HashMap();
        tmpMap.put( DigitRep.ZERO.toString(),   "0");
        tmpMap.put( DigitRep.ONE.toString(),    "1");
        tmpMap.put( DigitRep.TWO.toString(),    "2");
        tmpMap.put( DigitRep.THREE.toString(),  "3");
        tmpMap.put( DigitRep.FOUR.toString(),   "4");
        tmpMap.put( DigitRep.FIVE.toString(),   "5");
        tmpMap.put( DigitRep.SIX.toString(),    "6");
        tmpMap.put( DigitRep.SEVEN.toString(),  "7");
        tmpMap.put( DigitRep.EIGHT.toString(),  "8");
        tmpMap.put( DigitRep.NINE.toString(),   "9");       
        VALID_DIGITS = Collections.unmodifiableMap(tmpMap);
    }

    /**
     * Private constructor to enforce flyweight/factory pattern.
     * 
     * @param blockRep
     */
    private Digit(String blockRep) {
        this.blockRep = blockRep;
    }

    /**
     * Flyweight factory method to create a Digit object from the "block"
     * representation of the digit.
     * @param blockRep The "block" representation of a digit.  Should look
     * something like:
     * " _ \n"
     * "|_|\n"
     * "|_|"
     * @return A flyweight Digit object representing the digit.
     */
    public static synchronized Digit getDigit(String blockRep) {
        Digit digit = digits.get(blockRep);
        if(digit == null) {
            digit = new Digit(blockRep);
            digits.put(blockRep, digit);
        }

        return digit;
    }

    /**
     * Determines whether or not the digit is valid.
     * @return true if the digit is valid, else false.
     */
    public boolean isValid() {
        return VALID_DIGITS.containsKey(blockRep);
    }

    /**
     * Accessor method to get the block representation of this digit.
     * 
     * @return
     */
    public String getBlockRep() {
        return blockRep;
    }

    @Override
    public String toString() {
        return VALID_DIGITS.containsKey(blockRep) ? VALID_DIGITS.get(blockRep) : "?";
    }
}

1
덜 알려졌지만 여전히 유용한 패턴 중 하나를 +1합니다.
MattDavey

2

오늘날의 Gang of Four 패턴의 대부분은 오늘날에도 여전히 사용되지만이 책에는없는 다른 인기있는 패턴이 있습니다.

사용하는 언어로 Design Patters에 대한 참조를 찾으십시오. 이들은보다 구체적이고 특정 언어 기능을 사용하여보다 간결하고 우아한 방식으로 패턴을 구현합니다.

디자인 패턴을위한 3 가지 훌륭한 리소스 :

"Head First Design Patterns"책 -선택한 언어는 Java이지만 모든 언어와 관련이 있습니다. Dofactory Design Patterns- 코드가 포함 된 훌륭하고 무료 .net 디자인 패턴 설명. PluralSight-디자인 패턴 라이브러리 -이 라이브러리 는 유료이지만 목록에 포함시키지 않는 것이 좋습니다.


1

ACE와 같은 일반적인 라이브러리를 사용하면 생각보다 많은 것을 사용하게됩니다. 나는 Observer / Observable을 광범위하게 사용합니다 :-)


1

빌더를 한 번 이상 사용했습니다 (동일한 변환기 프로세스로 HTML 또는 Excel 출력을 작성할 수 있음).

나는 종종 JDBC 관련 작업 또는 추상 스윙 컨트롤러를 위해 템플릿 방법을 사용합니다.

일단 양식 기반 응용 프로그램으로 많은 새로운 기능을 개발해야했는데 혼란 스러웠습니다. 기존 항목을 State-pattern 기반 솔루션으로 리팩터링 한 후에 만 ​​진행할 수있었습니다. (글쎄, 대부분).

또한 명령을 자주 사용하고 (스윙 작업) 관찰자도 사용합니다.

일단 스윙 형태의 변화를 감지하기 위해 Mememento와 같은 솔루션을 사용했습니다. 양식은 내가 비교 한 (equals ()) 상태를 이전 상태와 직렬화합니다.


1

나는 내 경력을 통해 그들 대부분을 가지고 있다고 생각합니다. 내가 사용하지 않은 유일한 것은 다중 상속의 큰 팬이 아니기 때문에 책에서 다중 상속으로 구현되는 어댑터 패턴입니다.


1

나는 Decorator를 좋아한다. 내가 언급 한 것에 추가 한 유일한 것은 프록시입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.