2012-06-20 29 views
26

Tôi đang tự hỏi về thực hành tốt nhất ở đây. Có thực hành tốt cho phương pháp nhà máy để trả về null nếu nó không thể tạo ra bất kỳ thứ gì? Dưới đây là ví dụ:Có OK cho phương thức factory để trả về null không?

ICommand command = CommandFactory.CreateCommand(args); 
if (command != null) 
    command.Execute(); 
else 
    // do something else if there is no command 

Một cách khác là trả lại NullCommand hoặc một điều gì đó, tôi đoán, nhưng cách tốt nhất là gì?

Trả lời

31

Tôi nghĩ rằng có khả năng hợp lý để phương thức nhà máy trả về giá trị rỗng trong một số trường hợp, nhưng không phải nếu đó là phương thức được gọi là CreateCommand. Nếu đó là GetCommand hoặc FetchCommand, điều đó có thể không sao ... nhưng phương pháp Create sẽ đưa ra một ngoại lệ về lỗi, tôi sẽ đề xuất.

Dù bạn thực sự muốn trả lại null trong trường hợp này tùy thuộc vào bức tranh lớn hơn, tất nhiên. (Có thực hiện đối tượng null hợp lý mà bạn có thể trả lại không, ví dụ?)

+0

Đồng ý với @Jon Skeet. Tạo hàm tạo hàm ý, và bạn không mong đợi một null từ một trong số chúng, vì vậy không chắc bạn sẽ kiểm tra xem đó có phải là những gì nó đã làm hay không. –

+0

@TonyHopkinson: Ở phía bên kia, bạn sẽ không mong đợi một ngoại lệ từ một nhà xây dựng hoặc. –

+6

@TimSchmelter: Tại sao không? Tôi sẽ * hoàn toàn * mong đợi một ngoại lệ từ các nhà thầu trong các tình huống nhất định - 'FileStream' là một ví dụ cổ điển ...hoặc bất kỳ thông số nào có thể không hợp lệ dưới bất kỳ hình thức nào, ví dụ: đưa ra một tham chiếu null cho một cái gì đó mong đợi một tham chiếu không null. –

1

Tôi đồng ý với Jon Skeet. CreateCommand ngụ ý xây dựng rõ ràng.

Nếu bạn không ném Exception, thì trong trường hợp đó, tôi sẽ đích thân thực hiện triển khai NullCommand, để tránh báo cáo có điều kiện ở tất cả người tiêu dùng và có thể xảy ra lỗi NullReferenceException.

3

Trả lại null trong trường hợp này sẽ làm cho phương pháp của bạn khó sử dụng hơn; khách hàng phải nhận thức được tình trạng lỗi ngầm. Thay vào đó, hãy ném ngoại lệ và bạn cũng có thể cung cấp phương pháp riêng để khách hàng thử nghiệm cho điều kiện này:

if (CommandFactory.CanCreate(args)) { 
    ICommand command = CommandFactory.Create(args); 
    command.Execute(); 
} 

Hoặc làm cho nhà máy có thể khởi chạy; đó sẽ là tốt hơn nếu bạn cần phải args quá trình trước:

CommandFactory factory = new CommandFactory(args); 
if (factory.IsValid()) { 
    ICommand command = factory.Create(); 
    command.Execute(); 
} 

Giao diện của nhà máy hiện nay làm cho nó rõ ràng và rõ ràng rằng sự sáng tạo có thể thất bại, nhưng nó vẫn đòi hỏi khách hàng để sử dụng phương pháp kiểm tra. Một lựa chọn khác là thế này:

ICommand command; 
if (CommandFactory.TryCreate(args, out command)) { 
    // creation succeeded ... 
} 
+0

_ "có thể sẽ thất bại nếu chúng không kiểm tra null" _ Vì C# không hỗ trợ ngoại lệ đã kiểm tra (không giống như java), khách hàng cũng có thể thất bại nếu họ không xử lý ngoại lệ đó, vì vậy đó không phải là một đối số mạnh (imho) . –

+1

@TimSchmelter: Tôi đã sửa đổi từ ngữ của mình trên cụm từ đó .... Hy vọng quan điểm của tôi rõ ràng hơn bây giờ. –

0

Nó chỉ có ý nghĩa để trở Null nếu có một lý do tại sao bạn sẽ muốn người dùng phải kiểm tra cho null mỗi lần ông gọi là Tạo. Thông thường bạn sẽ xem xét sau một mô hình sử dụng hoàn toàn hợp lệ:

var obj = MyFactory.CreateThing(); 
obj.DoSomething(); 

Nhưng những gì bạn đang đề xuất là để buộc các mô hình sử dụng sau đây:

var obj = MyFactory.CreateThing(); 
if (obj == Null) { 
    // Handle null condition 
} else { 
    obj.DoSomething(); 
} 

Thông thường Null kịch bản sẽ có nghĩa là một số loại thất bại, trong trường hợp đó một ngoại lệ có lẽ sẽ có ý nghĩa nhất. Nhưng cuối cùng bạn là nhà sản xuất âm nhạc ở đây và phải quyết định điều gì là hợp lý trong thế giới bạn đang xây dựng.

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