装饰者模式(Decorator Pattern)

定义:动态地将责任附加到对象上,是和继承不同的一种拓展功能的方式。

​ 还是需要扩展原有类功能的场景,这次介绍OO中的另一个著名原则——对扩展开放,对修改关闭。之前的策略模式实际上就体现了这一原则,我们在使用策略模式委托(delegate)其他类来实现具体功能,具体功能在运行时才指定,增加新功能不需要修改原有类的代码。而装饰者模式提供了解决问题的另一种方式。

​ 在装饰者模式中,基本类通过装饰类来拓展自己的功能。具体来说,基本类和装饰类需要继承自相同的抽象类或者接口,装饰类就像一个外壳套在基本类上,由于它们继承自相同的抽象类,在使用是可以利用多态,使用者无需知道一个对象有没有被装饰过或者被装饰过多少次。那么如何装饰?假设我们要增强基本类中一个方法的功能,装饰类中当然也有同名方法,装饰类的对应方法中首先必定会调用被装饰者的对应方法(原有的功能),在此基础上,装饰类中的方法可以增加额外的功能。具体实例在调用该方法时,首先调用的是最外层装饰类的方法,最外层装饰类会调用下一次装饰(或基本类)的对应方法,通过这样类似递归的方式,使基本类的功能得到拓展。由于基本类和装饰类继承自相同的抽象类,示例在调用方法时无需知道是否经过了装饰。

​ 装饰者模式的例子就是JAVA或其他编程语言中的IO类,我们可以看到IO类中有非常基础的类,如单纯向流中输出输出,或者有进一步的封装的类,还有具有高抽象的println等方法,我们容易理解,这些类实际上是通过装饰者模式一层一层封装得到的。由此我们也看到装饰者模式的一个缺点,就是可能产生大量的小类,有可能增加系统的复杂度。

工厂模式(Factory Pattern)

定义:工厂模式定义了一个创建对象的接口,但由子类决定要创建的类是哪一个。工厂模式把实例化推迟到子类。

​ 利用OO的多态时,我们常常需要根据不同的条件创建不同的子类。这个过程可以通过一系列条件判断来完成,但是这样做有很大的局限性。如果增加了新的子类,我们就需要修改原本创建对象的代码,这违反了之前对扩展开放,对修改关闭的原则,同时也不满足面向接口编程而不是面向实现编程。在工厂模式中,我们在需要创建对象的类(Creator)中声明抽象的工厂方法,工厂方法具体由子类实现,父类并不关心对象的创建过程。这样做既实现了封装容易变化的代码(增加子类时工厂方法的实现需要改变),又实现了功能代码与创建对象的代码的解耦。

​ 上述工厂模式使用继承来实现创建对象代码与其他代码的解耦,还有一种抽象工厂模式则通过对象的组合实现类似的效果。在抽象工厂方法中,我们创建一个抽象工厂的接口,对象的创建被实现在接口所暴露出来的方法中。