模式的秘密——工厂模式

原创 2016年08月29日 08:26:38

模式的秘密——工厂模式

一、   工厂模式的概念

工厂模式:为创建对象提供过度接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

 

二、   工厂模式的应用场景

工厂方法

1、当一个类不知道它所必须创建的对象的类的时候;

2、当一个类希望由它的子类来指定它所创建的对象的时候;

3、当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮组子类是代理者这一信息局部化的时候。

抽象工厂

1、一个系统应当不依赖于产品类实例被创立、组成和表示的细节,这对于所有形态的工厂模式都是重要的

2、这个系统的产品有至少一个的产品族

3、同属于一个产品族的产品是设计成在一起使用的,这一约束必须得在系统的设计中体现出来

4、不同的产品以一系列的接口的面貌出现,从而使系统不依赖于接口实现的细节

 

三、   工厂模式的实例

在一些制作类APP、游戏、即时通信应用的人物装扮功能中,我们可以选择人物的发型、脸型、眼睛、鼻子、嘴巴、睫毛、眉毛的样子来构造人物形象,类似这样的功能可以通过工厂模式的思想来实现。比如说,现在我们要实现人物发型的功能,我们就可以通过工厂模式来实现,我们就简单的以左偏分、右偏分和中分为例来看一看源码应该如何实现。

1、         首先,我们需要定义一个统一的接口HairInterface,实现画发型的功能

 

public interfaceHairInterface {

          public void drawHair();

}

2、         然后左偏分、右偏分和中分的子类都实现HairInterface接口

 

/*

 * 左偏分

 */

public class LeftDirHair implements HairInterface {

 

     @Override

     public void drawHair() {

          // TODO Auto-generated method stub

          System.out.println("左偏分");

     }

 

}

 

/*

 * 右偏分

 */

public class RightDirHair implements HairInterface {

 

     @Override

     public void drawHair() {

          // TODO Auto-generated method stub

          System.out.println("右偏分");

     }

 

}

 

3、         需要什么样的发型我们可以通过实例化具体的子类来实现,这样做后期有了新的发型不便于扩展,所以我们可以通过定义工厂来统一定义发型的实例。

 

/*

 * 发型工长

 * 生成发型

 */

public class HairFactory {

     public HairInterface getHair(String key) {

          if ("left".equals(key)) {

               return new LeftDirHair();

          }else if ("right".equals(key)) {

               return new RightDirHair();

          }

          return null;

     }

}

 

4、         测试

 

HairFactory factory = new HairFactory();

     HairInterfacehairInterface = factory.getHair("left");

hairInterface.drawHair();

5、         上面我们通过关键字来判读发型,我们可以通过Java的反射机制来对工厂方法进行修改,在HairFactory中添加方法

 

public HairInterface getHairByClassName(String className) {

          try {

               HairInterfacehair = (HairInterface) Class.forName(className).newInstance();

               return hair;

          }catch (InstantiationException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }catch (IllegalAccessException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }catch (ClassNotFoundException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }

          return null;

     }

在测试类中这样调用

HairFactory factory = new HairFactory();

HairInterface left factory.getHairByClassName("LeftDirHair");

left.drawHair();

注:必须是全类名(包名+类名),小编没有创建应用包,这点不提倡

6、         上面的方法我们通过反射来判读发型,感觉关键字太长,不太方便,所以我们在该进一下,我们可以通过type.properties实现全类名和关键字的映射,创建文件type.properties,内容如下:

left=LeftDirHair

right=RightDirHair

7、         通过PropertiesReader读取type.properties文件

 

/*

 *properties文件读取

 */

public class PropertiesReader{

     public Map<String, String> getProperties(){

          Propertiesprops = new Properties();

          Map<String,String> map = new HashMap<>();

          try {

               InputStreamin = getClass().getResourceAsStream("type.properties");

               props.load(in);

               Enumerationen = props.propertyNames();

               while(en.hasMoreElements()){

                     Stringkey = (String)en.nextElement();

                     Stringproperty = props.getProperty(key);

                     map.put(key, property);

               }

          }catch (Exception e) {

               // TODO: handle exception

               e.printStackTrace();

          }

          return map;

     }

}

8、         在HairFactory中添加改进的方法getHairByClassKey

 

public HairInterface getHairByClassKey(String key) {

          try {

               Map<String, String> map = new PropertiesReader().getProperties();

              

               HairInterfacehair = (HairInterface) Class.forName(map.get(key)).newInstance();

               return hair;

          }catch (InstantiationException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }catch (IllegalAccessException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }catch (ClassNotFoundException e) {

               // TODO Auto-generated catch block

               e.printStackTrace();

          }

          return null;

  }

 

                  前面我们以人物的发型为例简单讲解了工厂模式的源码实现。那么,比如新的需求圣诞节马上到了,老板要求实现“圣诞系列男孩的装扮”和“圣诞系列女孩装扮”,这个时候我们又该怎么办呢?这个时候我们就可以考虑抽象工厂模式的思想来实现老板的需求,这样的话不管是圣诞系列还是春节系列都so easy!

1、 首先,我们需要定义男孩和女孩的抽象类

 

public interface Boy {

     public void drawBoy();

}

 

public interface Girl {

     public void drawGirl();

}

 

2、 然后,定义圣诞系装扮男孩和女孩的具体实现类

 

/*

 * 圣诞系男孩装扮

 */

public class MCBoy implements Boy {

 

     @Override

     public void drawBoy() {

          // TODO Auto-generated method stub

          System.out.println("圣诞系列男孩装扮");

     }

 

}

 

/*

 * 圣诞系列女孩装扮

 */

public class MCGirl implements Girl {

 

     @Override

     public void drawGirl() {

          // TODO Auto-generated method stub

          System.out.println("圣诞系列女孩装扮");

     }

 

}

 

3、 接着,我们需要定义一个工厂接口用来获取男孩和女孩的实例

 

public interfacePersonFactory {

     public Boy getBoy();

 

     public Girl getGirl();

}

 

4、 最后,定义圣诞系装扮工厂实现PersonFactory接口

 

public class MCFactory implements PersonFactory {

 

     @Override

     public Boy getBoy() {

          // TODO Auto-generated method stub

          return new MCBoy();

     }

 

     @Override

     public Girl getGirl() {

          // TODO Auto-generated method stub

          return new MCGirl();

     }

 

}

5、 验证

PersonFactory factory2 = new MCFactory();

     Girlgirl factory2.getGirl();

girl.drawGirl();

6、 当然什么中秋系装扮、元旦系装扮都和圣诞系装扮实现方式类似。

四、   工厂模式的设计思想

低耦合,一个对象的依赖对象的变化与本身无关

具体产品与客户端剥离,责任分割

五、   总结

工厂方法模式和抽象工厂模式对比

1、工厂模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广

2、工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构

3、工厂模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类

 

工厂模式的优点:

1、系统可以在不修改具体工厂角色的情况下引进新的产品

2、客户端不必关心对象如何创建,明确了职责

3、更好的理解面向对象的原则,面向接口编程,而不是面向实现编程

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

简单工厂模式(思想)

简单工厂模式解释:         简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern...

设计模式思想工厂模式

工厂模式 分为 简单工厂模式 工厂方法模式 抽象工厂模式 简单工厂模式什么样的呢? 用户A需要A产品,用户B需要B产品,直接找工厂要就行了。当然需要A产品类,B产品类,然后工厂根据用...

工厂模式的小例子——j2sE

  • 2009年04月01日 21:41
  • 2KB
  • 下载

java工厂模式应用——多数据库分页实现

1.由于数据库的不同,每种数据库实现的分页的SQL语句不同,其实方法是一样的,这样我们可以抽象出数据库查询分页的方法接口,如下package com.hibernate.pageService; i...

设计模式——简单工厂模式

  • 2013年08月10日 15:54
  • 6KB
  • 下载

鬼话连篇(二)——简单工厂模式(C++/C#)

概念:作为菜鸟,我觉得我不会讲概念性的东西。就算会讲,也应该是从其他地方抄过来的。而能看到这篇博客的小伙伴们应该也从其他地方或多或少有所了解,我也就不加赘述了。思路:首先我们来解决一个实际问题。当我们...

工厂模式——排序方法的封装

排序工厂类>作业总结 作业题: 实现一个排序系统              相关知识: 1、 接口(C++叫抽象类) 2、 排序算法:冒泡排序、快速排序、直接插入排序、归并排序 3、 工厂模式 要...

简单工厂模式——Factory

专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式,属于类的创建型模式。   简单工厂模式的UML类图                        ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:模式的秘密——工厂模式
举报原因:
原因补充:

(最多只允许输入30个字)