简单工厂(Simple Factory),最合适的设计模式首秀.
简单工厂又称为静态工厂方法(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),最合适的设计模式首秀.的更多相关文章
- 设计模式:简单工厂(Simple Factory)
定义:根据提供的数据或参数返回几种可能类中的一种. 示例:实现计算器功能,要求输入两个数和运算符号,得到结果. 结构图: HTML: <html xmlns="http://www.w ...
- 使用C# (.NET Core) 实现简单工厂(Simple Factory) 和工厂方法设计模式 (Factory Method Pattern)
本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子. 前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是 ...
- 设计模式~简单工厂模式(Factory)
简单工厂模式Simple Factory根据提供给它的数据,返回一个类的实例.通常它返回的类都有一个公共的父类(或者接口对象). 简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类 ...
- 简单工厂,Factory Method(工厂方法)和Abstract Factory(抽象工厂)模式
对于简单工厂来说,它的工厂只能是这个样子的 public class SimplyFactory { /** * 静态工厂方法 */ public static Prouct factory(Str ...
- Java设计模式:Simple Factory(简单工厂)模式
概念定义 简单工厂(Simple Factory)模式,又称静态工厂方法(Static Factory Method)模式,即定义一个工厂类,根据传入的不同参数创建不同的产品实例,这些实例对象具有共同 ...
- Java 设计模式系列(二)简单工厂模式和工厂方法模式
Java 设计模式系列(二)简单工厂模式和工厂方法模式 实现了创建者和调用者的分离.分为:简单工厂模式.工厂方法模式.抽象工厂模式 简单工厂模式.工厂方法模式都很简单,就不详细介绍了. 一.简单工厂 ...
- 设计模式学习(四): 1.简单工厂 (附C#实现)
New 这是一个典型的情况, 我们需要在运行时来实例化一些具体的类. 在需要修改或者扩展的时候我们就需要改这段代码. 一个程序中可能会多次出现类似的代码, 这使得维护和更新非常困难而且容易出错. 通过 ...
- Unity C# 设计模式(二)简单工厂模式
定义: 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一. 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例 ...
- 工厂模式(factory pattern)
工厂模式主要用来封装对象的创建,有3种分类:简单工厂(simple factory).工厂方法(factory method).抽象工厂(abstract factory). 简单工厂包括3种组成元素 ...
随机推荐
- JavaScript DOM 编程艺术(1)---> JavaScript语法
一. JavaScript语法目录 语法 操作 条件语句 循环语句 函数 对象 二. 具体内容 2.1 语法 javaScript代码要通过HTML/XHTML文档才能执行.可以有两种方式完成这一 ...
- 《Linux命令行与shell脚本编程大全》第十九章 初识sed和gawk
这两个工具能够极大简化需要进行的数据处理任务. 19.1 文本处理 能轻松实现自动格式化.插入.修改或删除文本元素的简单命令行编辑. sed和gawk就具备上述功能 19.1.1 sed编辑器 被称为 ...
- Thinkphp使用phpexcel导入文件并写入数据库
现实中,我们往往很多地方都需要这样批量导入数据,除了phpexcel还有csv等方法可以解决 下面详细介绍一下使用方法 首先在官方下载安装包解压到本地,然后复制保存到tp框架下的vendor目录下 h ...
- Android开发之漫漫长途 番外篇——内存泄漏分析与解决
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- 2017最新PHP初级经典面试题目汇总(下篇)
17.isset.empty.is_null的区别 isset 判断变量是否定义或者是否为空 变量存在返回ture,否则返回false 变量定义不赋值返回false unset一个变量,返回false ...
- 使用PHP画统计图的方法
<?php //最后一次修改:2004-6-21 //一个生成矩形图,曲线图的图形分析类 //作者:tonera //说明: //任何人可在任何场合自由使用这个类.但由此所发生的损害跟作者无关. ...
- [安全]PHP能引起安全的函数
php中需要禁用以下函数来提高安全性 打开php.ini 找到 disable_functions .然后禁用以下函数 [C] 纯文本查看 复制代码 ? 1 disable_functions = ...
- JavaScript学习总结(一)——ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
一.JavaScript简介 JavaScript是一种解释执行的脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型,它遵循ECMAScript标准.它的解释器被称为JavaScript引 ...
- 天天乐宝APP开发
"互联网+"时代是一个"信息过剩"的时代,也是一个"注意力稀缺"的时代,怎样在"无限的信息中"获取"有限的注意 ...
- JavaWeb核心技术学习 - 1.从JDBC说起
作者:java1to3链接:http://www.cnblogs.com/java1to3/著作权归作者所有.未经作者本人同意,禁止一切转载.商业或非商业转载请联系作者获得授权并请注明出处. ・JDB ...