2012-05-09 10 views
40
  1. Ví dụ điển hình cho mẫu nhà máy Tóm tắt trong C#?
  2. Ưu điểm của mẫu nhà máy Tóm tắt trong C# là gì?
  3. Làm thế nào để sử dụng C# generics với mô hình nhà máy Abstract?
  4. Làm cách nào để thử nghiệm đơn vị với mẫu Nhà máy trừu tượng?
+1

http://www.dofactory.com/Patterns/PatternAbstract.aspx – Habib

+2

Câu hỏi phải cụ thể hơn. Có vẻ như, bạn không muốn tìm thông tin về chủ đề của mình và chỉ muốn ai đó giải thích cho bạn chủ đề. –

+0

Ngoài ra, bạn có thể điều tra các mẫu khác trái ngược với Mẫu Nhà máy Trừu tượng. http://www.dofactory.com/Patterns/Patterns.aspx –

Trả lời

123

Trước hết, tôi khuyên bạn nên đọc về mẫu Nhà máy Tóm tắt, ví dụ: here. Bây giờ tôi sẽ cố gắng giải thích lý do tại sao bạn sẽ sử dụng mẫu này.

Thông thường, nếu bạn sử dụng mẫu Nhà máy, bạn sẽ tạo đối tượng trong một Nhà máy. Vấn đề phát sinh khi bạn có nhiều triển khai thực hiện của một lớp (hoặc các lớp) đã cho. Bây giờ, nhiều triển khai được nhóm lại. Bạn sẽ sử dụng Abstract Factory pattern khi bạn có một nhà máy, nhưng bạn muốn nhóm việc tạo các đối tượng cho mỗi nhóm.

Được rồi, giải thích ở trên có thể không hoàn toàn rõ ràng, vì vậy tôi sẽ cung cấp cho bạn một ví dụ.

Giả sử bạn có thư viện lớp với các tác nhân dữ liệu. Các đại lý dữ liệu cung cấp cho bạn các phương thức để truy cập và lưu trữ dữ liệu khác nhau. Tất nhiên, có nhiều cách để lưu trữ dữ liệu của bạn. Ví dụ: trong một cơ sở dữ liệu, trong tệp XML, trên một dịch vụ,. Đối với mỗi cách có thể, bạn muốn có các tác nhân dữ liệu. Bây giờ vấn đề là, bạn không muốn ai đó sử dụng DataAgentA cho các tệp XML cùng với DataAgentB cho cơ sở dữ liệu (giả sử rằng chúng ta có các thực thể A và B). Người dùng chỉ nên sử dụng một công cụ lưu trữ.

Hãy để tôi giới thiệu cho bạn mẫu Abstract Factory.

Bạn sẽ đảm bảo rằng người dùng không thể trực tiếp khởi tạo Đại lý dữ liệu của bạn, nhưng họ sẽ phải lấy các đại lý dữ liệu này ra khỏi nhà máy. (Một lợi thế nữa là, khi bạn sử dụng ví dụ một cơ sở dữ liệu (EF), bạn có thể thực hiện kết nối nội bộ để đảm bảo các Đại lý Dữ liệu của bạn sử dụng cùng một ngữ cảnh, v.v.) Làm cách nào để thực hiện điều này? Chúng tôi thiết lập các nhà xây dựng của các đại lý dữ liệu của chúng tôi để ´internal '. Ngoài ra, chúng tôi tạo ra các nhà máy khác nhau cho mỗi công cụ lưu trữ. Bây giờ, vì tất cả các nhà máy đều làm như vậy, chúng tôi cũng có những giao tiếp này (giống như các đại lý dữ liệu của chúng tôi, vì tất cả chúng đều phải làm như vậy, đúng không !?).

Dưới đây chúng tôi có giao diện của chúng tôi. Về cơ bản đây là mẫu nhà máy, nhưng chỉ bây giờ thay vì khoảng lớp học, chúng tôi đang nói về các giao diện .

public interface IAgentA 
{ 
    // Add some methods here! 
} 

public interface IAgentB 
{ 
    // Add some methods here! 
} 

public interface IAgentFactory 
{ 
    IAgentA CreateAgentA(); 
    IAgentB CreateAgentB(); 
} 

Bây giờ cho hai tác nhân, chúng tôi có hai triển khai có thể, một cho XML và một cho lưu trữ cơ sở dữ liệu (một ví dụ, bạn có thể có nhiều loại triển khai như bạn muốn). Những triển khai đó sẽ trông như thế này (xem bên dưới). Xin lưu ý rằng tôi đã tạo phương thức khởi tạo internal! Điều này là cần thiết cho phần đi kèm sau khối mã này.

public class AgentA_Xml : IAgentA 
{ 
    internal AgentA_Xml() 
    { /* Construction here */} 

    // IAgentA method implementations 
} 

public class AgentB_Xml : IAgentB 
{ 
    internal AgentB_Xml() 
    { /* Construction here */} 

    // IAgentB method implementations 
} 


public class AgentA_Database : IAgentA 
{ 
    internal AgentA_Database() 
    { /* Construction here */} 

    // IAgentA method implementations 
} 

public class AgentB_Database : IAgentB 
{ 
    internal AgentB_Database() 
    { /* Construction here */} 

    // IAgentB method implementations 
} 

Bây giờ với tư cách là người xây dựng nội bộ. Điều này khiến bạn không thể khởi tạo các lớp bên ngoài assembly, thường là những gì bạn làm với các loại trường hợp này. Bây giờ chúng ta phải tạo ra các nhà máy của chúng tôi.

public class XMLAgentFactory : IAgentFactory 
{ 
    public IAgentA CreateAgentA() 
    { 
     return new AgentA_Xml(); 
    } 

    public IAgentB CreateAgentB() 
    { 
     return new AgentB_Xml(); 
    } 
} 


public class DatabaseAgentFactory : IAgentFactory 
{ 
    public IAgentA CreateAgentA() 
    { 
     return new AgentA_Database(); 
    } 

    public IAgentB CreateAgentB() 
    { 
     return new AgentB_Database(); 
    } 
} 

Kể từ khi cả hai nhà máy thực hiện các giao diện IAgentFactory, người dùng có thể dễ dàng thay đổi của AgentFactory thực hiện (nếu ông, trong trường hợp này, muốn sử dụng một công cụ lưu trữ khác nhau) mà không cần phải thay đổi bất kỳ mã khác ông viết (chống các đại lý), miễn là anh ta lập trình chống lại các giao diện (rõ ràng).

Giải thích trên đây hy vọng sẽ trả lời các câu hỏi của bạn (1) và (2).

  1. Ví dụ về mẫu nhà máy trừu tượng trong C#?
  2. và lợi thế của mẫu nhà máy Tóm tắt trong C# là gì?

Trả lời câu hỏi của bạn (3).

  1. Cách sử dụng C# generics with Abstract factory pattern?

Bạn vẫn có thể sử dụng Generics, điều này không thay đổi bất kỳ chút khi bạn sử dụng một mô hình Abstract Factory. Tất nhiên, bạn sẽ phải tạo các phương thức nhà máy chung (các phương thức tạo), nhưng điều đó không có vấn đề gì.

Trả lời câu hỏi của bạn (4).

  1. Thử nghiệm đơn vị với mẫu nhà máy trừu tượng như thế nào?

Cũng giống như bạn kiểm tra đơn vị bất kỳ lớp nào khác. Chỉ có một điều sẽ khác.

Vì bạn có thể muốn thử nghiệm hàm tạo của các lớp của bạn (và có thể là các phương thức bên trong khác), bạn cần làm cho các hàm tạo (phương thức) nội bộ hiển thị cho dự án thử nghiệm đơn vị của bạn (và bạn không muốn thay đổi internal đến public). Đây có thể dễ dàng thực hiện bằng cách thêm dòng sau vào tập tin của bạn AssemblyInfo.cs của dự án của bạn (dự án mà nhà máy và các lớp học của bạn là in):

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("My.UnitTest.Namespace")] 

Bạn có thể tìm thêm thông tin (và nhận xét) về thuộc tính InternalsVisibleTo trên MSDN .

Tôi hy vọng loại câu trả lời này là câu hỏi của bạn.

+1

Câu trả lời này là một trong những viên đá quý ẩn mà mọi người nói về một số lần. Rất độc đáo giải thích. Cảm ơn bạn. – ppumkin