11 Design Patterns for Reuse and Maintainability
设计模式
1.工厂方法模式
为什么需要工厂模式?
想象一下,如果所有的对象我们都通过new操作来创建,当我们的程序中大量使用此对象时,突然有一天对象的类名发生了修改,那么我们岂不是需要挨个修改类名。所以我们可以将那些频繁出现的对象创建,封装到一个工厂类中,当我们需要创建对象的时候,直接调用工厂类中的工厂方法来为我们生成对象,这样,就算出现了变动,我们也只需要修改工厂中的代码即可。
同时,可能有些对象的创建并不是只需要一个new就可以,有时候可能还需要更多的步骤来创建
简单工厂模式
1.首先创建一个工厂类
2.定义一个静态方法来创建对象
例如:我们就可以根据水果的名称来创建相应的水果
但是有一个问题,当我们有新的水果的时候,我们就需要在这个方法当中新加代码,不符合开闭原则OCP(对修改封闭,对拓展开放),所以简单工厂就不满足了,我们就需要工厂模式。
将工厂抽象化,然后抽象类会有很多的实现子类(具体工厂),然后通过他们来创建对象
1.将主工厂抽象化
2.实现具体工厂
这样的话,当我们需要新增水果的时候,我们可以新建具体的类来继承
抽象工厂模式
抽象工厂模式使得具体的工厂类可以创建多个不同的对象
例如,如果我们还是按照上面的工厂模式,那么我们需要创建9个具体的工厂类,这时我们可以通过抽象工厂
创建一个工厂类,里面可以生产多个物品(手机,平板,路由器),然后我就就只需创建三个具体的工厂(小米工厂,华为,苹果工厂)但是这样的话,当我们需要添加新的物品的时候,就难免需要在具体的工厂中添加,违反了OCP开闭原则。
2.适配器
将某个类的接口转换为客户端期望的另一个接口表示,主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。也称为包装器Wrapper。适配器主要分为三种:类适配器、对象适配器、接口适配器。
Target :目标角色,我们期望的接口
Adaptee:需要转换的对象,也就是我们想把谁转换为目标角色,一般是已经存在的类或者对象
Adapter:适配器,需要我们自己新建立的。
类适配器:
举例:加入我们要给手机充电,但是插座为英式插座,而我们的充电器为中国款式,所以我们需要一个适配器。
Target--中国插头
Adaptee--英式插头
Adapter--适配器
我们可以通过继承和实现接口方式实现
装饰器模式
是指在不改变现有对象结构的情况下,动态的给该对象增加一些功能的模式,他属于对象结构型模式。
例子:假如我们要开一个快餐店,里面有炒面,炒饭。然后里面可以加鸡蛋,培根等配料,相应的价钱也会发生改变。如果我们按照一开始的想法,我们想的是:
但是如果菜单上新了,有了一个炒河粉,那么我们就需要新建很多类,比如EggFriedHefen,BaconFriedHefen。。。当我们菜单很多的时候,就会造成类爆炸。所以这种方法是不可取的。我们就可以使用装饰者模式。
装饰模式中的角色:
1.抽象构件:定义一个抽象接口(类)以规范准备接受附加责任的对象
2.具体构件:实现抽象构件,通过装饰为其添加一些指责(功能)
3.抽象装饰:继承或实现抽象构件,并包含具体构件的实例,可以通过子类扩展具体构件的功能。
4.具体装饰:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
带入我们的例子就是:
抽象构件:快餐类(规范炒饭,炒面····行为)、具体构件:实现快餐类的具体构件,比如炒饭,面
抽象装饰:配料类、具体装饰:鸡蛋,培根,火腿·······
代码如下:
main函数如下
运行效果如图:
其余的什么培根,火腿。或者是炒面炒河粉也是同理。
策略模式 Strategy
属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
结构:
1.抽象策略:这是一个抽象角色,通常由一个接口或者抽象类实现,此角色给出所有的具体策略所需要的接口
2.具体策略:实现了抽象策略定义的接口,提供具体的算法或者实现行为
3.环境类:持有一个策略类的引用,最终给客户端调用
举例:假如我们开了一家百货公司,针对不同的节日(春节,中秋节,圣诞节)推出不同的促销活动,由推销员将促销活动展示给顾客,利用策略模式我们可以
代码如下:
抽象策略:
然后三个实现抽象策略的具体策略
环境类:含有策略类的引用
当我们需要售货员推销物品的时候,我们只需要
使用场景:
- 模板模式Template Method
主要包含一下角色:
抽象类:负责给出一个算法的轮廓和骨架,它由一个模板方法和若干个基本方法构成
模板方法:定义了算法的骨架,按照某种顺序调用其包含的基本方法
基本方法:1.抽象方法 :一个抽象方法由抽象类声明,靠其子类实现
2.具体方法:由抽象类或者具体类声明实现,其子类可以覆盖也可以调用
3.钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种
一般是用于判断的逻辑方法,,一般名为isXxx返回值为boolean类型
具体子类:实现抽象类中所定义的抽象方法和钩子方法
举例:炒菜的步骤是固定的,分为倒油、热油、倒蔬菜、倒调料、翻炒等步骤。
那么我们如何使用模板模式?
抽象类:
具体子类:
主函数:
运行结果:
访问者模式Visitor
迭代器模式Iterator
提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
抽象聚合:定义存储,添加,删除聚合元素以及创建迭代器对象的接口
具体聚合:实现抽象聚合类,返回一个具体迭代器的实例
抽象迭代器:定义访问和遍历聚合元素的接口,通常包含hasNext和next等方法
具体迭代器:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
举个例子:加入我们要对Student进行聚合
抽象聚合:规定我们具体聚合的形式(我的理解就是这个抽象聚合就相当于一个List之类的集合Plus,然后里面有添加学生、删除学生、获取迭代器等方法)
具体聚合
抽象迭代器:为我们的迭代器规定一下形式
具体迭代器: