工厂模式:简单工厂模式、工厂方法模式和抽象工厂模式

我们一般制造对象时,采用操作符new来进行创建。但是慢慢我们了解到实例化这个活动不应该总是公开地进行,同时初始化还经常造成“耦合”的问题。

如果我们不希望出现上述问题,那么我们就有必要认识一下“工厂模式”,它将有助于我们从复杂的依赖中解脱出来。

1)为什么说“new”不好?



当看到“new”,就会想到“具体”。

我们不应该总是针对实现编程,但是当我们每次使用new时,正是在针对实现编程而不是接口,这很不符合我们的期望。

当使用“new”时,我们的确是在实例化一个具体类,当代码绑着具体类会导致代码更脆弱,更缺乏弹性。

当看到这样的代码,一旦有变化或扩展,就必须重新打开这段代码进行检查和修改。通常这样修改过的代码将造成部分系统更难维护和更新,而且也更容易犯错。

针对接口编程,可以隔离掉以后系统可能发生的一大堆改变。

 2)我们现在建立一个拥有多种披萨类型的披萨店



 通常,我们为了让系统有弹性,我们将各种类型的披萨都继承于一个抽象类或接口。(但是这样做会导致这些类或者接口无法直接实例化)

这么编程,我们就会承受一些压力,这些压力来自于增加或删除比萨类型

这时候,我们想到回到OO设计原则去寻找线索。我们发现这么一条“找出会变化的方面,把它们从不变的部分分离出来”。

那么,现在我们最好将创建对象移到orderPizza()之外,这就需要把创建披萨的代码移到另一个对象中,由这个对象专职创建披萨。

3)定义简单工厂



4)工厂方法模式



 

现在我们为上述我们建立的披萨店开设加盟店。

我们希望每个加盟店有自己独特的风味,但是为了保证品牌的一致性,虽然风味可以不同,但披萨的制作流程火候必须一致。

甚至我们可以上不想子类覆盖的方法orderPizza()声明成final。

开一家披萨店,举个例子。

实现一个独特风味的披萨,举个例子。

调用,测试一下。

5)依赖倒置原则



 

 

6)抽象工厂模式



7)小结



 OO基础:

  • 抽象
  • 封装
  • 多态
  • 继承 

 

OO原则:

  • 封装变化
  • 多用组合、少用继承
  • 针对接口编程,不针对实现编程
  • 为交互对象之间的松耦合设计而努力
  • 对扩展开放,对修改关闭
  • 依赖抽象,不要依赖具体类

 

OO模式:

  • 策略模式——定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
  • 观察者模式——在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新
  • 装饰者模式——动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的一种选择
  • 抽象工厂模式——提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类
  • 工厂方法模式——定义了一个创建对象的接口,但由于子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类

 

要点:

  •  所有的工厂都是用来封装对象的创建
  • 简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦
  • 工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象
  • 抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中
  • 所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合
  • 工厂方法允许类将实例化延迟到子类进行
  • 抽象工厂创建相关的对象家族,而不需要依赖它们的具体类
  • 依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象
  • 工厂是很有威力的技巧,帮助我们针对抽象编程,而不是针对具体类编程

参考书目:《Head First 设计模式》

 

原文地址:https://www.cnblogs.com/dudududu/p/9126073.html

时间: 2024-10-26 13:08:44

工厂模式:简单工厂模式、工厂方法模式和抽象工厂模式的相关文章

《Head first设计模式》之抽象工厂

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类. 确保原料的一致 披萨店成功的关键在于新鲜.高质量的原料.要如何确保每家加盟店使用高质量的原料?你打算建造一家生成原料的工厂,并将原料运送到各家加盟店.对于这个做法,现在还剩下一个问题:加盟店坐落在不同的区域,纽约的红酱料和芝加哥的红酱料是不一样的.加盟店之间有相同的产品家族(意式腊肠.酱料.芝士.蔬菜等等),但是制作方式根据区域的不同而有差异.所以对于纽约和芝加哥,你准备了两组不同的原料.假如不久之后加州就有加盟店

结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别

之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处.工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类.也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口

简单工厂和工厂方法以及抽象工厂模式

工厂模式:定义一个用于创建对象的借口,让子类决定实例化哪一个类 抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类 个人觉得这个区别在于产品,如果产品单一,最合适用工厂模式,但是如果有多个业务品种.业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方 式.再通俗深化理解下:工厂模式针对的是一个产品等级结构 ,抽象工厂模式针对的是面向多个产品等级结构的. 再来看看工厂方法模式与抽象工厂模式对比: 工厂方法模式 抽象工厂模式 针对的是一个产品等级结构 针对的

简单工厂模式,工厂方法模式,抽象工厂模式,spring的狂想

菜鸟D在项目中遇见一个比较纠结的高耦合,所以就想办法来解耦.情况是这样的:系统通过用户选择treeview控件的节点判断调用不同的处理,这些处理中某些东西又是类似的.同事的建议是采用简单工厂,耦合就耦合吧,反正treeview节点基本是不会变化的.(能偷懒就偷懒吧) 菜鸟D有些偏执,想找些方法来解耦.于是就学习了这个几种方法,虽然不一定用的上,多学一点总是好的. 首先说简单工厂,例子是一个已经二到死的计算器. 简单工厂由三种角色组成:工厂类角色(creator),抽象产品类角色(product,

设计模式(Python)-简单工厂,工厂方法和抽象工厂模式

本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的问题? 是什么?通过Python语言来去实现这个设计模式,用于解决为什么中提到的问题. 怎么用?理解了为什么我们也就基本了解了什么情况下使用这个模式,不过在这里还是会细化使用场景,阐述模式的局限和优缺点. 这次的主角是简单工厂,工厂方法和抽象工厂模式,由于这几个模式联系紧密,有一定的相似性,所以放在

简单工厂模式&工厂方法模式&抽象工厂模式的区别

之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处.工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类.也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口

Java设计模式—工厂方法模式&抽象工厂模式

工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义:Creator为抽象创建 类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的. 工厂方法模式的扩展方式有很多种,下边是工厂方法模式一个比较实用的源代码: 抽象产品类: pub

工厂方法模式And抽象工厂模式

一.工厂方法模式 简单工厂模式的缺陷就是类的创建太过于依赖工厂,一旦需要进行程序扩展,就必须修改工厂类的代码 这违背了背包原则. 而工厂方法模式针对这一问题进行了改进. public interface Sender { public void send(); } public interface producer { public Sender produce(); } public class MailFactory implements producer{ public Sender pr

2 简单工厂模式、工厂模式、抽象工厂模式

简单工厂模式: -----------------------------------Pizza.java-------------------- package com; public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public abstract void cut(); } -----------------------------------APizza.