本文有更新,请移步个人我的博客:https://blog.andyqiao.top/article/12/设计模式
不少时候,我发现这三种设计模式难以区分,经常会张冠李戴闹了笑话。颇有必要深刻总结一下三种设计模式的特色、相同之处和不一样之处。函数
三个设计模式名字中都含有“工厂”二字,其含义是使用工厂(一个或一系列方法)去生产产品(一个或一系列类的实例)。设计
另外,有时候,咱们经常会将生产产品的一个或一系列方法封装到一个类中,我习惯把这个类叫作“工厂类”;而被实例化的类称做“产品类”。指针
工厂类(SimpleFactory)拥有一个工厂方法(create),接受了一个参数,经过不一样的参数实例化不一样的产品类。blog
以下边UML类图所示为简单工厂。 接口
优势:get
(1)很明显,简单工厂的特色就是“简单粗暴”,经过一个含参的工厂方法,咱们能够实例化任何产品类,上至飞机火箭,下至土豆面条,无所不能。因此简单工厂有一个别名:上帝类。博客
缺点:产品
(1)任何”东西“的子类均可以被生产,负担过重。当所要生产产品种类很是多时,工厂方法的代码量可能会很庞大。引用
(2)在遵循开闭原则(对拓展开放,对修改关闭)的条件下,简单工厂对于增长新的产品,无能为力。由于增长新产品只能经过修改工厂方法来实现。
工厂方法正好能够解决简单工厂的这两个缺点。
工厂方法是针对每一种产品提供一个工厂类。经过不一样的工厂实例来建立不一样的产品实例。
以下边UML类图所示为工厂方法。
优势:
(1)工厂方法模式就很好的减轻了工厂类的负担,把某一类/某一种东西交由一个工厂生产;(对应简单工厂的缺点1)
(2)同时增长某一类”东西“并不须要修改工厂类,只须要添加生产这类”东西“的工厂便可,使得工厂类符合开放-封闭原则。
缺点:
(1)相比简单工厂,实现略复杂。
(2)对于某些能够造成产品族的状况处理比较复杂。
对于缺点(2),咱们能够借用抽象工厂来实现。
抽象工厂是应对产品族概念的。
例如,汽车能够分为轿车、SUV、MPV等,也分为奔驰、宝马等。咱们能够将奔驰的全部车看做是一个产品族,而将宝马的全部车看做是另外一个产品族。分别对应两个工厂,一个是奔驰的工厂,另外一个是宝马的工厂。与工厂方法不一样,奔驰的工厂不仅是生产具体的某一个产品,而是一族产品(奔驰轿车、奔驰SUV、奔驰MPV)。“抽象工厂”的“抽象”指的是就是这个意思。
上边的工厂方法模式是一种极端状况的抽象工厂模式(即只生产一种产品的抽象工厂模式),而抽象工厂模式能够当作是工厂方法模式的一种推广。
以下边UML类图所示为抽象工厂。
优势:针对产品族;
缺点:针对产品族。
因此,只有对应产品族的状况下,才须要使用抽象工厂模式。
简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增长产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增长产品)
抽象工厂 :用来生产不一样产品族的所有产品。(不支持拓展增长产品;支持增长产品族)
(1)工厂类经常采用单例模式(Singleton)。
(2)工厂类拥有基类(定义共同接口),基类能够为纯虚类,也能够定义缺省方法。
(3)对于工厂方法和抽象工厂,基类中的生产产品的函数经常为虚函数,以实现动态绑定。
(4)调用工厂方法的函数一般采用工厂实现的指针和引用做为形参,以便根据不一样的工厂实参调用不一样的工厂方法。