工厂方法模式:

定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

解决的使项目中的实例化问题,一般我们是在某个地方用到某个类就new一个。工厂模式解决的是大量的实例化某些、某种、某批类的对象。

类图:

通用代码:
抽象产品类:

package com.test.Test;public abstract class Product {// 产品类的公共方法public void method1() {// 业务逻辑处理}// 抽象方法public abstract void method2();}

具体产品类:
具体产品类可以有多个,都继承于抽象产品类。

package com.test.Test;public class ConcreteProduct1 extends Product {public void method2() {// 业务逻辑处理}}
package com.test.Test;public class ConcreteProduct2 extends Product {public void method2() {// 业务逻辑处理}}

抽象工厂类:
抽象工厂类负责定义产品对象的产生。

package com.test.Test;public abstract class Creator {/** 创建一个产品对象,其输入参数类型可以自行设置* * 通常为String、Enum、Class等,当然也可以为空*/public abstract Product createProduct(Class<? extends Product> c);}

具体工厂类:
具体如何产生一个产品的对象,是由具体的工厂类实现的。

package com.test.Test;public class ConcreteCreator extends Creator {public Product createProduct(Class<? extends Product> c) {Product product = null;try {product = (Product) Class.forName(c.getName()).newInstance();} catch (Exception e) {// 异常处理}return product;}
}

场景类:

package com.test.Test;public class Client {public static void main(String[] args) {Creator creator = new ConcreteCreator();Product product = creator.createProduct(ConcreteProduct1.class);/** 继续业务处理*/}}

例子:

抽象产品类:

package com.test.teaAndmilk;/*** 奶茶(抽象产品类)* 2015年9月18日 下午5:19:01* @author 张耀晖**/
public abstract class TeaAndMilk {//奶茶类的抽象方法,由具体的子类来实现public abstract void prepare();//奶茶类的公共方法public void doWater(){System.out.println("加入水。。。");}public void doMix(){System.out.println("搅拌均匀。。。");}public void doCapping(){System.out.println("封装加盖。。。完成");}}

具体产品类:

package com.test.teaAndmilk;/*** 绿茶(具体产品类)* 2015年9月18日 下午5:34:17* @author 张耀晖**/
public class GreenTea extends TeaAndMilk {@Overridepublic void prepare() {System.out.println("加入绿茶所用的茶叶。。。");}}
package com.test.teaAndmilk;/*** 珍珠奶茶(具体产品类)* 2015年9月18日 下午5:34:42* @author 张耀晖**/
public class GemMilk extends TeaAndMilk {@Overridepublic void prepare() {System.out.println("加入珍珠奶茶需要的材料。。。");}}

抽象工厂类:

package com.test.Factory;import com.test.teaAndmilk.TeaAndMilk;/*** 抽象奶茶创建工厂(抽象工厂类)* 2015年9月18日 下午5:34:08* @author 张耀晖**/
public abstract class FactoryCreator {public abstract <T extends TeaAndMilk> T createTeaAndMilk(Class<T> c);}

具体工厂类:

package com.test.Factory;import com.test.teaAndmilk.TeaAndMilk;/*** 奶茶创建工厂(具体工厂类)* 2015年9月18日 下午5:38:14* @author 张耀晖**/
public class TeaAndMilkFactory extends FactoryCreator{@Overridepublic <T extends TeaAndMilk> T createTeaAndMilk(Class<T> c) {TeaAndMilk teaAndmilk = null;try {teaAndmilk = (TeaAndMilk) Class.forName(c.getName()).newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return (T)teaAndmilk;}}

场景类:

package com.test.client;import com.test.Factory.FactoryCreator;
import com.test.Factory.TeaAndMilkFactory;
import com.test.teaAndmilk.GreenTea;
import com.test.teaAndmilk.TeaAndMilk;
/*** 奶茶店(场景类)* 2015年9月18日 下午5:46:05* @author 张耀晖**/
public class Client {public static void main(String[] args) {FactoryCreator creator = new TeaAndMilkFactory();//如果顾客需要绿茶TeaAndMilk teaAndmilk = creator.createTeaAndMilk(GreenTea.class);//具体的业务处理teaAndmilk.prepare();teaAndmilk.doWater();teaAndmilk.doMix();teaAndmilk.doCapping();}}

运行结果:

工厂方法模式的优点:
大家应该能够深刻体会到工厂方法模式的好处:如果使用JDBC连接数据库,数据库从MySql切换到Oracle,需要改动地方就是切换一下驱动名称(前提条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接案例。

工厂方法模式的使用场景:
工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重的考虑是否要增加一个工厂类来进行管理,增加代码的复杂度。

工厂方法模式的扩展:
缩小为简单工厂模式:
简单工厂模式:定义一个创建对象的类,由这个类来实例化对象的行为。
上例更改为简单工厂模式:
简单工厂模式中的工厂类:

package com.test.easyFactory;import com.test.teaAndmilk.TeaAndMilk;/*** 奶茶创建工厂(简单工厂模式中的工厂)* 2015年9月18日 下午7:12:51* @author 张耀晖**/
public class EasyFactory {public static <T extends TeaAndMilk> T createTeaAndMilk(Class<T> c){//定义一个生产出的奶茶种类TeaAndMilk teaAndMilk = null;try {teaAndMilk = (TeaAndMilk)Class.forName(c.getName()).newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return (T)teaAndMilk;}}

简单工厂模式中的场景类:

package com.test.easyFactory;import com.test.teaAndmilk.GemMilk;
import com.test.teaAndmilk.TeaAndMilk;/*** 奶茶店(场景类)* 2015年9月18日 下午7:21:00* @author 张耀晖**/
public class Client {public static void main(String[] args) {TeaAndMilk teaAndMilk = EasyFactory.createTeaAndMilk(GemMilk.class);teaAndMilk.prepare();teaAndMilk.doWater();teaAndMilk.doMix();teaAndMilk.doCapping();}}

运行结果:

分析与工厂方法模式的不同之处:

  1. 将工厂方法模式中的抽象工厂类(FactoryCreator类)去掉了
  2. 将具体工厂类(TeaAndMilkFactory类)中的createTeaAndMilk()方法设置为静态方法。简化了类的创建过程。并且去掉了继承抽象类。
  3. 因为工厂类发生类变化,所以会导致调用者场景类(Client类)发生类变化。

抽象工厂模式

定义:
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。

通用类图:

通用源码类图:

AbstractProductA和AbstractProductB两个抽象产品类可以有关系,例如共同继承一个抽象类或接口。
通用源码:
抽象产品类:

package com.test.Test;public abstract class AbstractProductA {// 每个产品共有的方法public void shareMethod() {}// 每个产品相同方法,不同实现public abstract void doSomething();}

两个具体的产品实现类
产品A1的实现类:

package com.test.Test;public class ProductA1 extends AbstractProductA {@Overridepublic void doSomething() {System.out.println("产品A1的实现方法");}}

产品A2的实现类:

package com.test.Test;public class ProductA2 extends AbstractProductA {@Overridepublic void doSomething() {System.out.println("产品A2的实现方法");}}

产品B与此类似,代码省略了。

抽象工厂类:
抽象工厂类AbstractCreator的职责是定义每个工厂要实现的功能
该抽象工厂类定义了两个产品族的产品创建。
注意: 有N个产品族,在抽象工厂类中就应该有N个创建方法。

package com.test.Test;public abstract class AbstractCreator {// 创建A产品家族public abstract AbstractProductA createProductA();// 创建B产品家族public abstract AbstractProductB createProductB();}

产品等级1的实现类:
如何创建一个产品,则是有具体的实现类来完成的。
注意: 有M个产品等级就应该有M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务。

package com.test.Test;public class Creator1 extends AbstractCreator {// 只生产产品等级为1的A产品public AbstractProductA createProductA() {return new ProductA1();}// 只生产产品等级为1的B产品public AbstractProductB createProductB() {return new ProductB1();}}

产品等级2的实现类:

package com.test.Test;public class Creator2 extends AbstractCreator {// 只生产产品等级为2的A产品public AbstractProductA createProductA() {return new ProductA2();}// 只生产产品等级为2的B产品public AbstractProductB createProductB() {return new ProductB2();}}

场景类:

package com.test.Test;public class Client {public static void main(String[] args) {// 定义出两个工厂AbstractCreator creator1 = new Creator1();AbstractCreator creator2 = new Creator2();// 产生A1对象AbstractProductA a1 = creator1.createProductA();// 产生A2对象AbstractProductA a2 = creator2.createProductA();// 产生B1对象AbstractProductB b1 = creator1.createProductB();// 产生B2对象AbstractProductB b2 = creator2.createProductB();/** * * * 然后在这里就可以为所欲为了...*/}}

具体的应用实例:

人种接口:

package com.test.human;/*** 人种接口* 2015年9月18日 下午8:50:17* @author 张耀晖**/
public interface Human {// 每个人种都有相应的颜色public void getColor();// 人类都会说话public void talk();// 每个人都有性别public void getSex();
}

人种有三个抽象类,负责人种的抽象属性定义:肤色和语言,白色人种、黑色人种、黄色人种
白色人种:

package com.test.human;/*** 白色人种* 2015年9月18日 下午8:53:22* @author 张耀晖**/
public abstract class AbstractWhiteHuman implements Human {@Override//白色人种的皮肤颜色为白色public void getColor() {System.out.println("白色人种的皮肤颜色为白色!");}@Override//白色人种讲话public void talk() {System.out.println("白色人种会说话,一般说的都是单字节!");}}

黄色人种:

package com.test.human;/*** 黄色人种* 2015年9月18日 下午8:55:34* @author 张耀晖**/
public abstract class AbstractYellowHuman implements Human {@Override//黄色人种的皮肤颜色为黄色public void getColor() {System.out.println("黄色人种的皮肤颜色为黄色!");}@Override//黄色人种讲话public void talk() {System.out.println("黄色人种会讲话,一般说的都是双字节!");}}

黑色人种:

package com.test.human;/*** 黑色人种* 2015年9月18日 下午8:53:15* @author 张耀晖**/
public abstract class AbstractBlackHuman implements Human {@Override//黑色人种的皮肤颜色为黑色public void getColor() {System.out.println("黑色人种的皮肤颜色为黑色!");}@Override//黑色人种讲话public void talk() {System.out.println("黑色人种会讲话,一般人听不懂!");}}

每个抽象类都有两个实现类,分别实现公共的最细节、最具体的事物:肤色和语言。具体的实现类肤色性别定义,以黄色女性人种为例。
其他的黑色人种、白色人种的男性和女性的代码与此类似,不再重复编写。
黄色女性人种:

package com.test.human;/*** 黄色女性人种* 2015年9月18日 下午8:57:53* @author 张耀晖**/
public class WomenYellowHuman extends AbstractYellowHuman {@Override//黄人女性public void getSex() {System.out.println("黄人女性");}}

黄色男性人种:

package com.test.human;/*** 黄色男性人种* 2015年9月18日 下午8:59:06* @author 张耀晖**/
public class MenYellowHuman extends AbstractYellowHuman {@Override//黄人男性public void getSex() {System.out.println("黄人男性");}}

八卦炉定义:

package com.test.factory;import com.test.human.Human;/*** 八卦炉定义* 2015年9月18日 下午9:03:35* @author 张耀晖**/
public interface HumanFactory {//制造一个黄色人种public Human createYellowHuman();//制造一个黑色人种public Human createBlackHuman();//制造一个白色人种public Human createWhiteHuman();
}

具体的八卦炉:
生产女性的八卦炉:

package com.test.factory;import com.test.human.Human;
import com.test.human.WomenBlackHuman;
import com.test.human.WomenWhiteHuman;
import com.test.human.WomenYellowHuman;/*** 生产女性的八卦炉* 2015年9月18日 下午9:05:53* @author 张耀晖**/
public class WomenFactory implements HumanFactory {@Override//生产出黄人女性public Human createYellowHuman() {return new WomenYellowHuman();}@Override//生产出黑人女性public Human createBlackHuman() {return new WomenBlackHuman();}@Override//生产出白人女性public Human createWhiteHuman() {return new WomenWhiteHuman();}}

生产男性的八卦炉:

package com.test.factory;import com.test.human.Human;
import com.test.human.MenBlackHuman;
import com.test.human.MenWhiteHuman;
import com.test.human.MenYellowHuman;/*** 生产男性的八卦炉* 2015年9月18日 下午9:11:20* @author 张耀晖**/
public class MenFactory implements HumanFactory {@Override//生产出黄人男性public Human createYellowHuman() {return new MenYellowHuman();}@Override//生产出黑人男性public Human createBlackHuman() {return new MenBlackHuman();}@Override//生产出白人男性public Human createWhiteHuman() {return new MenWhiteHuman();}}

女娲类(场景类):

package com.test.Client;import com.test.factory.HumanFactory;
import com.test.factory.MenFactory;
import com.test.factory.WomenFactory;
import com.test.human.Human;/*** 女娲造人* 2015年9月18日 下午9:18:56* @author 张耀晖**/
public class NvWa {public static void main(String[] args) {//第一条生产线,男性生产线HumanFactory menFactory = new MenFactory();//第二条生产线,女性生产线HumanFactory womenFactory = new WomenFactory();//生产线建立完毕,开始生产人Human menYellowHuman = menFactory.createYellowHuman();Human womenYellowHuman = womenFactory.createYellowHuman();menYellowHuman.getColor();menYellowHuman.talk();menYellowHuman.getSex();womenYellowHuman.getColor();womenYellowHuman.talk();womenYellowHuman.getSex();//下面继续创建黑人和白人的男性和女性。。。。。。}}

运行结果:

抽象工厂模式的使用场景

抽象工厂模式的使用场景定义非常简单:一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式,什么意思呢?例如一个文本编辑器和一个图片处理器,都是软件实体,但是*nix下的文本编辑器和WINDOWS下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也是类似情况,也就是具有了共同的约束条件:操作系统类型,于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。

工厂模式---设计模式(二)相关推荐

  1. Java 设计模式之工厂模式(二)

    原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...

  2. 抽象工厂模式设计模式_创新设计模式:抽象工厂模式

    抽象工厂模式设计模式 抽象工厂模式是一种创新模式,是与构建器和工厂模式一起最受欢迎的模式之一. 使用创建模式是为了创建对象,而不是直接使用构造函数创建对象. 抽象工厂模式提供了一种封装一组具有共同主题 ...

  3. 抽象工厂模式设计模式_21世纪的设计模式:抽象工厂模式

    抽象工厂模式设计模式 这是我的演讲的第二部分," 21世纪的设计模式" . 此模式在Java代码中到处都有使用,尤其是在更多"企业"代码库中. 它涉及一个接口和 ...

  4. 抽象工厂模式设计模式_抽象工厂设计模式解释

    抽象工厂模式设计模式 抽象工厂设计模式是工厂设计模式的另一种形式. 这种模式可以被视为"超级工厂"或"工厂工厂". 抽象工厂设计模式(属于"四人帮&q ...

  5. 设计模式详解——工厂模式(二)

    本篇文章介绍一种设计模式--工厂模式.工厂模式是用来封装对象的创建,减少应用程序和具体类之间的依赖,促进松耦合.根据工厂模式的应用特性,一共分为三种子模式:简单工厂模式,工厂方法模式和抽象工厂模式.本 ...

  6. Java设计模式(二)简单工厂模式—设计模式六大原则

    文章目录 设计模式六大原则 1. 开闭原则 2. 里氏代换原则 3. 依赖倒转原则 4. 接口隔离原则 5. 迪米特法则(最少知道原则) 6. 合成复用原则 工厂设计模式 什么是工厂模式 工厂模式的好 ...

  7. 工厂三兄弟之简单工厂模式(二)

    2 简单工厂模式概述 简单工厂模式并不属于GoF 23个经典设计模式,但通常将它作为学习其他工厂模式的基础,它的设计思想很简单,其基本流程如下: 首先将需要创建的各种不同对象(例如各种不同的Chart ...

  8. Python面向对象程序设计之抽象工厂模式之二-一个更加pythonic的抽象工厂

    上一篇文章我们说到DiagramFactory和其SvgDiagramFactory子类以及它们使用到的类比如(Diagram,SvgDiagram等等),能够很好的实现预订的功能并且也符合抽象工厂的 ...

  9. 软件设计体系-简单工厂模式实例二---权限管理

    在某OA系统中,系统根据对比用户在登录时输入的账号和密码以及在数据库中存储的账号和密码是否一致来进行身份验证,如果验证通过,则取出存储在数据库中的用户权限等级(以整数形式存储),根据不同的权限等级创建 ...

最新文章

  1. Web服务器、Servlet和Servlet容器
  2. Fedora 12 环境搭建
  3. 软件项目管理0711:团队成员怕担责任
  4. pycharm中无法安装scipy、imread、GDAL等库
  5. Python打包 pyinstaller
  6. PX4代码解析(4)
  7. MATLAB学习笔记(十七)
  8. 小e的每日一画 之 飞毯旅行记 20071231
  9. 榛子云短信-微信小程序60秒倒计时插件
  10. Could not find modernizr-2.6.2 in any of the sources
  11. 多功能扩音器索爱S-318,教师、导游们的辅助神器
  12. e5服务器系列天梯图,至强e5系列cpu天梯图_2020年5月至强e5天梯图排行
  13. 前端三刺客----HTML
  14. 手淘双十一性能优化项目揭秘
  15. opencv滤波函数简介
  16. dw的html代码文档,Dw 基础篇:DW的文档工具栏
  17. c语言换行编辑,C语言怎么换行
  18. 用户体验五要素_新零售「盒马」的用户体验设计5要素
  19. java rollback_Java Connection.rollback()方法:事务回滚
  20. 音视频开发学习(三) -- RGB YUV HSV 颜色空间

热门文章

  1. JavaScript第一天学习
  2. nodejs path.parse()
  3. css3 设置多列布局
  4. maven 部分命令
  5. 使用PyQT编写界面程序
  6. 我们并非生活在“虚幻世界”宇宙或是三维空间
  7. freebsd镜像作用和vmware服务开启
  8. debian安装搜狗
  9. git show HEAD^num和个git show HEAD~num的区别
  10. 00-02.PHP 网站假设 之 学习PHP语法 [James建站]