C# 灵活的课堂设计,遵循开闭原则
我正在玩一些应用程序,并进行一些重构,以使其更加灵活。正如我所料,出现了很多问题。 例如,我正试图找到一种最佳的方法来删除太空船级集合中的项目C# 灵活的课堂设计,遵循开闭原则,c#,oop,design-patterns,C#,Oop,Design Patterns,我正在玩一些应用程序,并进行一些重构,以使其更加灵活。正如我所料,出现了很多问题。 例如,我正试图找到一种最佳的方法来删除太空船级集合中的项目 class Spaceship{ List<Weapon> Weapons {get;set;} List<Shield> Shields {get;set;} public void RemoveEquipment(Equipment item){ switch(item.EquipmentType ) { c
class Spaceship{
List<Weapon> Weapons {get;set;}
List<Shield> Shields {get;set;}
public void RemoveEquipment(Equipment item){
switch(item.EquipmentType )
{
case EquipmentType.Weapon:
weapons.Remove(item);
break;
case EquipmentType.Shield:
shields.Remove(item);
break;
}
}
public void AddEquipment(Equipment item){
//works the same way as RemoveEquipment
}
}
class Equipment{
//EquipmentType is enum
EquipmentType Type {get;set;};
}
class Weapon: Equipment{
}
class Shield:Equipment{
}
class AutoCannon:Weapon{
}
class LaserGun:Weapon {
}
级宇宙飞船{
列出武器{get;set;}
列表屏蔽{get;set;}
公共无效清除设备(设备项){
开关(项目.设备类型)
{
箱子装备类型。武器:
武器。移除(项目);
打破
外壳设备类型。屏蔽:
屏蔽。移除(项目);
打破
}
}
公用设备(设备项){
//与RemoveeEquipment的工作方式相同
}
}
类设备{
//设备类型为enum
EquipmentType类型{get;set;};
}
武器类别:装备{
}
防护等级:设备{
}
自动驾驶舱:武器{
}
激光枪:武器{
}
有更好的办法吗?如果我想删除相同子类型的一组项目(例如,武器收藏中的每个激光枪-不使用反射),该怎么办
如果我想添加新类型的设备,则必须修改负责添加/删除的方法(开关/案例) 根据经验,您不希望公开类型为
List
的属性,尤其是如果它们不是只读的。我建议将武器
和盾牌
属性更改为IEnunerable
或至少IReadOnlyList
,并将其设置为只读
话虽如此,您的太空船
类可以如下所示:
// internal is the default access modifier for types, but it's more descriptive to specify it.
internal class Spaceship
{
private List<Equipment> _equipment = new List<Equipment>();
public IEnumerable<Weapon> Weapons {get {return _equipment.OfType<Weapon>();}}
public IEnumerable<Shield> Shields {get {return _equipment.OfType<Shield>();}}
public void RemoveEquipment(Equipment item)
{
_equipment.Remove(item);
}
public void AddEquipment(Equipment item)
{
_equipment.Add(item);
}
}
public void RemoveEquipment<T>() where T : Equipment
{
_equipment.RemoveAll(e => e is T);
}
//internal是类型的默认访问修饰符,但指定它更具描述性。
内舱宇宙飞船
{
私有列表_设备=新列表();
公共IEnumerable武器{get{return_equipment.OfType();}}
公共IEnumerable Shields{get{return{u equipment.OfType();}}
公共无效清除设备(设备项)
{
_设备。移除(项目);
}
公用设备(设备项)
{
_设备。添加(项目);
}
}
然后,为了移除特定类型的所有设备,您可以执行以下操作:
// internal is the default access modifier for types, but it's more descriptive to specify it.
internal class Spaceship
{
private List<Equipment> _equipment = new List<Equipment>();
public IEnumerable<Weapon> Weapons {get {return _equipment.OfType<Weapon>();}}
public IEnumerable<Shield> Shields {get {return _equipment.OfType<Shield>();}}
public void RemoveEquipment(Equipment item)
{
_equipment.Remove(item);
}
public void AddEquipment(Equipment item)
{
_equipment.Add(item);
}
}
public void RemoveEquipment<T>() where T : Equipment
{
_equipment.RemoveAll(e => e is T);
}
public void RemoveEquipment(),其中T:设备
{
_设备拆除(e=>e为T);
}
您还可以同时添加一组设备:
public void AddEquipment(IEnumerable<Equipment> items)
{
_equipment.AddRange(items);
}
public void AddEquipment(IEnumerable items)
{
_设备。添加范围(项目);
}
请注意,并没有更麻烦的开关语句,也几乎并没有涉及特定类型的设备——除非你们明确需要盾牌和武器
当然,主要的好处是,当添加一种新型装备时,你不需要改变你的
太空船类来支持它(当然,除非你想拥有一个专门用于该特定类型装备的属性,如武器或盾牌).你真的需要有武器
和盾牌
设定器吗?如果您可以使这些属性成为只读属性,那么就可以轻松地使用泛型来生成更好、更短的代码。另外,一艘船可以有多种武器或盾牌吗?因为如果可以,那么这些属性应该是IEnumerable
和IEnumerable
而不是单个武器或盾牌。我错了,这些属性是集合