简单工厂(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种组成元素 ...
随机推荐
- 二维,多维数组排序array_multisort()函数的使用
对于数组的排序,很很多方法:随便百度了一下 sort() - 以升序对数组排序 rsort() - 以降序对数组排序 asort() - 根据值,以升序对关联数组进行排序 ksort() - 根据键, ...
- Linux下安装Redis php-redis扩展 redis重启shell脚本 超详细!
前言 前面刚写过nosql其中三款热门产品的对比,这次主要写关于Redis的一些事情,Redis的介绍.安装以及扩展(php-redis,因为我是phper)安装等等.同时是写给我的朋友(cccjjj ...
- JS构造函数模式
构造函数是可以创建特定类型对象的函数,可以接受参数定义函数成员.如果之前做过java比较好理解,举个例子: function exampleFunction(arg1, arg2, arg3){ th ...
- ShoneSharp语言(S#)的设计和使用介绍系列(4)— 入门概述
ShoneSharp语言(S#)的设计和使用介绍 系列(4)- 入门概述 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. ...
- 【转】用systemJS+karma+Jasmine+babel环境去编写简单的ES6工程
原文链接:http://www.cnblogs.com/shuoer/p/7779131.html 用systemJS+karma+Jasmine+babel环境去编写简单的ES6工程 首先解释下什么 ...
- 数据结构与算法(C/C++版)【绪论/线性表】
声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识 /// ...
- win10解决乱码问题
Unicode是Unicode.org制定的编码标准,目前得到了绝大部分操作系统和编程语言的支持.Unicode.org官方对Unicode的定义是:Unicode provides a unique ...
- Python的集合
1. Python的集合 1.1 集合的定义 在Python中, 集合set是基本数据类型的一种集合类型,它有可变集合(set())和不可变集合(frozenset)两种.Python中的集合set类 ...
- 42.Linux应用调试-初步制作系统调用(用户态->内核态)
1首先来讲讲应用程序如何实现系统调用(用户态->内核态)? 我们以应用程序的write()函数为例: 1)首先用户态的write()函数会进入glibc库,里面会将write()转换为swi(S ...
- Android - shape圆形画法(oval)
shape圆形画法(oval) 本文地址: http://blog.csdn.net/caroline_wendy 1. 创建一个目录drawable, 用于存放xml类型的图片资源; 2. 在dra ...