2010-03-04 24 views
7

Có phải Factory Method pattern (không bị nhầm lẫn với mẫu Nhà máy hoặc Nhà máy Tóm tắt) vi phạm Open/Closed principle không?Mẫu Phương thức Nhà máy có vi phạm nguyên tắc Mở/Đóng không?

Cập nhật: Để làm rõ, tôi đang đề cập đến trường hợp trong đó lớp bê tông có phương pháp nhà máy tĩnh trên đó. Ví dụ: (đây là từ trang Wikipedia trên FMP):

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    private Complex(double a, double b) { 
     //... 
    } 
} 

Không phải nhà xây dựng tư nhân ngăn lớp được phân lớp, tức là mở rộng?

Lớp học không phải được sửa đổi để hỗ trợ các phương pháp nhà máy mới không? Ví dụ, nếu lớp ban đầu chỉ có từCartesian và sau đó từPolar là cần thiết, không phải lớp đó phải được sửa đổi để hỗ trợ điều này?

Không phải cả hai phần mở/đóng vi phạm này đều không vi phạm?

+2

Tôi muốn biết bạn nghĩ gì về điều này trước khi tôi trả lời. Câu trả lời của bạn sẽ khiến tôi cảm thấy bạn đang tìm câu trả lời. Nếu không nó giống như bạn đang gia công phần mềm công việc của bạn để SO. –

+0

Rất tiếc, đã lên kế hoạch để thêm nhận xét nhưng bị bỏ qua bởi công việc. :) Tôi nghĩ rằng nó vi phạm nó. Xin vui lòng sửa tôi nếu tôi sai, nhưng FMP ra lệnh cho một nhà xây dựng riêng, và một nhà xây dựng riêng cấm mở rộng. Ngoài ra, sẽ không phải lớp học phải được sửa đổi để hỗ trợ triển khai thay thế? Tôi đang nghĩ về tình huống mà một lớp học có phương pháp nhà máy tĩnh. Có lẽ đây chỉ là một hương vị của FMP? –

+0

Nếu nó là một lớp con, bạn có thể sử dụng phương thức này hoặc sử dụng super() (giả sử Java). Tốt hơn là bạn không nên có các phương thức tĩnh và có một phương thức duy nhất lấy các tham số để chọn một tham số bằng cách sử dụng một câu lệnh switch hoặc bằng cách đọc trong một tệp cấu hình được cung cấp. –

Trả lời

3

Không, nó không vi phạm nguyên tắc Mở/Đóng.

Mở/đóng có nghĩa là bạn có thể sửa đổi cách hệ thống hoạt động mà không sửa đổi mã đã tồn tại. Bạn có thể mở rộng mã và sử dụng nó theo nhiều cách khác nhau, nhưng mã cũ vẫn còn nguyên vẹn và không cần phải kiểm tra lại.

Mẫu Phương thức nhà máy sẽ tạo một loại đối tượng khác dựa trên các thông số được chỉ định. Phương thức Factory thực sự hoạt động tốt với nguyên tắc Open/Closed nếu được thực hiện đúng. Tuy nhiên, nếu bạn tạo một lớp mới và sau đó muốn phương thức Factory để tạo một đối tượng mới của kiểu đó, bạn sẽ phải thay đổi phương thức Factory.

Mặc dù, nếu bạn có một số loại tệp cấu hình hoặc thứ gì đó được đọc theo Phương pháp nhà máy thì bạn sẽ không phải thay đổi Phương thức nhà máy ... chỉ cần tệp cấu hình sau đó ra lệnh đối tượng nào sẽ được tạo bởi Phương thức Nhà máy.

2

Không. Từ liên kết của bạn Wikipedia:

phần mềm tổ chức (các lớp học, mô-đun, chức năng, vv) nên được mở cho phần mở rộng, nhưng đóng cửa để sửa đổi

Trọng phương pháp nhà máy là phần mở rộng. Bạn đang tạo một lớp học mới. Bạn không thay đổi lớp hiện tại. Bạn phải thay thế (thông qua cấu hình của container IoC của bạn hy vọng) các lớp con cho bản gốc.

5

Mẫu nhà máy không phải là kẻ vi phạm là OCP.

Tùy thuộc vào cách bạn có hành vi của Complex hơn nữa.

Nếu Complex là cần thiết để hỗ trợ việc sản xuất các loại mới của Complex đối tượng, và bạn chọn để sửa đổi Complex bằng cách thêm fromX phương pháp mới được bổ sung để hỗ trợ họ, sau đó điều này có nghĩa rằng Complex trở thành một người vi phạm của OCPComplex phải được mở lại cho sửa đổi:

class Complex 
{ 
    public static Complex fromCartesian(double real, double imag) { 
     return new Complex(real, imag); 
    } 

    public static Complex fromPolar(double modulus, double angle) { 
     return new Complex(modulus * cos(angle), modulus * sin(angle)); 
    } 

    //class opened for modification 
    public static Complex fromOtherMeans(String x , String y) { 
     return new Complex(x, y); 
    } 
} 

bạn có thể đẩy vấn đề này xuống vào một tập tin văn bản hoặc tập tin thuộc tính của một số loại để giải oan cho mình vì phải thay đổi lớp java, nhưng nó không ngăn cản bạn từ việc phải viết thêm logic trong lĩnh vực này của giải pháp theo thứ tự er để hỗ trợ các loại mới Complex.

Tùy thuộc vào việc sử dụng Complex trong thiết kế của bạn (các loại khác nhau như thế nào? Bạn đang sử dụng chúng như thế nào?), Có một số tùy chọn thay thế có thể áp dụng tốt.

Một ví dụ như OCP thay thế thân thiện là phân lớp Complex để cung cấp phương thức nhà máy bổ sung. Một lớp con là minh hoạ đơn giản nhất về cách Complex được mở rộng nhưng không được sửa đổi.

Một OCP thay thế thân thiện khác để thay đổi Complex trong trường hợp này là Decorator pattern. Liên tục trang trí Complex với khả năng tạo các biến thể mới của Complex tôn trọng OCP vì Complex không được sửa đổi nhưng được mở rộng bằng cách gói nó với chức năng mới.

Phương án thay thế thứ ba có thể là thay đổi cấu trúc của Complex để tính toán của nó được cung cấp theo bố cục. Điều này sẽ mở ra cho bạn cơ hội sử dụng số Strategy pattern để phân biệt giữa các hành vi khác nhau của Complex.

Điều về mẫu Nhà máy là nó giúp tuân thủ mã ngữ cảnh OCP. Người ta có thể sử dụng một trong những kỹ thuật trên để ở bên phải của OCP với lớp Nhà máy của họ, nhưng đồng nghiệp của bạn có thể xem xét đồ thị đối tượng, đặt câu hỏi về sự khôn ngoan của việc có đồ thị đối tượng trên một Nhà máy và đơn giản hóa nó trở lại một Nhà máy, đưa bạn trở lại ví dụ đầu tiên.

Trong trường hợp này, thay vì cố gắng uốn cong việc triển khai mẫu Nhà máy để tôn trọng các nguyên tắc SOLID, hãy xem xét lý do bạn sử dụng nó ở tất cả.