2010-03-18 36 views
14

Tôi đã tự hỏi, tại sao phương pháp tĩnh Create tồn tại?Tại sao phương thức tĩnh Tạo tồn tại?

Ví dụ, tại sao sử dụng mã này:

System.Xml.XmlReader reader = System.Xml.XmlReader.Create(inputUri); 

qua mã này:

System.Xml.XmlReader reader = new System.Xml.XmlReader(inputUri); 

tôi không thể tìm ra lý do cho việc sử dụng một trong khác, và không thể tìm thấy bất kỳ mối quan hệ giữa các lớp học sử dụng cấu trúc này so với các lớp khác.

Có ai có thể làm sáng tỏ điều này không?

Trả lời

17

XmlReader là lớp trừu tượng. Bạn không thể khởi tạo nó.

Cung cấp phương thức Create là ví dụ về mẫu nhà máy. Tùy thuộc vào các đối số đã chỉ định, việc thực thi XmlReader khác nhau được chọn và trả về. Ví dụ, có xác thực XmlReader xác nhận và không xác nhận hợp lệ trong khuôn khổ .NET.

+0

Không bao giờ nhận thấy thực tế nó trừu tượng. Điều này có đúng với mọi lớp học có phương pháp như vậy không? – GeReV

+1

+1 nhưng bạn có thể đã dành thêm vài dòng để đưa ra một ví dụ nhỏ .. –

+0

@GeReV: Có nhiều lớp trừu tượng trong khung .NET cung cấp phương thức Tạo. Nhưng đó không phải là một yêu cầu. Đó là một mẫu thiết kế. – dtb

5

Bởi vì nó thực sự có thể tạo và đối tượng của loại có nguồn gốc mà bạn không có quyền truy cập hoặc trả về một lớp trừu tượng (như dtb trả lời). Đây là factory method pattern.

+0

Vâng, nếu bạn thực sự đọc bài viết wikipedia bạn dán bạn sẽ nhận thấy rằng nó mô tả một mô hình hoàn toàn khác nhau. – Grzenio

+0

Đó là cùng một mẫu. Tùy thuộc vào các tham số được truyền cho phương thức mà nó tạo ra các đối tượng thuộc các kiểu khác nhau. –

+1

Đọc lại. Mẫu mà bạn đã liên kết tạo ra các cá thể mới tùy thuộc vào việc triển khai thực hiện một phương thức Tạo trừu tượng, không phải trên các đối số được truyền cho một triển khai đơn lẻ, phổ biến. Nó rất giống nhau. – dtb

3

Mẫu này cho phép lớp XmlReader cung cấp cho bạn các phiên bản của các lớp dẫn xuất phù hợp với thông số bạn đã chuyển đến Create. Lưu ý đặc biệt là các quá tải chấp nhận một đối tượng XmlReaderSettings. Một lớp con khác nhau XmlReader có thể được trả lại cho bạn tùy thuộc vào cài đặt của bạn.

Ví dụ tốt hơn là WebRequest.Create(url). Tùy thuộc vào địa chỉ URL bạn vượt qua, bạn có thể nhận được một HttpWebRequest, một FtpWebRequest vv

3
  • Bởi vì bạn không cần phải cam kết các lớp chính xác của đối tượng bạn nhận được. Các nhà xây dựng chỉ có thể xây dựng các đối tượng từ chính xác một lớp.
  • Bởi vì bạn có thể đặt tên cho một phương thức có ý nghĩa, ví dụ: BigInt.probablePrime(). Các nhà xây dựng chỉ có thể có cùng tên với lớp.
  • Vì bạn có thể có nhiều phương pháp nhà máy cho cùng một kết hợp loại thông số, ví dụ: Point.fromPolarCoords (int, int) và Point.fromCartesianCoords (int, int), nhưng chỉ có thể có một hàm tạo (int, int).

(Một câu trả lời chi tiết hơn được đưa ra trong Bloch của 'Effective Java'.)

1

Đôi khi chúng tồn tại như một hình thức tự tài liệu. Tôi có một thành phần truy cập db mà tôi có thể khởi tạo hoặc với một chuỗi kết nối hoặc tên của kết nối trong tệp cấu hình. Cả hai phương thức này lấy các chuỗi như một tham số để chúng không thể phân biệt bằng các tham số. Vì vậy, tôi đã tạo phương thức nhà máy FromConnectionString(string) và phương pháp nhà máy FromConnectionName(string). Sắc thái này hoàn toàn sẽ bị mất bởi đường dây new Foo(bool, string).

6

Một câu trả lời tổng quát hơn ...

Lý do những người như các loại phương pháp, được gọi là "phương pháp nhà máy tĩnh", là bởi vì bạn có thể cung cấp cho họ một tên (như trái ngược với nhà xây dựng).Vì vậy, nếu bạn cần ba nhà xây dựng khác nhau, bạn có thể tạo các phương thức nhà máy tĩnh có tên liên quan đến việc sử dụng chúng.

Một lý do khác là phương pháp nhà máy không thực sự cần tạo đối tượng mới - nó có thể trả về cùng một lần nếu cần.

4

Một hàm tạo chỉ có thể được sử dụng để tạo các cá thể của một lớp cụ thể, trong khi phương thức tĩnh Create có thể tạo một thể hiện của các lớp khác nhau tùy thuộc vào đầu vào.

Trong trường hợp của XmlReader lớp phương pháp Create sẽ trả về một XmlDictionaryReader, XmlTextReader, XmlValidatingReader hoặc XmlNodeReader, tùy thuộc vào quá tải bạn sử dụng và những gì các tham số bạn gửi cho nó.

0

Ý tưởng là theo cách này họ có thể thay đổi việc triển khai XmlReader và không phá vỡ bất kỳ mã người dùng nào (ví dụ: họ có thể thay đổi loại thực tế được trả về từ phương thức Tạo).

Cá nhân tôi không thích cách tiếp cận này, bởi vì nó tạo ra một mối quan hệ nghịch đảo trong phân cấp lớp XmlReader. Có lẽ họ nghĩ rằng các mô hình nhà máy là một overkill?

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