2009-10-13 23 views
15

Tôi đang thực hiện nghiên cứu chuyên sâu về các mẫu thiết kế và tôi đã xem qua nguyên mẫu, mà trước đó tôi chưa từng nghiên cứu. Tôi đã tìm kiếm trên web và một vài cuốn sách, và không có một ví dụ thực sự tốt về nguyên mẫu có thể thấy rằng không chỉ là bản sao. Có phải mẫu thiết kế của nguyên mẫu cơ bản là một tính năng ngôn ngữ của java và C# là bản sao?Mẫu thiết kế nguyên mẫu có thực sự chỉ sao chép không?

+3

Mẫu là trừu tượng độc lập về ngôn ngữ, bản sao là một thành ngữ ngôn ngữ cụ thể. Sẽ đúng khi nói rằng mẫu Prototype là sự khái quát hóa thành ngữ bản sao, hoặc bản sao đó là một thành ngữ cụ thể của ngôn ngữ Prototype nhưng sẽ là một lỗi để buộc nó chặt chẽ thành một ngôn ngữ duy nhất. –

Trả lời

18

Mẫu thử nghiệm nhiều hơn Clone. Ngữ nghĩa ngữ nghĩa rộng hơn, có nghĩa là các trường vô hướng/giá trị của một cá thể đối tượng được sao chép trong một cá thể mới sao cho chúng có trạng thái tương đương nhưng chiếm các vị trí khác nhau trong bộ nhớ. Bản sao có thể được sử dụng để hỗ trợ nhiều nhu cầu khác nhau.

Mẫu thử nghiệm kết hợp Clone cụ thể vào việc giải quyết vấn đề lớn hơn về việc tách đối tượng xây dựng khỏi việc sử dụng đối tượng. Ngữ nghĩa nguyên mẫu nói rằng phương thức duy nhất (hoặc ít nhất là được hỗ trợ/ưa thích) để xây dựng một đối tượng mới của hành vi được yêu cầu là bằng cách sao chép một cá thể cụ thể, được gọi là cá thể mẫu. Những trường hợp nguyên mẫu này có thể sống trong một nhà máy nguyên mẫu, được triển khai để tạo ra các cá thể mới bằng cách gọi Clone trên các cá thể mẫu. Các cá thể mẫu có thể được khởi tạo thông qua việc tiêm phụ thuộc. Mã tiêm là mã duy nhất cần biết cách xây dựng các cá thể mẫu, và điều này có hiệu quả trở thành mã nhà máy thực sự.

Hy vọng rằng lớp ví dụ nhà máy sau làm rõ mấu chốt của mô hình:

public class PrototypeWidgetFactory : IWidgetFactory 
{ 
    public PrototypeWidgetFactory(PrototypeWidget scenarioA, PrototypeWidget scenarioB, PrototypeWidget scenarioC) 
    { 
    _scenarioA = scenarioA; 
    _scenarioB = scenarioB; 
    _scenarioC = scenarioC; 
    } 

    public Widget GetForScenarioA() { return _scenarioA.Clone(); } 
    public Widget GetForScenarioB() { return _scenarioB.Clone(); } 
    public Widget GetForScenarioC() { return _scenarioC.Clone(); } 

    private PrototypeWidgetFactory _scenarioA; 
    private PrototypeWidgetFactory _scenarioB; 
    private PrototypeWidgetFactory _scenarioC; 
} 

Một thể hiện của nhà máy này có thể được thông qua bất cứ nơi nào IWidgetFactory là cần thiết. Ưu điểm là bạn không cần một loạt các lớp nhà máy khác nhau cho mỗi hành vi. Trong thực tế, đối với một số loại hành vi, bạn thậm chí không cần một loạt các lớp khác nhau nếu bạn chỉ cần tiêm các thể hiện cùng loại được khởi tạo khác nhau vào nhà máy mẫu thử nghiệm. Trong trường hợp này, lợi thế thậm chí còn lớn hơn ở chỗ API không sưng lên với một loạt các lớp nhỏ không làm được nhiều.

Hạn chế là mã tiêm cần biết cách xây dựng các nguyên mẫu. Điều này là dễ vỡ nếu có rất nhiều logic phức tạp liên quan đến việc xây dựng các nguyên mẫu.

(Lưu ý: Mẫu thử nghiệm không yêu cầu tất cả các phương thức trên một nhà máy mẫu thử trở lại cùng loại. Tôi vừa làm ví dụ trả về chỉ các Widget vì nó minh họa lợi thế lớn hơn khi sử dụng các nguyên mẫu để xây dựng các đối tượng cho hành vi cụ thể các đối tượng thuộc một loại nhưng được khởi tạo khác nhau.)

public class PrototypeDomainFactory : IDomainFactory 
{ 
    public PrototypeDomainFactory(PrototypePerson personPrototype, PrototypeCompany companyPrototype, PrototypeWidget widgetPrototype) 
    { 
    _personPrototype = personPrototype; 
    _companyPrototype = companyPrototype; 
    _widgetPrototype = widgetPrototype; 
    } 

    public Person GetPerson() { return _personPrototype.Clone(); } 
    public Company GetCompany() { return _companyPrototype.Clone(); } 
    public Widget GetWidget() { return _widgetPrototype.Clone(); } 

    private PrototypePerson _personPrototype; 
    private PrototypeCompany _companyPrototype; 
    private PrototypeWidget _widgetPrototype; 
} 
0

Clone() chắc chắn là một phần của nó. Tôi nghĩ rằng mô hình cũng nói về việc có những cách để thu thập các đối tượng, lặp qua chúng, và tìm ra một cách phù hợp để sao chép. Bạn cũng phải thiết lập các đối tượng để bắt đầu.

4

Sorta. Clone() thực hiện rất nhiều thứ bạn muốn cho mục đích Thử nghiệm, nhưng bạn có thể tiến xa hơn với mẫu nếu bạn cần. Xem Steve Yegge's deep (and lengthy!) explanation hoặc nghiên cứu mô hình đối tượng Javascript.

+1

Đó không phải là nguyên mẫu - (mặc dù nó chắc chắn có liên quan) - anh ấy gọi nó là Mẫu Thuộc tính. Trong JavaScript, từ "nguyên mẫu" được sử dụng để mô tả một phần của điều này, và nhân bản chắc chắn là có liên quan, nhưng tôi vẫn nghĩ về chúng như những thứ khác nhau. Prototype trong GoF không nói về ý tưởng về tính chất động. –

+0

Đó là một điểm công bằng.Tôi đã luôn luôn nghĩ về nguyên mẫu như bao gồm những thứ như tính chất động và khả năng lặp lại, chỉ vì nếu nó không * là * về cơ bản Clone(), và điều đó dường như là lame. –

+0

Ồ, cảm ơn vì đã đăng bài blog đó. Rất tốt đọc. Tôi đã học được rất nhiều từ việc đọc nó. Tôi đồng ý nó không phải là mẫu thử nghiệm được mô tả trong cuốn sách GoF. –