Một phương pháp để đạt được đúng OCP có thể là như sau:
Xác định một phương pháp trừu tượng Is
để buộc mỗi kiểu phụ cụ thể của động vật có vú để xác định xem nó có phù hợp với một giá trị nhất định của enum:
abstract public class Mammal
{
public abstract void MakeSound();
public abstract bool Is(MammalTypes mammalType);
}
việc triển khai của Is trong lớp con sẽ như thế nào:
class Cat : Mammal
{
// other specific members
public override bool Is(MammalTypes mammalType)
{
return mammalType == MammalTypes.Cat;
}
}
class Dog : Mammal
{
// other specific members
public override bool Is(MammalTypes mammalType)
{
return mammalType == MammalTypes.Dog;
}
}
này đang được thực hiện, chúng tôi bây giờ có thể tạo ra một MammalF lớp actory rằng, khi đưa ra một động vật có vú quét giá trị enum thông qua các lớp có sẵn và khi nó tìm thấy một trận đấu, nó sẽ trả về một thể hiện của lớp đó:
public class MammalFactory
{
private readonly IEnumerable<Type> _mammalTypes;
public MammalFactory()
{
var currentAssembly = Assembly.GetExecutingAssembly();
_mammalTypes = currentAssembly.GetTypes()
.Where(t => typeof(Mammal).IsAssignableFrom(t) && !t.IsAbstract);
}
public Mammal Create(MammalTypes mammalType)
{
return _mammalTypes
.Select(type => CreateSpecific(type, mammalType))
.First(mammal => mammal != null);
}
public Mammal CreateSpecific(Type type, MammalTypes mammalEnumType)
{
var mammalInstance = (Mammal)Activator.CreateInstance(type);
return mammalInstance.Is(mammalEnumType) ? mammalInstance : null;
}
}
Việc sử dụng cuối cùng sẽ trông như thế này:
var mammalFactory = new MammalFactory();
var guessWhatMammal = mammalFactory.Create(MammalTypes.Cat);
Điều này hoàn toàn tuân thủ OCP. Nó chỉ là cần thiết để tạo ra một lớp Mammal mới cho nó được tự động có dây và sẵn sàng để sử dụng trong ứng dụng. (Không cần phải sửa đổi bất cứ điều gì khác trong việc áp dụng, trừ các enum chính nó)
Có một số vấn đề với cách tiếp cận này:
- nó chỉ quét lắp ráp hiện đang thực hiện với nhiều loại động vật có vú
- nó có để tạo ra một thể hiện của động vật có vú mỗi khi nó cần phải kiểm tra xem loại đó là thích hợp
trong khi những vấn đề này có thể được giải quyết, người ta vẫn còn để lại: phức tạp.
Đây là phức tạp bởi vì:
- chúng tôi đã tăng gấp đôi số lượng mã cần thiết
- tự động hệ thống dây điện có thể gây nhầm lẫn cho người mới đến dự án
Tôi nghĩ rằng kết luận là điều này: các mẫu thiết kế không phải là các quy tắc nghiêm ngặt. Nó không phải là giá trị làm một cái gì đó chỉ để phù hợp với một thiết kế nhất định. Thay vào đó, chúng ta phải thực dụng và thấy rằng sự cân bằng hoàn hảo giữa sự phù hợp với mô hình và tính hữu ích/đơn giản/dễ đọc. Điều này phụ thuộc rất nhiều vào vấn đề chúng tôi cố gắng giải quyết và trong nhiều trường hợp, nó có thể rất tốt là tuyên bố switch
mà bạn trình bày trong câu hỏi.
Đó là ** NOT ** Object Oriented. Lớp cơ sở không nên biết về các lớp dẫn xuất của nó. – gdoron
Thật khó để hình dung những gì bạn đã làm. Vui lòng thêm mã mà bạn đã viết cho câu hỏi của mình. – Abbas