目录
工厂模式:
工厂模式的分类:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式 :
什么时候使用简单工厂模式?
1.需要创建的对象少
2.不需要关注对象的创建过程
实现方式
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
优点
工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。
缺点
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
注意:由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
工厂方法模式:
抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。
抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。
具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
什么时候使用工厂方法模式?
1.一个类不需要知道所需对象的类,只需要知道具体类对应的工厂类。
2.一个类通过其子类来决定创建哪个对象,工厂类只需提供一个创建对象的接口。
3.将创建对象的任务委托给具体工厂,也可以动态指定由哪个工厂的子类创建。
优点:
工厂方法模式是为了克服简单工厂模式的缺点(主要是为了满足OCP)而设计出来的。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。工厂方法模式完全满足OCP,即它有非常良好的扩展性。
缺点:
如果某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦。比如说,每增加一个产品,相应的也要增加一个子工厂,会加大了额外的开发量。
注意:当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法,支持多扩展少修改的OCP原则。
抽象工厂模式:
何时使用抽象工厂模式?
需要一组对象完成某种功能或多组对象完成不同的功能
系统稳定,不会额外增加对象
优点:
1.分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。
2.易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。
3.有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。
缺点:
难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。
注意:一旦增加就需要修改原有代码,不符合开闭原则,所以尽可能用在不需要修改的场景。
适配器模式
适配器分类:
1.类适配器模式
2.对象适配器模式
3.接口适配器模式
适配器的目的:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
什么时候使用适配器模式?
1、系统需要使用现有的类,而此类的接口不符合系统的需要。
2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。
3、通过接口转换,将一个类插入另一个类系中。
优点:
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、增加了类的透明度。
4、灵活性好。
缺点:
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
注:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。Adapter 模式最大的作用还是将原本不兼容的接口融合在一起工作。
类适配器模式:
Adapter 类,通过继承 source 类,实现 Destination 类接口,完成 source->Destination 的适配。
对象适配器模式:
将 Adapter 类作修改,不是继承 source 类,而是持有 source 类的实例,以解决兼容性的问题。 即:持有 source 类,实现 Destination 类接口,完成source->Destination 的适配
接口适配器模式:
当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求
桥接模式
角色:
Client 类:桥接模式的调用者
Abstraction:维护了 Implementor/ 即它的实现类 ConcreteImplementorA.., 二者是聚合关系,Abstraction充当桥接类
xxxAbstraction :抽象的具体子类
Implementor :行为实现类的接口
ConcreteImplementorA /B:具体行为的实现类A、B
桥接模式的目的?
将抽象部分与实现部分分离,使它们都可以独立的变化。
什么时候使用桥接模式?
实现系统可能有多个角度分类,每一种角度都可能变化。
优点:
1、抽象和实现的分离。
2、优秀的扩展能力。
3、实现细节对客户透明。
缺点:
桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
注意事项及细节
实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性
对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其它的部分由具体业务来完成
桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本
注意事项:
1.对于两个独立变化的维度,使用桥接模式再适合不过了。
2.桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程
3.桥接模式要求正确识别出系统中两个独立变化的维度(抽象、和实现),因此其使用范围有一定的局限性,即需要有这样的应用场景。