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

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

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

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

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

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. 清北学堂(2019 4 28 ) part 1

    今天主要用来铺路,打基础 枚举 没什么具体算法讲究,但要考虑更优的暴力枚举方法,例如回文质数,有以下几种思路: 1.挨个枚举自然数,再一起判断是否是回文数和质数,然而一看就不是最优 2.先枚举质数再判 ...

  2. [ffmpeg] h.264解码所用的主要缓冲区介绍

    在进行h264解码过程中,有两个最重要的结构体,分别为H264Picture.H264SliceContext. H264Picture H264Picture用于维护一帧图像以及与该图像相关的语法元 ...

  3. C语言函数-strcat

    strcat: 将两个char类型连接. char d[20]="GoldenGlobal"; char *s="View"; strcat(d,s); 结果放 ...

  4. a标签 download base64 下载 网络失败

    使用html2canvas 生成尺寸较大 base64 后进行 a标签  download 下载 ,浏览器报网络失败错误 通过谷歌搜索 发现原因是 因为截取尺寸较大  导致生成base64 长度太大 ...

  5. 「FHQ Treap」学习笔记

    话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一 ...

  6. Http input plugin

    logstash作为一个数据输入端.提供http服务,接收客户端的http请求,获取发送的内容. 在config目录下新建文件: vim config/http-input.yml input { h ...

  7. CC1310 笔记

    GPIO控制: #include <ti/drivers/GPIO.h> GPIO_init() 函数会调用 结构体实例 GPIOCC26XX_config,把需要使用到的GPIO放一起, ...

  8. Daily Codeforces 计划 训练时录

    时间                 场次                             过题数目      补题数目   难易度 2019.4.7      codeforces-1141 ...

  9. 对filter的初步认识

    Filter 技术是servlet 2.3  新增加的功能.servlet2.3是sun公司 于2000年10月发布的,它的开发者包括许多个人和公司团体,充分体现了sun公司所倡导的代码开放性原则.在 ...

  10. Arrays和String单元测试 20175301

    要求 在IDEA中以TDD的方式对String类和Arrays类进行学习 一.String类相关方法的单元测试 1.ChatAt的测试 代码: import org.junit.Test; impor ...