创建型的五大模式
工厂模式
工厂模式:通过不同的参数,返回不同的对象;
工厂:也就是我们要做的,而产品就是返回的对象,他们具有一定程度的相似;
具体例子:不同类型的弹出框,或者elementUI中的message,又或者express的不同方法;
优点
- 你可以避免创建者和具体产品之间的紧密耦合。
- 单一职责原则 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。
- 开闭原则 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型。
缺点
- 应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。
抽象工厂
抽象工厂:与工厂的区别,在于返回的产品不一定在自己的工厂上,有可能在其他工厂上;
也就是通过传入的参数不同实例化不同的对象,他们可能有很大区别,但是在某个整体来看是统一化的,比如一个GUI系统上的各个组件,具体点,就比如按钮和复选框,他们呢有很多的差异,但是因为他们的一个大工厂也就是这个GUI作用是一致的,也就是高度方向的一个抽离;
优点:
- 你可以确保同一工厂生成的产品相互匹配。
- 你可以避免客户端和具体产品代码的耦合。
- 单一职责原则 你可以将产品生成代码抽取到同一位置, 使得代码易于维护。
- 开闭原则 向应用程序中引入新产品变体时, 你无需修改客户端代码。
缺点:
- 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。
小结对比
总的来说,工厂抽象的是产品,抽象工厂抽象的是工厂,把工厂高度抽离;让模块之间更加区分;
工厂模式的零件是工厂的,但是抽象工厂的零件不一定是自己工厂的,可能是来自其他工厂;
工厂方法 是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。
抽象工厂 是一种创建型设计模式, 它能创建一系列相关或相互依赖的对象, 而无需指定其具体类。
生成器模式
生成器模式比较一个典型的样子就是链式调用;是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象,
生成器: 我们要做的一个流水线,然后我们定义好步骤(可能不是按照必须的一个步骤,但是会定义好有哪些步骤),然后我们就有了一条流水线,将步骤串联起来;
例子: 表单信息的设置;
优点:
- 你可以分步创建对象, 暂缓创建步骤或递归运行创建步骤。
- 生成不同形式的产品时, 你可以复用相同的制造代码。
- 单一职责原则。 你可以将复杂构造代码从产品的业务逻辑中分离出来。
缺点:
- 由于该模式需要新增多个类, 因此代码整体复杂程度会有所增加。
原型模式
原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。
原型:也就是我们计划实现的一个模板,这个模板能被复制出来,这个的作用就是我们不需要具体的去写产品;而是去克隆产品,
经典的就是 js中的原型了, 举个例子: Object 是一个对象,Object.prototype,Object其实就是Object.prototype的一个clone 对象 ,在js中我们去new 一个对象,其实是去clone 的一个原型,顺便具体来说一下new 操作符的实现:
function privateNew(targetObj ,...args){
let obj = {};
obj.__proto__ = obj.prototype;
const res = obj.apply(target,args)
return typeof res === 'object'?res:target;
}
优点:
- 你可以克隆对象, 而无需与它们所属的具体类相耦合。
- 你可以克隆预生成原型, 避免反复运行初始化代码。
- 你可以更方便地生成复杂对象。
- 你可以用继承以外的方式来处理复杂对象的不同配置。
缺点:
- 克隆包含循环引用的复杂对象可能会非常麻烦。
单例模式
单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
之前我们从
工厂到了-->抽象工厂-->流水线(生成器)-->克隆生产对象(原型)
到了现在是去关注产品本身的一些性质了,单例模式就是指的是单个产品的一个效果,保证只有一个单例存在,
例子: 个人把防抖作为一个单例的经典例子,定时器是在我那60分钟之类只能去创建一个的对象,
class dboll{
const timer = null;
const main = ()=>{
if(this.timer){ return null};
this.timer = setTimeInterval(
handler,
10000
)
}
}
优点:
- 你可以保证一个类只有一个实例。
- 你获得了一个指向该实例的全局访问节点。
- 仅在首次请求单例对象时对其进行初始化。
缺点:
- 违反了单一职责原则。 该模式同时解决了两个问题。
- 单例模式可能掩盖不良设计, 比如程序各组件之间相互了解过多等。
- 该模式在多线程环境下需要进行特殊处理, 避免多个线程多次创建单例对象。
- 单例的客户端代码单元测试可能会比较困难, 因为许多测试框架以基于继承的方式创建模拟对象。 由于单例类的构造函数是私有的, 而且绝大部分语言无法重写静态方法, 所以你需要想出仔细考虑模拟单例的方法。 要么干脆不编写测试代码, 或者不使用单例模式。
以上是我对创建型的一个总结,总的而言是一套很有作用的攻关秘籍
真的超爱结构型设计模式 (refactoringguru.cn)这个网站,以上图片也来自这个优秀的网站——专门讲解设计模式和重构的知识