Các mẫu thiết kế của GoF - những mẫu nào bạn thực sự sử dụng? [đóng cửa]


16

Tôi đang cố gắng giáo dục các đồng nghiệp của mình trong lĩnh vực thiết kế mẫu. Một số mẫu Gang of Four ban đầu là một chút bí truyền, vì vậy tôi tự hỏi liệu có một nhóm các mẫu "thiết yếu" mà tất cả các lập trình viên nên biết. Khi tôi xem qua danh sách, tôi nghĩ có lẽ tôi đã sử dụng -

  • Nhà máy trừu tượng
  • Phương pháp nhà máy
  • Người độc thân
  • Cầu
  • Mặt tiền
  • Chỉ huy

Những cái nào bạn thực sự sử dụng trong thực tế, và bạn sử dụng chúng để làm gì?

Liên kết cho những người muốn một danh sách các mẫu


7
IMHO, câu hỏi quá mơ hồ để mang lại cuộc thảo luận hữu ích. Bạn có muốn một câu trả lời cho mỗi mẫu hoặc một câu trả lời cho mỗi kết hợp các mẫu không?
Macke

Một số lý do tại sao bạn sử dụng các mẫu này sẽ hữu ích, nếu không, bạn chỉ liệt kê các khái niệm ... Hãy tưởng tượng đặt câu hỏi: "Bạn sử dụng từ khóa nào?" và thu thập các danh sách " for, if, while...vv" - rất khó để đo lường mức độ vô nghĩa của nó.
ocodo

1
Tôi không đồng ý Slomojo - Tôi nghĩ sẽ khá tiện khi biết từ khóa nào được sử dụng phổ biến và không có trong ngôn ngữ. Tương tự như vậy đối với các lớp cơ sở, ví dụ.
Craig Schwarze

1
Sửa đổi nó một chút công bằng hơn - hy vọng điều này sẽ tạo ra một số cuộc thảo luận tốt hơn bây giờ.
Craig Schwarze

1
Những loại trái cây bạn thực sự ăn? Tôi tò mò muốn biết những gì bạn đang hy vọng thoát khỏi câu hỏi này. Nếu bạn thấy một mẫu mà 3 hoặc 4 người đã sử dụng nhưng bạn chưa biết, liệu điều đó có khiến bạn sử dụng nó không?
Marcie

Câu trả lời:


4

Đây là danh sách những cái tôi đã sử dụng hoặc nhìn thấy trong thực tế:

Singleton - Đối tượng ứng dụng trong ASP.Net là một ví dụ điển hình cho việc này.

Bộ điều hợp - Việc kết nối với cơ sở dữ liệu thường có thể liên quan đến một lớp Bộ điều hợp ít nhất là trong khu vực của tôi .Net.

Factory - General để tạo các đối tượng mặc dù tôi đã thấy điều này nhiều hơn trong một số ASP cổ điển cũ hơn trong ngày.

Chiến lược - Tôi đã có một ứng dụng cho từng loại thiết bị tôi có cấu trúc tương tự cho lớp mà tôi sẽ xem xét triển khai mẫu này.

Mặt tiền - Trong một số cách, điều này tương tự như mẫu Adaptor về mặt thường là thứ gì đó liên kết với nhau một vài hệ thống.


1
Tất cả các sử dụng hợp lệ. Đối với bất cứ ai cũng đọc điều này - hãy nhớ rằng những mẫu này chắc chắn không giới hạn ở những mẫu này.
Boris Yankov

5

Các tác giả đã biên soạn các mẫu từ các thiết kế quan sát mà họ tìm thấy trong các ứng dụng thực tế. Không ai có thể sẽ sử dụng tất cả chúng, nhưng tất cả chúng đều được sử dụng.


Bạn đã sử dụng smithco, và để làm gì?
Craig Schwarze

@CraigS Tôi đã sử dụng nhiều trong số họ. Các tác giả của Mẫu thiết kế có một tập hợp các ví dụ tốt với mỗi mẫu mà họ mô tả. Gợi ý tốt nhất tôi có thể đưa ra là dành thời gian để đọc kỹ cuốn sách.
smithco

3

Trang trí .

EDIT : Trong hầu hết mọi dự án vượt ra khỏi giai đoạn 'tầm thường', một dự án kết thúc với giao diện IAction (chi tiết có thể khác nhau):

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

Giờ tiếp theo tôi dành cho việc viết rất nhiều lớp nhỏ, gần như tầm thường thực hiện IAction. Khi kết hợp, chúng rất mạnh mẽ và linh hoạt.

Ví dụ: LogAction(ghi vào nhật ký và thực hiện IAction), NullAction(không làm gì và trả về true), ActionList(thực hiện danh sách IActions và trả về ANDing của các bools). Trong một số trường hợp, một AndAction(trả lại AND của hai hành động, có thể bị ngắn mạch hoặc không) OrAction, cũng NotActioncó ý nghĩa.

Mặc dù về mặt kỹ thuật từ các ví dụ trên chỉ có LogAction là Công cụ trang trí (cái khác không hoạt động trên chính xác 1 IAction), tôi vẫn coi đây là một khái quát của mẫu Trang trí khi tôi tạo một Danh sách hành động của LogActions của IActions.


Bạn sử dụng chúng để làm gì?
Craig Schwarze

1
@CraigS Ví dụ được thêm vào theo yêu cầu.
Sjoerd

Nó trông giống như một sự pha trộn giữa Decorator và Composite, điều này rất tốt, và một minh chứng hoàn hảo rằng sự khó khăn trong các mẫu không đến từ việc sử dụng chúng một cách độc lập, mà là trộn chúng lại với nhau :)
Matthieu M.

Vâng, đây là một cổ điển. Nó là kết hợp với lệnh. Thực sự có một tên cho patten này: nó được gọi là "Đặc điểm kỹ thuật" ( en.wikipedia.org/wiki/Specification_potype ).
Martin Wickman

2

Tôi giả sử bạn có nghĩa là hạn chế câu hỏi trong việc sử dụng các mẫu trong mã / dự án riêng (không có thư viện lớp và khung bên thứ 3).

Cũng như những người khác, tôi cũng đã sử dụng các mẫu Factory thường xuyên nhất. Sau đó

  • Singleton : ngày nay không quá nhiều, nhưng đôi khi vẫn cần thiết, điển hình cho dữ liệu cấu hình toàn cầu
  • Phương pháp chiến lượcmẫu : khá thường xuyên, ví dụ: đại diện cho các loại tính toán khác nhau trong ứng dụng của chúng tôi
  • Trình tạo : để sắp xếp kết quả của các giao dịch với hệ thống máy tính lớn vào các đối tượng đầu ra (trong một số trường hợp, nó bao gồm rất nhiều phân tích văn bản và tạo phân cấp đối tượng lớn)
  • Lệnh : Tôi đã triển khai nó chỉ một lần cách đây nhiều năm, nhưng hiện tại trong dự án Java của chúng tôi, tôi sử dụng Callables mọi lúc, mà tôi tin rằng về cơ bản là các Lệnh

2

Tôi đã sử dụng nhiều thứ khác đã được đề cập (Singleton, Factory, Builder, Command, Strateg, v.v.)

Một cái tôi chưa thấy đề cập đến là Flykg, mà tôi có xu hướng sử dụng rất nhiều. Tôi đã cung cấp một ví dụ thực hiện bên dưới:

/**
 * 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 một trong những mẫu ít được biết đến nhưng vẫn cực kỳ hữu ích.
MattDavey

2

Hầu hết các mẫu Gang of Four ban đầu vẫn được sử dụng cho đến ngày nay, nhưng có những mẫu khác hiện đang phổ biến không có trong sách.

Tìm một tài liệu tham khảo cho Design Patters bằng ngôn ngữ bạn sử dụng. Họ có xu hướng cụ thể hơn và sử dụng các tính năng ngôn ngữ cụ thể để thực hiện các mẫu theo cách ngắn gọn và thanh lịch hơn.

Ba tài nguyên tuyệt vời cho các mẫu thiết kế:

Sách "Các mẫu thiết kế đầu tiên" - ngôn ngữ được lựa chọn là Java, nhưng có liên quan đến tất cả các ngôn ngữ. Các mẫu thiết kế dofactory - giải thích các mẫu thiết kế .net tuyệt vời và miễn phí với mã. PluralSight - Thư viện mẫu thiết kế - cái này được trả tiền, nhưng quá tốt để không đưa nó vào danh sách.


1

Chà, nếu bạn sử dụng các thư viện phổ biến như ACE, cuối cùng bạn sẽ sử dụng nhiều hơn bạn nghĩ. Tôi sử dụng rộng rãi Observer / Observable :-)


1

Tôi đã sử dụng Trình tạo ít nhất một lần (quy trình chuyển đổi tương tự có thể xây dựng đầu ra HTML hoặc Excel).

Tôi thường xuyên sử dụng Phương thức mẫu (cho các tác vụ liên quan đến JDBC hoặc các bộ điều khiển Xoay trừu tượng).

Khi tôi đã phải phát triển nhiều tính năng mới thành một ứng dụng dựa trên hình thức, đó là một mớ hỗn độn. Tôi chỉ có thể tiến bộ sau khi tôi đã tái cấu trúc các công cụ hiện có thành một giải pháp dựa trên mô hình Nhà nước. (Chà, hầu hết là vậy).

Tôi cũng sử dụng Lệnh thường xuyên (Thao tác xoay) và Người quan sát cũng vậy.

Khi tôi đã sử dụng giải pháp tương tự Mememento để phát hiện các thay đổi trong biểu mẫu Xoay. Biểu mẫu sẽ tuần tự hóa trạng thái của nó những gì tôi đã so sánh (bằng ()) với các trạng thái trước đó.


1

Tôi tin rằng tôi có hầu hết họ thông qua sự nghiệp của tôi. điều duy nhất tôi chắc chắn rằng tôi chưa sử dụng là Mô hình bộ điều hợp được triển khai với nhiều kế thừa trên cuốn sách vì tôi không phải là một fan hâm mộ lớn của nhiều kế thừa.


1

Tôi thích trang trí. Người duy nhất tôi đã thêm vào những người được đề cập là Proxy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.