1.面向对象设计最困难的部分是将系统分解成对象集合。因为要考虑许多因素:封装,粒度,依赖关系,灵活性,性能,演化,复用等等,他们都影响着系统的分解,并且这些因素通常还是互相冲突的。
2.设计模式帮我们确定并不明显的抽象和描述这些抽象的对象。如描述过程或算法的对象现实中并不存在,但他们却是设计的关键部分。strategy(策略)模式描述了怎样实现可互换的算法族。state(状态)模式将实体的每一个状态描述为一个对象。
3.决定对象的粒度。
Facade(外观)模式描述了怎样用对象表示完整的子系统。flyweight(享元模式)描述了如何支持大量的最小粒度的对象。
Abstract Factory (抽象工厂)和Builder(生成器)模式产生哪些专门负责生成其他对象的对象。Visitor(访问者模式)和 Commond(命令)模式生成的对象专门负责实现对其他对象或对象组的请求。
4.在面向对象系统中,接口是基本的组成部分。
5.白箱复用:类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被成为白箱复用。在继承方式中,父类的内部细节对子类可见。
黑箱复用:新的更复杂的功能,可以通过组装和组合对象来获得。对象的组合要求被组合的对象具有良好定义的接口。这种复用风格成为黑箱复用。
6.委托是一种组合方法。它使组合更具有与继承同样地复用能力。
有一些模式使用了委托。如State(状态模式),Strategy(策略模式),和Visitor(访问者模式)。在State(状态)模式中,一个对象将请求委托给一个描述当前状态的State对象来处理。在Strategy(策略)模式中,一个对象将一个特定的请求委托给一个描述请求执行策略的对象,一个对象只会有一个状态,但它对不同的请求可以有许多策略。这两个模式的目的都是通过改变委托对象来改变委托对象的行为。在Visitor中,对象结构的每个元素上的操作总是被委托到Visitor对象。
7.聚合与相识。
聚合意味着一个对象拥有另一个对象或对另一个对象负责。一般我们称一个对象包含另一个对象或者是另一个对象的一部分。聚合意味着聚合对象和其所有者具有相同的生命周期。
相识意味着一个对象仅仅知道另一个对象。有时相识也被称为“关联”或“引用”关系。相识的对象可能请求彼此的操作。但是不对对方负责。相识是一种比聚合要弱的关系,它只表示了对象间较松散的耦合关系。
8.设计应该支持变化
(1).通过显式的指定一个类来创建对象 在创建对象时指定类名将使你受特定实现的约束而不是特定接口的约束。这会使未来的变化更复杂。要避免这种情况,应该间接的创建对象。
设计模式:Abstract Factory(抽象工厂模式),Factory Method(工厂模式),Prototype(原型模式)
(2)对特殊操作的依赖: 当你为请求指定一个特殊的操作时,完成该请求的方式就固定下来。为避免把请求代码写死,你将可以在编译时刻或运行时刻很方便的改变响应请求的方法。
设计模式:Chain of Responsibility(责任链模式),Commond(命令模式)
(3)对硬件和软件平台的依赖 外部的操作系统接口和应用编程接口在不同的软硬件平台上是不同的。依赖于特定平台的软件将很难移植到其他平台上,甚至都很难跟上本地平台的更新。所以设计系统时限制其平台相关性就很重要了。
设计模式:Abstract Factory(抽象工厂), Bridge(桥模式)
(4)对对象表示或实现的依赖
知道对象怎样表示、保存、定位或实现的客户在对象发生变化时可能也需要变化。对客户隐藏这些信息能阻止连锁变化。
设计模式:Abstract Factory(抽象工厂),Bridge(桥模式),Memento(备忘录模式),Proxy(代理模式)
(5)算法依赖 算法在开发和复用时常常被扩展、优化和替代。依赖于某个特定算法的对象在算法发生变化时不得不变化。因此有可能发生变化的算法应该被孤立起来。
设计模式:Builder(生成器模式),Iterator(迭代器模式),Strategy(策略模式),Template Method(模板方法模式),Visitory(访问者模式)
(6)紧耦合。 紧耦合的类很难独立的被复用,因为它们是互相依赖的。紧耦合产生单块的系统,要改变或删掉一个类,你必须理解或改变其他许多类。这样的系统是一个很难学习、移植和维护的密集体。
松散耦合提高了一个类本身被复用的可能性,并且系统更容易于学习、移植、修改和扩展。设计模式使用抽象耦合和分层技术来提高系统的松散耦合性。
设计模式:Abstract Factory(抽象工厂模式),Command(命令模式),Facade(外观模式),Mediator(设计者模式),Observer(观察者模式),Chain of Responsibility(责任链模式)
(7)通过生成子类来扩充功能。
通常很难通过定义子类来定制对象。每一个新类都有固定的实现开销(初始化,终止处理等)。定义子类还需要对父类有深入的了解。如,重定义一个操作可能需要重定义其他操作。一个被重定义的操作可能需要调用继承下来的操作。并且子类方法会导致类爆炸,因为即使对于一个简单的扩充,也不得不引入许多新的子类。
设计模式:Bridge(桥模式),Chain of Responsibility(责任链模式)
(8)不能方便地对类进行修改。对类的修改难以进行。
设计模式:Adapter(适配器模式), Decorator(装饰模式),Visitor(访问者模式)