设计模式之工厂模式
来源:互联网 发布:json.stringify array 编辑:程序博客网 时间:2024/06/06 11:24
尊重原创 http://write.blog.csdn.net/postedit/26062579
本文代码:http://download.csdn.net/detail/yuanzeyao2008/7360653
工厂模式主要是用来生成具有相同接口的类
工厂模式主要包括:1、简单工厂
2、工厂方法
3、抽象工厂
我们首先来学习一下简单工厂的原理:
学习背景:
我需要这样一个智能程序,我对它讲话,它能够为我制造一台能够满足我需求的电器
如:我要看电视,它给我制造一台电视,我要洗衣服,它给我制造一台洗衣机...
首先我使用面向过程的方法来实现这个程序
public static void main(String[] args) throws IOException { //从控制台获取用户需求 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String input=br.readLine(); //根据用户需求,制造相应的电器为用户服务 if(input.equals("洗衣服")) { Washer washer=new Washer(); washer.execute(); }else if(input.equals("看电视")) { Televisor tv=new Televisor(); tv.execute(); }else if(input.equals("冰冻食物")) { Refrigerator ref=new Refrigerator(); ref.execute(); } }
上面这段程序基本功能是具备了的,但是有一种坏的味道(重构里面喜欢用的词),所有的逻辑判断都放在了客户端程序中,如果用户的需求变了,那么我们就需要更改客户端代码,添加逻辑判断,对于代码的扩展非常不方面,而且也不合符“开放-封闭”原则,像这种根据不同的需求要生成具有类似功能类的情况非常适合 使用工厂模式解决,下面我就使用简单工厂模式在解决这个问题:
简单工厂的类图如下:
步骤:
1、建立一个电器的公用接口Machine
/** * 电器的公用接口,没一种使用工厂创建的都必须实现它 * com.design.factory.simple.Machine * @author yuanzeyao <br/> * create at 2014年5月17日 上午10:44:58 */public interface Machine{ public void execute();}2、每一种电器都实现接口,具体见代码
3、工厂类
/** * 简单工厂类,用于生产实现了Machine的各种电器 * com.design.factory.simple.SimpleFactory * @author yuanzeyao <br/> * create at 2014年5月17日 上午10:34:41 */public class SimpleFactory{ private static final String TAG = "SimpleFactory"; public static Machine createMachine(String demand) { //根据用户需求,制造相应的电器为用户服务 if(demand.equals("洗衣服")) { return new Washer(); }else if(demand.equals("看电视")) { return new Televisor(); }else if(demand.equals("看电视")) { return new Refrigerator(); }else return null; }} 4、客户端 public class Simple2{ private static final String TAG = "Simple2"; public static void main(String[] args) throws IOException { //从控制台获取用户需求 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String input=br.readLine(); Machine machine=SimpleFactory.createMachine(input); if(machine!=null) { machine.execute(); } }}
使用了简单工厂后,最大的好处就是方便了添加用户需求,将逻辑判断代码都移到了工厂类里面,当我们需要添加新的需求时,仅仅修改工厂类即可,不需要修改客户端代码,以上就是简单工厂设计模式,非常简单
下面使用工厂方法实现同样的功能
之所以有工厂方法模式,是因为简单工厂有一些缺点:
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利
所以我们一定要明白一个道理:没有十全十美的设计模式,如果这个设计模式符合你的需求那么就是最好的
工厂方法模式和简单工厂模式的区别如下:
1、每个具体产品都有一个对应的工厂类,并且为工厂类抽象出一个借口
2、在客户端根据条件使用不同的工厂类
工厂方法的类图如下:
实现方式:
1、编写一个抽象工厂类
/** * 工厂抽象出来的接口 * com.design.factory.method.IFactory * @author yuanzeyao <br/> * create at 2014年5月17日 上午11:34:03 */public interface IFactory{ public static final String TAG = "IFactory"; public Machine createMachine();}2、各个机器的具体工厂类,这里我只贴出洗衣机的,其他的大家可以下载代码查看
/** * 洗衣机具体工厂类 * com.design.factory.method.WasherFactory * @author yuanzeyao <br/> * create at 2014年5月17日 上午11:35:43 */public class WasherFactory implements IFactory{ private static final String TAG = "WasherFactory"; @Override public Machine createMachine() { return new Washer(); }}
3、客户端代码:
public class Sample3{ private static final String TAG = "Sample"; public static void main(String[] args) throws IOException { IFactory factory=null; //从控制台获取用户需求 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String input=br.readLine(); //根据用户需求,制造相应的电器为用户服务 if(input.equals("洗衣服")) { factory=new WasherFactory(); }else if(input.equals("看电视")) { factory=new TelevisorFactory(); }else if(input.equals("冰冻食物")) { factory=new RefrigeratorFactory(); } Machine machine=factory.createMachine(); machine.execute(); }}
我们总结下工厂方法和简单工厂方法的区别吧
在简单工厂方法中,将所有的判断逻辑加入到了工厂类中,这样创建所有机器的细节封装到工厂中,对用户来说非常方便,但是这样导致工厂的责任过于重大,一旦某个逻辑出问题,所有的机器都造不出来。
在工厂方法模式中就将工厂抽象出来了,每个机器都有个工厂,这样一个工厂出问题,其他工厂仍然能够使用,但是这个设计模式有个缺点就是每增加一个需求,需要增加2个类,所以可能导致产生很多的类
下面我们来学习工厂模式的最后一种:抽象工厂方法
抽象工厂方法是要求一个工厂能够创建所有的产品(有点像简单工厂),以及为每个工厂抽取一个公共接口(有点像工厂方法),只不过具体的工厂中的产品要有某种关联。
举个例子:比如我的需求是洗衣服,那么工厂就为我创建洗衣机,如果这个工厂是“美的”,那么就生产美的的,如果这个工厂是“康佳”的,那么就生产康佳的(我只是举例的,它们不一定生产这些电器) ,此时美的也生产电视,冰箱等等家电,同时康佳也都生产这些家电。
我们使用代码来实现抽象工厂
1、实现一个工厂的抽象类
/** *抽象工厂类,里面生产多件产品,这些产品有着某种关联,比如都是该厂家生产 * com.design.factory.abstractfactory.IFactory * @author yuanzeyao <br/> * create at 2014年5月17日 下午12:31:44 */public interface IFactory{ public Machine createTelevisor(); public Machine createWasher(); public Machine createRefrigerator();}
2、实现一个厂家所有产品的具体实现类,具体见代码
3、实现每个具体工厂类
/** * 生产美的电器的工厂 * com.design.factory.abstractfactory.MediaFactory * @author yuanzeyao <br/> * create at 2014年5月17日 下午12:39:41 */public class MediaFactory implements IFactory{ private static final String TAG = "MediaFactory"; @Override public Machine createTelevisor() { return new MediaTv(); } @Override public Machine createWasher() { return new MediaWasher(); } @Override public Machine createRefrigerator() { return new MediaRefrigerator(); }}/** * 生产康佳电器的工厂 * com.design.factory.abstractfactory.KanjiaFactory * @author yuanzeyao <br/> * create at 2014年5月17日 下午12:40:00 */public class KanjiaFactory implements IFactory{ private static final String TAG = "MediaFactory"; @Override public Machine createTelevisor() { return new KanjiaTv(); } @Override public Machine createWasher() { return new KanjiaWasher(); } @Override public Machine createRefrigerator() { return new KanjiaRefrigerator(); }}
4、客户端代码
public class Sample4{ private static final String TAG = "Sample4"; public static void main(String[] args) throws IOException { //从控制台获取用户需求 //数据输入格式:厂家首字母大写_需求 如:M_洗衣服,就给你返回美的洗衣机 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String input=br.readLine(); String[]inputs=input.split("_"); IFactory factory=null; if(inputs[0].equals("M")) { factory=new MediaFactory(); }else { factory=new KanjiaFactory(); } if(inputs[1].equals("洗衣服")) { factory.createWasher().execute(); }else if(inputs[1].equals("看电视")) { factory.createTelevisor().execute(); }else if(inputs[1].equals("冰冻食物")) { factory.createRefrigerator().execute(); } }}
其实这段代码的外面还可以加一层 简单工厂模式,也就是结合简单工厂+抽象工厂,来优化代码
学到这里,工厂模式差不多也结束了,三种工厂模式各有各的有点,我们需要根据具体情况来使用,欢迎大家留言讨论...
0 0
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之---工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之-工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之工厂模式
- 设计模式之 ------工厂模式
- 设计模式之工厂模式
- PAT A 1043. Is It a Binary Search Tree (25)
- 数据去重
- Android bug——hwui中fb socket泄露问题
- OpenCV中傅里叶变换和反变换的运用
- 国行高配版三星Galaxy S5/Mega 2大起底
- 设计模式之工厂模式
- 如何让三星I9105P获得ROOT权限
- MFC中简单的数据库文件操作(添加,修改,查找,删除)
- 偶得网站
- Linux sqlite3基本命令
- 安装oracle 11gR2单实例+ASM
- andriod 四大组件
- MFC中对话框的操作
- 51用485传送温度给stm32