简单工厂又称为静态工厂方法(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. 认识 Less

    CSS(层叠样式表)是一项出色的技术,它使得网页的表现与内容完全分离,使网站维护工作变得更容易,不会因为内容的改变而影响表现,也不会因为表现的改变而影响内容. 作为一门标记性语言,CSS 的先天性优点 ...

  2. HDU2159--二维费用背包,三重背包

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  3. 三种方法实现PCA算法(Python)

    主成分分析,即Principal Component Analysis(PCA),是多元统计中的重要内容,也广泛应用于机器学习和其它领域.它的主要作用是对高维数据进行降维.PCA把原先的n个特征用数目 ...

  4. springmvc 4.3,RequestParamMethodArgumentResolver无法正常解析String参数问题解决

    搭建一个新工程时,想使用最新稳当版的springmvc,所以选择了最新的版本 <dependency> <groupId>org.springframework</gro ...

  5. Python搭建Web服务器,与Ajax交互,接收处理Get和Post请求的简易结构

    用python搭建web服务器,与ajax交互,接收处理Get和Post请求:简单实用,没有用框架,适用于简单需求,更多功能可进行扩展. python有自带模块BaseHTTPServer.CGIHT ...

  6. MATLAB中最基本函数plot()的用法

    1二维平面图形 1.1基本图形函数 画出一条正弦曲线和一条余弦曲线 1.1.1绘图参数表 y 黄- 实线. 点< 小于号 m 紫: 点线o 圆s 正方形 c 青-. 点划线x 叉号d 菱形 r  ...

  7. Oracle在本地调试成功读取数据,但是把代码放到服务器读不出数据的解决方法。

    用MVC EF框架开发项目,数据库用的是Oracle,本地调试的时候一切正常,但是把代码编译之后放到服务器就会读不出数据. 原因:本地调试环境与服务器环境不一致. 办法:在服务器上装ODT.NET组件 ...

  8. Java爬虫——人人网模拟登录

    人人网登录地址:http://www.renren.com/ 此处登录没有考虑验证码验证码. 首先对登录方法进行分析 有两种方法. 一)在Elements中分析源码 发现登录点击后的事件是http:/ ...

  9. kafak集群安装-转

    前言 最近在利用Spark streaming和Kafka构建一个实时的数据分析系统,对图书阅读数据进行分析,做实时推荐.Spark Streaming 模块是对于 Spark Core 的一个扩展, ...

  10. hdu 1233 还是畅通project(kruskal求最小生成树)

    还是畅通project Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...