设计模式
面向对象
工厂方法
Factory method Pattern 实现了“工厂”概念的面向对象设计模式。定义一个创建对象的接口,但让实现这个接口的类决定实例化哪个类。
通俗的说法:女朋友想要可乐,你需要体贴的问她要百事还是可口可乐吗?不需要把,你只需要和服务员说来瓶可乐即可。服务员会自动拿百事可乐或者可口可乐
package com.tyrantqiao.algorithms.pattern;
import com.tyrantqiao.algorithms.pattern.shape.Circle;
import com.tyrantqiao.algorithms.pattern.shape.IShape;
import com.tyrantqiao.algorithms.pattern.shape.Triangle;
import java.lang.reflect.InvocationTargetException;
/**
* date: 2018/4/30
* Description: 工厂模式
* blog https://tyrantqiao.github.io/Blog
* <p>
* 解决的什么问题:
* 比如说现在要cricle.paint()
* 在God类中{@code Shape circle=new Circle();}
* {@code circle.paint();}
* 假如说要加多个triangle.paint();
* 就要多定义一个 {@code Shape triangle=new Triangle();
* triangle.paint();}
* 导致God类依赖严重,臃肿
* <p>
* 解决方法就是通过工厂方式,God Class不关心具体实现Shape的细节,只管把自己想要的东西告诉{@link FactoryPattern}的getShape()方法
*
* @author tyrantqiao
* @version 0.0.1
* @see <a href="https://github.com/tyrantqiao">qiao's github</a>
*/
public class FactoryPattern {
enum ShapeEnum {
/**
* 圆形
*/
CIRCLE("circle"), Triangle("triangle");
private final String shapes;
ShapeEnum(String shapes) {
this.shapes = shapes;
}
public String getShape() {
return shapes;
}
}
/**
* @param shapeType 形状类型
* @return 获取类型
* @apiNote 存在问题,每次加类型都要修改这个方法,后期容易臃肿,改进为反射进行获取类
*/
public IShape getShape(String shapeType) {
if (ShapeEnum.CIRCLE.getShape().equals(shapeType)) {
return new Circle();
} else if (ShapeEnum.Triangle.getShape().equals(shapeType)) {
return new Triangle();
}
return null;
}
/**
* 进化版,根据类去实例化
*
* @param clazz 类
* @return 实例化后的类
*/
public IShape getShapeVersionTwo(Class<? extends IShape> clazz) {
try {
if (null != clazz) {
// 假如是内部类的话,此段代码无法运行,请注意
return clazz.getDeclaredConstructor().newInstance();
}
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
抽象工厂
抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来
俗话: 还是女票主子,出去玩总得化个美美的妆把,化妆就又需要口红,眉笔,腮红,粉底,眼线·····除了这些化妆品外,还讲究化妆的风格流派,是哥特萝莉派,还是生人勿近的女神派,这些需要的色号以及化妆品牌子型号又不同。
那怎么快速管理这些风格呢?土豪流派(抽象工厂):把每一个流派所需的化妆品放到一个化妆盒子里,这样子只要打开对应盒子,即可以拿到对应流派的化妆品
建造者模式
对象构建模式。将复杂对象的构建过程抽象出来,使抽象过程的不同实现方法可以构建出不同的对象。
俗话:都知道女朋友是一种神奇的主子生物,心情和天气一样阴晴不定,那么我们如何抉择怎么讲话呢?比如说我们有一个骚话模板计算器,有讲笑话,讲故事,出去吃饭等功能,不同的组合形式,不同的执行顺序都会影响到女朋友的心情。
重点来了:把这些骚话抽象成一个个按钮,按 1 是讲笑话,按 2 是讲故事,按 3 是出去吃饭,有了这些按钮,我们可以随意排列这些顺序 123、312,或者选择性挑选 31、23,都能生成一个很好和女朋友玩耍的操作模板。
Department department=new Department.Builder("数据库部门","3306")
.setMembers(···)
.setInstruments(···)
.build();
public class Department{
private String[] members;
private String[] instruments;
/**
* name 和 id必输
*/
private String name;
private String id;
private Department(Builder builder){
this.name=builder.name;
this.id=builder.id;
}
public static class Builder{
private String[] members;
private String[] instruments;
/**
* name 和 id必输
*/
private String name;
private String id;
private Builder(String name,String id){
this.name=builder.name;
this.id=builder.id;
}
public Builder setMembers(String[] members){
this.members=members;
return this;
}
public Builder setInstruments(String[] instruments){
this.instruments=instruments;
return this;
}
public Department build(){
return new Department(this);
}
}
}
原型模式
创建型模式的一种,通过复制一個已經存在的實例來返回新的實例, 而不是新建實例。被复制的实力成为原型
俗话怎么说呢,把对象引用当作一个自动回复消息模板,比如说你想自动回复“我在忙,别打扰我”,但是你不想每次都手打,那你可以选择《忙碌模板》进行快速回复,原型模型的目的就是为了快速的复制,毕竟不涉及内容的真正变更,只是浅复制 shallow copy 关于浅复制和深复制的请参考这篇文章
单例模式
在應用這個模式時,單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利於我們協調系統整體的行為—wiki
俗话:只有一个你
适配器模式(变压器模式)
(Adapter)配接器模式有時候也稱包裝樣式或者包裝。將一個類別的介面轉接成用戶所期待的.
俗话: 你在和外国友人吹水,但是语言不通(相当于接口不通),这时来了个自动翻译软件(适配器),大家就能交谈了。
对象适配器
适配器实现了其中一个对象的接口,并将另一个对象进行封装
类适配器
通过继承机制,同时继承两个对象的接口。但只能支持多重继承,比如 C++
桥梁模式
它把事物對象和其具體行爲、具體特徵分離開來,使它們可以各自獨立的變化。事物對象僅是一個抽象的概念–wiki
俗话:比如说化妆,你需要打理头发,同时也需要整理妆容,这两个都要根据不同的场景进行适配,通过桥梁模式,把抽象和实现分离,这样子就可以让打理头发,整理妆容适配场景
合成模式
合成模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的對象當作一個單一的對象
俗话:
“请我吃一道麦当劳把”
“可以啊,只能一道”
“哎哎哎,怎么还点汉堡鸡块可乐薯条了,这都四样了”
“四个刚好组一起作为套餐啊”
代理模式
通过代理人 proxy 为其他对象提供代理,以控制对对象的访问。起到保护目标对象+增强目标对象的作用。
参考资料
- 设计模式通俗
- <<设计模式之禅>>