2009-07-28 25 views
12

Tôi muốn trả lại một Giao diện và bên trong một câu lệnh chuyển đổi mà tôi muốn thiết lập. Đây có phải là thiết kế tồi không?Tuyên bố chuyển đổi có thể áp dụng trong phương pháp nhà máy không? C#

private IResultEntity GetEntity(char? someType) 
    { 
     IResultEntity entity = null; 

     switch (someType) 
     { 
      case 'L': //life 
       entity = new LifeEntity(); 
       break; 
      case 'P': //property 
       entity = new PropertyEntity(); 
       break; 
      case 'D': //disability 
       entity = new DisabilityEntity(); 
       break; 
      case 'C': //credit card 
       entity = new CreditCardEntity(); 
       break; 
     } 

     return entity; 
    } 

Trả lời

19

Tôi thường không nhớ các câu lệnh chuyển đổi trong nhà máy, miễn là tôi có thể nhóm và kiểm soát tất cả các lớp dẫn xuất mà tôi muốn tạo trước.

Đôi khi, có thể plugin do người dùng tạo có thể muốn thêm các lớp riêng của nó vào danh sách chuyển đổi đó và sau đó câu lệnh thụ động là không đủ.

tôi thấy tốt source for some more info này vào việc tạo ra một số chi tiết mạnh mẽ/classes nhà máy linh hoạt

Một trung đất cách tiếp cận tốt tôi thường thực hiện là để giữ một tĩnh từ điển < chuỗi, Type> cho mỗi lớp nhà máy.

Mọi người có thể chỉ là "đăng ký" hiện thực của riêng họ sử dụng một số loại

Factories.TypeRegistration.StaticDictionary.Add("somekey",typeof(MyDerivedClass)) 

(hoặc tốt hơn, sử dụng một phương pháp đăng ký và ẩn StaticDictionary)

thì Nhà máy có một nhiệm vụ dễ dàng tạo một cá thể bằng cách thực hiện tra cứu trong bảng:

Activator.CreateInstance(Factories.TypeRegistration.StaticDictionary["somekey"]); 
+0

Đây là cách tôi thường tiếp cận một nhà máy, đặc biệt là trong các thư viện nơi ứng dụng của khách hàng có thể muốn thêm triển khai của riêng họ. – Joon

+0

Nguồn đó để biết thêm liên kết thông tin không còn khả dụng, cơ hội nào đó được lưu trữ ở một nơi khác? Hoặc là có một bài tương đương ở đâu đó? –

+0

@Sam Heuck Tôi đã liên kết một phiên bản đã lưu trữ – Lennart

1

Tôi sẽ không nói thiết kế xấu của nó, mặc dù nó có khả năng khá cứng nhắc. Cách duy nhất để mở rộng điều này là thông qua biên dịch lại.

3

Tôi không biết, khả năng nào bạn có trong C#, nhưng tốt hơn là nên có một công tắc trong phương thức nhà máy hơn là có công tắc trên khắp nơi. Trong một phương thức nhà máy, một công tắc có thể chấp nhận được - nhưng tốt hơn là nó có thể được ghi lại.

+5

Câu trả lời này tóm tắt khá nhiều những gì tôi định nói. Tôi sẽ thêm rằng điều duy nhất tôi sẽ thay đổi trong việc triển khai nhà máy của bạn là tôi sẽ sử dụng một liệt kê thay vì một char không có khả năng là chìa khóa nhà máy. – wtaniguchi

+0

Làm thế nào để chuyển đổi một char vô giá thành một enum? Tôi không nghĩ rằng bạn có thể làm cho một enum của chuỗi hoặc ký tự. Tôi nghĩ rằng chúng đại diện cho các giá trị số. – Hcabnettek

+1

Chắc chắn đồng ý với enum về nhân vật 'huyền diệu'. Ngoài ra, bạn có thể muốn ném một ngoại lệ nếu bạn không thể tìm thấy trường hợp chính xác thay vì trả về null. Tôi nghĩ rằng đó chỉ là một sở thích. – kevindaub

2

Tôi không nghĩ có điều gì sai trái với điều này. Có, báo cáo chuyển đổi là một mã số mùi, nhưng trong cuốn sách của tôi, họ đang OK trong tình huống này. Có rất ít thứ khác bạn có thể làm để đạt được những thứ như thế này.

3

Tôi muốn có loại bạn muốn khởi tạo cho một giá trị cụ thể trong tệp cấu hình. Cái gì như:

<TypeMappings>
< tên TypeMapping = "cuộc sống" type = "Entities.LifeEntity, Tổ chức"/>
< TypeMapping name = "sở hữu" type = "Entities.PropertyEntity, Tổ chức"/>
< tên TypeMapping = "khuyết tật" type = "Entities.DisabilityEntity, Tổ chức"/>
< TypeMapping name = "creditcard" type = "Entities.CreditCardEntity, Tổ chức"/>
</TypeMappings >

Bên trong phương pháp của bạn, bạn sau đó có thể trích xuất tất cả các đăng ký từ các tập tin cấu hình, tìm ra phù hợp với phản ánh một và sử dụng để nhanh chóng các loại, nếu đăng ký là không tìm thấy, bạn ném một ngoại lệ.

Dưới đây là một số mẫu mã:

namespace Entities 
{ 

public interface IResultEntity 
{ 
} 

public class LifeEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a Life entity"); 
    } 
} 

public class PropertyEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a Property Entity"); 
    } 
} 

public class CreditCardEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a CreditCard Entity "); 
    } 
} 

public class DisabilityEntity : IResultEntity 
{ 
    public override string ToString() 
    { 
     return("I'm a Disability Entity"); 
    } 
} 

}

public static Entities.IResultEntity GetEntity(string entityTypeName,string fileName) 
{ 
    XDocument doc = XDocument.Load(fileName); 
    XElement element = doc.Element("TypeMappings").Elements("TypeMapping") 
           .SingleOrDefault(x => x.Attribute("name").Value == entityTypeName);   

    if(element == null) 
    { 
     throw new InvalidOperationException("No type mapping found for " + entityTypeName); 
    } 
    string typeName = element.Attribute("type").Value; 
    Type type = Type.GetType(typeName); 
    Entities.IResultEntity resultEntity = Activator.CreateInstance(type) as Entities.IResultEntity; 
    if(resultEntity == null) 
    { 
     throw new InvalidOperationException("type mapping for " + entityTypeName + " is invalid"); 
    } 
    return resultEntity; 
} 

    public static void Main() 
{ 
    try 
    { 
     Entities.IResultEntity result = GetEntity("life", @"c:\temp\entities.xml"); 
     Console.WriteLine(result); 

     result = GetEntity("property", @"c:\temp\entities.xml"); 
     Console.WriteLine(result); 

     result = GetEntity("disability", @"c:\temp\entities.xml"); 
     Console.WriteLine(result);   

     result = GetEntity("creditcard", @"c:\temp\entities.xml"); 
     Console.WriteLine(result);   

     result = GetEntity("foo", @"c:\temp\entities.xml"); 
     Console.WriteLine(result);  

    } 
} 

Rất nhiều các khuôn khổ DI phép bạn cung cấp nhiều đăng ký cho một giao diện mà bạn có thể truy vấn dựa trên siêu dữ liệu. Khám phá this link về cách MEF thực hiện xuất bằng siêu dữ liệu.

+0

trông giống như quá mức cần thiết –

2

Nó không phải là xấu, nó gần như chính xác giống như một ví dụ (Parameterized Factory Method) trong chính Gang of Four Bible.

Tôi từng nghĩ rằng các câu lệnh chuyển đổi là mùi mã, chúng không có, chúng có vị trí của chúng trong bất kỳ ngôn ngữ OO nào.

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