5

Tôi hiểu rằng một trong những lợi thế chính của Phương thức nhà máy so với Nhà máy đơn giản là nó không vi phạm Nguyên tắc SOLID mở. Tức là, trước đây không yêu cầu sửa đổi câu lệnh switch khi các kiểu mới được thêm vào.Nhà máy đơn giản so với phương pháp nhà máy: Tuyên bố chuyển đổi trong nhà máy so với khách hàng

Có một phần mà tôi hy vọng được làm rõ. Nếu tôi được sử dụng một nhà máy đơn giản, tôi sẽ có một nhà máy như thế này (giản thể):

public class ObjectFactory { 
    public static IObject CreateObject(ObjectTypeEnum objectType) { 
     switch (objectType) { 
      case TypeA: 
       return ObjectA; 
       break; 
      case TypeB: 
       return ObjectB; 
       break; 
      case TypeC: 
       return ObjectC; 
       break; 
     } 
    } 
} 

và khách hàng sẽ gọi nó là như thế này:

IObject myObject = ObjectFactory.CreateObject(objectType); 

Những bất lợi trong các tài liệu là CreateObject sẽ cần phải được sửa đổi khi các kiểu đối tượng mới được thêm vào.

Nhưng với phương pháp Factory, sẽ không chúng ta chỉ được di chuyển thay đổi này từ nhà máy cho khách hàng, như thế này (mã khách hàng):

IObject myObject; 
switch (objectType) { 
      case TypeA: 
       myObject = ObjectAFactory.CreateObject(); 
       break; 
      case TypeB: 
       myObject = ObjectBFactory.CreateObject(); 
       break; 
      case TypeC: 
       myObject = ObjectCFactory.CreateObject(); 
       break; 
} 

Trong trường hợp này khách hàng sẽ cần phải được sửa đổi mỗi khi một loại mới được thêm vào, so với trường hợp trước, nhà máy sẽ cần được sửa đổi. Vậy lợi thế của cái này qua cái kia là gì? Xin vui lòng không đánh dấu điều này là trùng lặp, tôi đã xem xét nhiều bài viết SO về các nhà máy và không có địa chỉ phân biệt cụ thể này.

Có giải pháp nào tốt hơn không vi phạm Nguyên tắc Mở/Đóng ở phía khách hàng hoặc nhà máy không?

Trả lời

1

Mẫu thiết kế chuẩn Abstract Factory không có tác dụng?
đang Giản Java:

public interface IFactory { 
    IObject createObject(); 
} 

public class FactoryA implements IFactory { 
    public IObject createObject() { 
     return new ObjectA(); 
    } 
} 

public class FactoryB implements IFactory { 
    public IObject createObject() { 
     return new ObjectB(); 
    } 
} 

Client is configured (injected) with the needed Factory at run-time 
    IFactory myFactory = ... // new FactoryA(); 
... 
IObject myObject = myFactory.createObject(); 
... 

Xem thêm các mẫu GOF Thiết kế Memory/Abstract Factory tại http://w3sdesign.com.

VARIANT 2
Thay vì sử dụng loại đối tượng enum, hãy xác định loại đối tượng của bạn với đa hình (để tránh báo cáo chuyển đổi). đang Giản Java:

public interface IObjectType { 
    int getObjectType(); 
    IObject createObject(); 
} 

public class ObjectTypeA implements IObjectType { 
    ... 
    public IObject createObject() { 
     return new ObjectA(); 
    } 
} 

public class ObjectTypeB implements IObjectType { 
    ... 
    public IObject createObject() { 
     return new ObjectB(); 
    } 
} 

Client determines object type 
IObjectType myObjectType = ... // new ObjectTypeA(); 
... 
IObject myObject = myObjectType.createObject(); 
... 

Kết luận của tôi:
Tôi nghĩ rằng, một giải pháp tốt hơn sẽ được thiết kế kiểu của bạn với đa hình thay vì sử dụng CONSTANS enum. Điều này sẽ tránh được các câu lệnh chuyển đổi và sẽ không vi phạm Nguyên tắc Mở/Đóng ở phía khách hàng hoặc phía nhà máy.

+0

Đây thực chất là biến thể của tùy chọn thứ hai ở trên. Lý do điều này không hiệu quả với tôi là trong trường hợp của tôi, "client" của nhà máy thực sự là một API Web. Ứng dụng khách Web API ("client của khách hàng") sẽ là yếu tố quyết định cho kiểu đối tượng là gì, vì vậy tôi không thấy cách tiêm nó mà không thực hiện chuyển đổi kiểu đối tượng, cho dù đó là api tạo ra IFactory hoặc trong chính nhà máy. – mayabelle

+0

Làm cách nào để khách hàng xác định loại đối tượng? – GFranke

+0

Khách hàng chuyển lên loại đối tượng mà họ muốn api. Kiểu đối tượng là một giá trị enum. – mayabelle

Các vấn đề liên quan