简单来说,用Template Method模式来构建生成实例的工厂,就是Factory Method模式。在这个模式中,父类决定实例的生成方式,但不决定所要生成的具体的类,具体的处理全部交给子类负责。这样就可以将生成实例的框架和实际负责生成实例的类解耦。

  下面的示例中,framework包是生成实例的框架。而idcard包是负责加工处理的。

  首先根据下面的实例代码来解释一下这种常用的设计模式。

 package BigJunOba.bjtu.framework;

 public abstract class Product {
public abstract void use();
}

  Product抽象类属于framework包。这个类用来表示“产品”,定义了use方法,定义了“产品”是“任意的可以use的”东西。

 package BigJunOba.bjtu.framework;

 public abstract class Factory {

     public final Product create(String owner) {
Product p = createProduct(owner);
registerProduct(p);
return p;
} protected abstract Product createProduct(String string);
protected abstract void registerProduct(Product product);
}

  Factory抽象类也属于framework包。在这里使用了Template Method模式,protected关键字说明只能被子类继承。最主要的create方法的意思是,通过create方法来生成Product实例。而create方法的实现是先调用createProduct生成产品,然后调用registerProduct方法注册产品。

 package BigJunOba.bjtu.idcard;

 import BigJunOba.bjtu.framework.Product;

 public class IDCard extends Product {

     private String owner;

     IDCard(String owner) {
System.out.println("制作" + owner + "的ID卡");
this.owner = owner;
} @Override
public void use() {
System.out.println("使用" + owner + "的ID卡");
} public String getOwner() {
return owner;
}
}

  IDCard类属于idcard包。作为Product的子类,用来表示ID卡。

 package BigJunOba.bjtu.idcard;

 import java.util.ArrayList;
import java.util.List; import BigJunOba.bjtu.framework.Factory;
import BigJunOba.bjtu.framework.Product; public class IDCardFactoty extends Factory{ private List<String> owners = new ArrayList<String>(); @Override
protected Product createProduct(String owner) {
return new IDCard(owner);
} @Override
protected void registerProduct(Product product) {
owners.add(((IDCard)product).getOwner());
} public List<String> getOwners() {
return owners;
}
}

  IDCardFactoty类也属于 idcard包。用来实现createProduct和registerProduct两种方法。

 package BigJunOba.bjtu.test;

 import BigJunOba.bjtu.framework.Factory;
import BigJunOba.bjtu.framework.Product;
import BigJunOba.bjtu.idcard.IDCardFactoty; public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFactoty();
Product card1 = factory.create("廉酱");
Product card2 = factory.create("桥爷");
card1.use();
card2.use();
}
}

  测试类属于test包。这里是用工厂来创建ID卡的示例,然后再调用相关的方法。

制作廉酱的ID卡
制作桥爷的ID卡
使用廉酱的ID卡
使用桥爷的ID卡

  测试结果如上图所示。

  Factory Method模式的类图如上图所示。使用工厂方法设计模式的好处是,本实例中,framework包中没有引入idcard包,在Product类和Factory类中,也没有出现IDCard和IDCardFactory等具体类的名字。因此,即使用也有的框架生成全新的类时,也完全不需要对framework包进行修改。通俗来说,就是“framework包不依赖于idcard包”。

设计模式(四)Factory Method模式的更多相关文章

  1. 设计模式之Factory Method模式

    作用:将实例的生成交给子类 用Template Method模式来构建生成实例的工厂,这就是Factory Method模式. 在Factory Method中,父类决定实例的生成方式,但并不决定所要 ...

  2. 设计模式:factory method模式

    核心:将实例的生成交给子类,父类中只定义生成实例的接口 理解:对比模板方法模式的思维非常类似,模板方法模式中的模板方法理解成创造对象的抽象方法,不再是流程框架,就变成工厂方法模式,只是具体的方法是创建 ...

  3. 设计模式初学者笔记:Factory Method模式

    如果要选择一种最多人熟悉的Factory Method模式的具体应用,那么就应该是MFC的App/Doc架构了.Factory Method主要在类框架中使用,以解决以下问题:框架必须实例化类,但框架 ...

  4. Java设计模式:Factory Method(工厂方法)模式

    概念定义 工厂方法(Factory Method)模式,又称多态工厂(Polymorphic Factory)模式或虚拟构造器(Virtual Constructor)模式.工厂方法模式通过定义工厂抽 ...

  5. Factory Method模式

    Factory Method(工厂方法)模式属于GoF设计模式中的创建型分组,它用于在不之制定待创建对象的具体类的情况下创建对象.--<asp.net设计模式> 说白了就是一个人想要出国旅 ...

  6. 设计模式学习--Factory Method

    What Factory Method:定义一个创建对象的接口,让子类来决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类. Why Factory Method是一个比較基 ...

  7. java23种设计模式——四、原型模式

    源码在我的github和gitee中获取 目录 java23种设计模式-- 一.设计模式介绍 java23种设计模式-- 二.单例模式 java23种设计模式--三.工厂模式 java23种设计模式- ...

  8. [学习笔记]设计模式之Factory Method

    写在前面 为方便读者,本文已添加至索引: 设计模式 魔法手札索引 在上篇笔记Abstract Factory设计模式中,时の魔导士创建了一系列的FoodFactory,并教会了其中一名霍比特人theC ...

  9. 一天一个设计模式——模板方法(Template Method)模式

    一.模式说明 现实世界中的模板是用于将事物的结构规律予以固定化.标准化的成果,它体现了结构形式的标准化.例如镂空文字印刷的模板,通过某个模板印刷出来的文字字体大小都是一模一样,但是具体使用什么材质的颜 ...

随机推荐

  1. PostMethod和GetMethod用法

    注:新浪短接口参考地址:https://www.douban.com/note/249723561/      将长的url链接转换成短链接 一.GetMethod try { HttpClient ...

  2. Flask基础(14)-->自定义过滤器

    Flask基础(13)-->自定义过滤器 什么是过滤器? 过滤器的本质就是函数.有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化.运算等等,而在模板中是不能直接调用 P ...

  3. ServiceStack.Redis高效封装和简易破解

    1.ServiceStack.Redis封装 封装的Redis操作类名为RedisHandle,如下代码块(只展示部分代码),它的特点: 1)使用连接池管理连接,见代码中的PooledClientMa ...

  4. 2019年最新超级有趣好玩的html+css网页布局课程,前端入门基础,html5+css3零基础入门课程-黑马程序员pink老师精心录制

    大家好,我是黑马程序员pink老师!! 本次视频是前端零基础入门的课程,pink老师采取有趣好玩讲法,带你快乐的学习枯燥的html+css知识,学完之后让你能快速布局pc端页面.代码也可以讲的好玩有趣 ...

  5. 02·nginx进阶·服务优化配置管理

    企业场景常用的Nginx http功能模块汇总 ngx_ http_ core_ module 包括-些核心的http 参数配置,对应Nginx的配置为HTTP区块部分 ngx_ http _acce ...

  6. web前端之浏览器: 知识汇总

    一.URL到页面 准备阶段: 输入URL,Enter进入查找 浏览器在本地查找host文件,匹配对应的IP: 找到返回浏览器并缓存 没有,则进入路由查找: 找到返回浏览器并缓存 再没有,再进入公网DN ...

  7. Python入门系列【附】进阶教程

    如题,本篇将讲解Python提升之路:Python作为语法简单易学的语言,入门容易精通却很难,这是共识,那么为什么会有这样的共识?精通Python的难度在哪里? Python拥有简单.形象.直观的语法 ...

  8. 【linux】Tomcat 安装

    登录linux后,切换目录到 /usr/local cd /user/local 在/usr/local目录新建文件夹servers用于存放tomcat文件 mkdir servers 在文件夹ser ...

  9. Redis未授权访问漏洞复现

    Redis未授权访问漏洞复现 一.漏洞描述 Redis默认情况下,会绑定在0.0.0.0:6379(在redis3.2之后,redis增加了protected-mode,在这个模式下,非绑定IP或者没 ...

  10. python+selenium遇到元素定位不到的问题,顺便记录一下自己这次的错误(报错selenium.common.exceptions.NoSuchElementException)

    今天在写selenium一个发送邮件脚本时,遇到一些没有找到页面元素的错误.经过自己反复调试,找原因百度,终于解决了.简单总结一下吧,原因有以下几点: 一:Frame控件嵌套,.Frame/Ifram ...