先讲一个重要的设计原则:合成/聚合复用原则,尽量使用合成/聚合,尽量不要使用类继承。
聚合表示一种弱的拥有关系,体现的是A对象可以保护B对象,但B对象不是A对象的一部分,合成则是一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。比方说大雁有两个翅膀,翅膀与大雁是部分和整体的关系,并且它们的生命周期是相同的,与是大雁和翅膀就是合成关系。而大雁是群居动物,所以每只大雁都是属于一个雁群,一个雁群可以有多只大雁,所以大雁和雁群是聚合关系。
合成/聚合复用原则的好处是:优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上,这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。你需要使用学会用对象的职责,而不是结构来考虑问题。
分析:手机是不同的品牌公司,各自做自己的软件,而PC却是硬件厂商做硬件,软件厂商做软件,组合起来才是可用的机器。
实际上游戏、通讯录、MP3播放器这些功能都是软件,如果我们可以让其分离与手机耦合,那么就可以大大减少面对新需求时改动过大的不合理情况 。
手机品牌包含有手机软件,但软件并不是品牌的一部分,所以它们之间是聚合关系。
abstract class HandsetSoft {
public abstract class Run();
}
class HandsetGame : HandsetSoft {
public override void Run() {
Console.WriteLine("运行手机游戏");
}
}
class HandsetAddressList : HandsetSoft {
public override void Run(){
Console.WriteLine("运行手机通讯录");
}
}
abstract class HandsetBrand {
protected HandsetSoft soft;
public void SetHandsetSoft(HandsetSoft soft) {
this.soft = soft;
}
public abstract void Run();
}
class HandsetBrandN : HandsetBrand {
public override void Run(){
soft.Run();
}
}
class HandsetBrandM : HandsetBrand {
public override void Run(){
soft.Run();
}
}
static void Main(string [] args){
HandsetBrand ab;
ab = new HandsetBrandN();
ab.SetHandsetSoft(new HandsetGame());
ab.Run();
ab.SetHandsetSoft(new HandsetAddressList());
ab.Run();
ab = new HandsetBrandM();
ab.SetHandsetSoft(new HandsetGame());
ab.Run();
ab.SetHandsetSoft(new HandsetAddressList());
ab.Run();
}