简单工厂又称为静态工厂方法(static factory method)模式,简单工厂是由一个工厂来决定创建出哪一种个体的实现,在很多的讨论中,简单工厂做为工厂方法模式(Factory Method)的一个特殊案例出现.

这个模式封装的变化点是什么?

这是每一个模式都应该考虑的核心问题,一定要记得,如果系统中这个点不会变化,是没必要来封装的,否则会造成模式误用.简单工厂是解决因为多个子类的实例动态创建的问题,变化点也就是:具体的创建实例不确定.

初期状态

既然是对象创建模式,当然解决的是对象创建时的耦合,不是所有的创建对象都是耦合的,我们需要酌情考虑,比如:String str = new String("abc");这样的代码,在系统中是不会变化的,或者变化频率非常的低,不必封装.而我们的业务对象比如一个游戏场景中的道路(Road)希望在运行中选择不同风格的道路,比如有泥泞道路(WaterRoad),雪地道路(SnowRoad),未来还有可能引入各种不同道路,那么我们的初期调用处(Client)代码可能是这样的:

if( roadType.equals("water") )
{
    WaterRoad wroad = new WaterRoad() ;
    //...
}
else if( roadType.equals("snow"))
{
    SnowRoad sroad = new SnowRoad() ;
    //...
}

此时如果要加入新的XXRoad风格对象,我们需要增加一个XXRoad类,然后在调用处(Clinet)代码中修改,增加else if( roadType.eqals("xxroad"))这样的代码.违反了设计模式中的开闭原则(对扩展开放,对修改关闭),我们使用了破坏性的方式来修改这段代码,导致了调用处代码的修改与重新编译.

第一步封装

按照重构的思路,我们上边的代码,因为违反了开闭原则,我们希望在修改代码时不用去修改Client代码,在这里我们引入依赖倒置原则来解决这个问题.

先来看看我们目前的依赖关系,高层模块依赖着低层模块,Client代码就是高层模块,它直接调用着WaterRoad,SnowRoad等对象,这样当对象有变化时,自然是会影响到Client代码.依赖倒置是指,在高层模块与低层模块中加入一层抽象层,两层代码都依赖了抽象层.这样当具体类型需要修改时,不会影响到Client.

解决办法

在上面的例子中,引入Road接口,来描述道路的共同行为,将WaterRoad与SnowRoad实现Road接口.这样一来,调用处的代码就变成了

    Road road = null ;

    if( roadType.equals("water") )
    {
        road = new WaterRoad() ;
        //...
    }
    else if( roadType.equals("snow"))
    {
        road = new SnowRoad() ;
        //...
    }

封装了什么?

至此我们完成了第一步封装,将对象的行为抽象为接口,将变化的不同类型的是现封装到了实现类中.但是Client中的代码还是在if else判断,如果加入新的类型,依然需要修改Client,接下来我们解决第二步封装.

第二步封装

上面提到的问题是要解决Client中的if else判断,我们引进SimpleFactory来封装这个动态判断的过程.

/**
 * 道路接口
 *
 * @author aladdinty
 * @create 2017-12-29
 **/
public interface Road
{
}

/**
 * @author aladdinty
 * @create 2017-12-29
 **/
public class SnowRoad implements Road
{
}

/**
 * @author aladdinty
 * @create 2017-12-29
 **/
public class WaterRoad implements Road
{
}

/**
 * 最简单的工厂模式
 *
 * @author aladdinty
 * @create 2017-12-29
 **/
public class SimpleFactory
{
    public static Road createObject(String roadType)
    {
        if( roadType.equals ( "water"))
        {
            return new WaterRoad () ;
        }
        else if( roadType.equals ("snow"))
        {
            return new SnowRoad () ;
        }
        else
        {
            return null ;
        }
    }

    public static void main( String[] args )
    {
        Object obj = SimpleFactory.createObject ("water") ;
    }
}

到目前为止,简单工厂模式就完成了,解决了具体创建的对象类型不确定,当增加新的具体实现时,我们可以增加类的方式来实现,不必修改调用处(Client),当然Factory还需要修改if else代码,这个问题可以用之后的工厂方法模式来解决,或者使用反射技术. 工厂方法模式是专门为了解决factory中的变化而生,反射是将字符串判断消化掉.

简单工厂(Simple Factory),最合适的设计模式首秀.的更多相关文章

  1. 设计模式:简单工厂(Simple Factory)

    定义:根据提供的数据或参数返回几种可能类中的一种. 示例:实现计算器功能,要求输入两个数和运算符号,得到结果. 结构图: HTML: <html xmlns="http://www.w ...

  2. 使用C# (.NET Core) 实现简单工厂(Simple Factory) 和工厂方法设计模式 (Factory Method Pattern)

    本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子. 前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是 ...

  3. 设计模式~简单工厂模式(Factory)

    简单工厂模式Simple Factory根据提供给它的数据,返回一个类的实例.通常它返回的类都有一个公共的父类(或者接口对象). 简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类 ...

  4. 简单工厂,Factory Method(工厂方法)和Abstract Factory(抽象工厂)模式

    对于简单工厂来说,它的工厂只能是这个样子的 public class SimplyFactory {  /** * 静态工厂方法 */ public static Prouct factory(Str ...

  5. Java设计模式:Simple Factory(简单工厂)模式

    概念定义 简单工厂(Simple Factory)模式,又称静态工厂方法(Static Factory Method)模式,即定义一个工厂类,根据传入的不同参数创建不同的产品实例,这些实例对象具有共同 ...

  6. Java 设计模式系列(二)简单工厂模式和工厂方法模式

    Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...

  7. 设计模式学习(四): 1.简单工厂 (附C#实现)

    New 这是一个典型的情况, 我们需要在运行时来实例化一些具体的类. 在需要修改或者扩展的时候我们就需要改这段代码. 一个程序中可能会多次出现类似的代码, 这使得维护和更新非常困难而且容易出错. 通过 ...

  8. Unity C# 设计模式(二)简单工厂模式

    定义: 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一. 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例 ...

  9. 工厂模式(factory pattern)

    工厂模式主要用来封装对象的创建,有3种分类:简单工厂(simple factory).工厂方法(factory method).抽象工厂(abstract factory). 简单工厂包括3种组成元素 ...

随机推荐

  1. StringUtils工具类常用方法汇总1(判空、转换、移除、替换、反转)

      Apache commons lang3包下的StringUtils工具类中封装了一些字符串操作的方法,非常实用,使用起来也非常方便.最近自己也经常在项目中使用到了里面的一些方法,在这里将常用的方 ...

  2. DC 辅域转主域

    DC 辅域转主域 #dc2辅域 角色转移为主域 #查看 netdom query fsmo ntdsutil roles connections #连接主机dc2 connect to server ...

  3. HTTPS原理浅析

    HTTPS(Hypertext Transfer Protocol Secure)协议用于提供安全的超文本传输服务. 其本质上是SSL/TLS层上的HTTP协议, 即所谓的"HTTP ove ...

  4. JAVA8新特性(一)

    default拓展方法 java8为接口声明添加非抽象方法的实现,也成为拓展方法. public interface Formula { void doSomething(); default voi ...

  5. 用phpmailer发送邮件提示SMTP Error: Could not connect to SMTP host解决办法

    之前做项目的时候做了一个用phpmailer发送邮件的功能<CI框架结合PHPmailer发送邮件>,昨天步署上线(刚开始用新浪云,嫌贵,换成阿里了),测试的时候,发送邮件却意外报错了.. ...

  6. select控件自动触发change事件

    这里接上面的二级联动.背景:当页面跳转到修改页面时,需要首先绑定学院和专业.这就需要在页面加载时触发select的change事件,具体用trigger函数进行实现.代码如下. $("#xs ...

  7. Android IntentService使用介绍以及源码解析

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.IntentService概述及使用举例 IntentService内部实现机制用到了HandlerThread,如果对HandlerThrea ...

  8. flask_login 整合 pyjwt + json 简易flask框架

    现在很多框架都实现前后端分离,主要为了适应以下几个目的: 1,前后端的分离,可以使前端开发和后端开发更加分工明确,而不是后端还需要在视图模板中加入很多{% XXXX %}标签 2,是为了适应跨域调用或 ...

  9. 19_Android中图片处理原理篇,关于人脸识别站点,图片载入到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写

    1载入图片到内存 (1).数码相机照片特别是大于3m以上的,内存吃不消,会报OutOfMemoryError,若是想仅仅显示原图片的1/8,能够通过BitmapFactory.Options来实现.详 ...

  10. Hadoop之SequenceFile

    Hadoop序列化文件SequenceFile能够用于解决大量小文件(所谓小文件:泛指小于black大小的文件)问题,SequenceFile是Hadoop API提供的一种二进制文件支持.这样的二进 ...