在开发系统中,经常会碰到一个问题。现在需要实现的一些功能,但是这个功能模块以后一定是需要扩展的,那么现在开发中就不仅要实现现在的功能,还要考虑以后的扩展。那么为了系统的健壮,扩展就要遵循开闭原则(简单说,就是对修改关闭,对扩展开发)。

  通过场景例子切入工厂方法模式

  要实现这个功能,就是要找到一种方法。可以创建一些操作,但是现在不实现,等着以后来实现这个功能。

  现在通过一个人成长过程中学到的技能来展示一下这种方案:

  在社会中生存技能千千万万,人也是在不断学习技能的,但是都能学习到那些技能自己也不能确定。但是学习技能是一定的。这时候我们就先定义一个技能的类,但是不知道学习的是什么技能,所以就先实现一个技能接口。

package designPattern_3_FactoryMethod;
//技能接口
public interface ILifeKills {
public void kill();
}

  学习的过程不要和技能耦合在一起,需要单独对象来实现,学习的过程就是创建技能对象的过程,所以这个学习对象就是用来生成具体的技能对象的。但是如果是一个人生学习技能方面的框架的话,肯定也不知道学习的是什么技能,那这就是自相矛盾了。怎么办呢?既然是框架,肯定有人来具体实现这个需要学习的技能和具体的学习方式。所以这个我们就知识定义学习方法,但是不定义学习的具体内容,让使用框架的人来实现。这就是定义一个抽象类。

package designPattern_3_FactoryMethod;

//抽象学习方法
public abstract class AbstractLearn { public void learn(){
ILifeKills lifekill = factoryMethod();
     lifekill.kill();
} protected abstract ILifeKills factoryMethod();
}

下面列出交流、开车的技能

 package designPattern_3_FactoryMethod;
//交流技能
public class Talking implements ILifeKills {
public void kill(){
System.out.println("交谈技能");
}
}
package designPattern_3_FactoryMethod;

//开车技术
public class Driver implements ILifeKills { @Override
public void kill() {
// TODO Auto-generated method stub
System.out.println("开车技术!");
}
}

具体学习的方法

package designPattern_3_FactoryMethod;

//学习交流的对象
public class LearnTalking extends AbstractLearn { public ILifeKills learn(){ return new Talking();
}
}
package designPattern_3_FactoryMethod;

//学习开车
public class LearnDriver extends AbstractLearn { @Override
protected ILifeKills factoryMethod() {
// TODO Auto-generated method stub
return new Driver();
} }

客户端调用

 package designPattern_3_FactoryMethod;

 public class Client {

     public static void main(String[] args) {
AbstractLearn al = new LearnTalking();
al.learn();
AbstractLearn al2 = new LearnDriver();
al2.learn();
}
}

   这面展示的例子就是工厂方法模式。只是我只生产一个具体的对象。以后根据需要可以生成对应的技能对象。接下来先看下工厂模式的定义,再结合简单工厂模式分析。结构图

  分析工厂方法模式

定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

         工厂方法的意义,在父类不知道需要生产具体对象的情况下,能够完成自身的功能调用,具体的实现延迟到其子类,实际上就是工厂类也抽象化了,具体的对象在各自的工厂子类中来实现。

         通过定义可以看出:抽象出来具体对象的接口,同时把工厂类也抽象化,这样产品对象和具体工厂都实现各自的抽象类,以后在扩展具体的对象的时候不用修改原来的工厂类,这也更加符合开闭原则。同时也看出来了,工厂方法模式是简单工厂模式的衍生。如果把工厂类的抽象类省略到,用普通类选择实现,那么工厂方法模式就回来到简单工厂模式。

   在使用工厂方法的时候要具有灵活性,在一个具体的工厂功法里面可以有多个不同的工厂方法,也可以在一个工厂类中实现十分相近的产品。看着有点类似简单工厂了,但是本质上还是工厂方法的本质。只是形式有些变化而已,但是这不重要。就像学习武功,只要内功深厚,很多招式都能够灵活运用,看似神奇,其实都是内功支撑。而设计模式也是如此。工厂方法模式只要把具体对象的实现延迟到子类,以后扩展工厂时候不用再去修改原来的工厂类,符合了开闭原则。那么就抓住了工厂方法模式的本质。

  分析了这么多工厂模式的优点,它当然也有缺点。就是会加大代码的复杂度,如果在不合适的场景中用到很有可能得不偿失。

  小结

  工厂方法的本质:就是把对象的实现延迟到其子类来实现,使得对产品的扩展更加灵活。这也是工厂方法模式和简单公共的区别。

  工厂方法不是不可以选择实现。以我的理解,在一个具体的工厂类中,可以实现相近的产品。以后扩展的时候再派生另外的类就可以了。

下一篇分析抽象工厂模式

设计模式 — 工厂方法模式(Factory Method)的更多相关文章

  1. 大话设计模式--工厂方法模式 Factory Method -- C++实现

    1. 工厂方法模式 定义一个用于创建对象的接口, 让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 和简单工厂模式相比: A: 简单工厂模式最大的优点在于工厂类中包含有必要的逻辑判断, ...

  2. C#设计模式——工厂方法模式(Factory Method Pattern)

    一.概述在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?如何提供一种封装机制来隔离出“这个易变对象 ...

  3. [设计模式]工厂方法模式(Factory Method)

    模式目的 定义一个用于创建对象的接口,让其子类来决定实例化哪个类. 工厂方法模式将类的实例化延迟到了子类中进行. 模式结构 组成部分 产品(Product) - 定义了产品功能的接口 具体产品(Con ...

  4. 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)

    原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pa ...

  5. 设计模式-03工厂方法模式(Factory Method Pattern)

    插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...

  6. 【设计模式】工厂方法模式 Factory Method Pattern

    在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...

  7. 二十四种设计模式:工厂方法模式(Factory Method Pattern)

    工厂方法模式(Factory Method Pattern) 介绍定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例有SqlMes ...

  8. 工厂方法模式-Factory Method(Java实现)

    工厂方法模式-Factory Method 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法让实例化的具体内容交给子类工厂来进行. 本文中的例子是这样的. 生产一个身份证, ...

  9. IOS设计模式浅析之工厂方法模式(Factory Method)

    概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...

  10. 设计模式之工厂方法模式(Factory Method Pattern)

    一.工厂方法模式的诞生 在读这篇文章之前,我先推荐大家读<设计模式之简单工厂模式(Simple Factory Pattern)>这篇文档.工厂方法模式是针对简单工厂模式中违反开闭原则的不 ...

随机推荐

  1. openstack虚拟机内核崩溃问题解决

    openstack对接的kvm虚拟化环境,创建虚拟机后无法进如系统,一直卡在call Trace . 解决办法: 更改配置文件的cpu-model,libvirt_cpu_mode = custom ...

  2. [leetcode] 5.Longest Palindromic Substring-2

    想了很多方法 搞轴对称,算对称轴,偶数都高出了一堆0.5在那加加减减,最后发现在移轴之前可能就返回了. class Solution: def longestPalindrome(self, s: s ...

  3. jmeter笔记(8)--关联

    关联是jmeter中比较重要的一个点,在测试过程中有些数据是经常发生变化的,要获取这些数据,就需要使用关联,Jmeter可以通过“后置处理器”中的“正则表达式提取器”来处理关联.. 正则表达式提取器 ...

  4. 洛谷P2179 骑行川藏

    什么毒瘤... 解:n = 1的,发现就是一个二次函数,解出来一个v的取值范围,选最大的即可. n = 2的,猜测可以三分.于是先二分给第一段路多少能量,然后用上面的方法求第二段路的最短时间.注意剩余 ...

  5. Windows10搭建FTP服务

    1.启用Windows10 Ftp服务 打开控制面板->程序和功能->启用或关闭windows功能然后如图: 2.配置FTP用户 我的电脑->右击点击管理->本地用户和组 在A ...

  6. DirectX11--深入理解与使用缓冲区资源

    前言 在Direct3D 11中,缓冲区属于其中一种资源类型,它在内存上的布局是一维线性的.根据HLSL支持的类型以及C++的使用情况,缓冲区可以分为下面这些类型: 顶点缓冲区(Vertex Buff ...

  7. RabbitMQ installation

    以windows环境测试 Erlang http://www.erlang.org/downloads 下载并安装 运行时软件 Erlang OTP 21.3 Windows 64-bit Binar ...

  8. AngularJs实现表单验证

    首先,我们应该知道,表单中,常用的验证操作有: $dirty 表单有填写记录 $valid 字段内容合法的 $invalid 字段内容是非法的 $pristine 表单没有填写记录 $error 表单 ...

  9. Python+Selenium+Unittest框架使用——Selenium——模拟操作浏览器(三)

    1.浏览器大小的控制 Set_window_size()是控制浏览器大小 Maximize_window()浏览器全屏显示 from selenium import webdriver #导入sele ...

  10. CSS3 Flex布局

    Flex 用于使页面上的内容自适应屏幕 首先,在网页代码的头部,加入一行viewport元标签. <meta name=”viewport” content=”width=device-widt ...