设计模式之(二)简单工厂模式(staticFactory)

  这篇博文介绍简单工厂模式,设计模式并不是固定的二十三种,不同的书介绍的可能有出入,这篇介绍的简单工厂模式在有些书上就忽略不介绍了。设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。从设计模式上的定义可以了解到设计模式的本质,既然是总结出来的,肯定有出入。作为学习设计模式来说,还是把这个也记录下来,能给跟多一些思考。

  简单工厂模式是工厂模式的简化版,正因为如此,所以他的使用可以说是非常的普遍,很多代码中都有他的影子。接下来我们剖析简单工厂模式。

       不用模式场景

     java 是面向对象语言,是面向接口编程。接下来就先来看一个例子。

 1 /******************   接口 ****************************/
 2 public interface iTest {
 3      
 4      void funTest(String strTest);
 5      
 6 }
 7 
 8 /******************   类  实现上面接口 ********************/
 9 
10 public class CTest implements iTest {
11     
12     @Override
13     public void funTest(String strTest) {
14         // TODO Auto-generated method stub
15         System.out.println(strTest);
16     }
17     
18 }
19 
20 /******************   调用 ********************/
22 public class Client {
23 
24     public static void main(String[] args) {
25         // TODO Auto-generated method stub
26         iTest it = new CTest();
27         it.funTest("I am CTest class!");
28     }
29 }

  当初我们学习 java 的时候就是这样来实现的,这个在练习和学习里面是没有问题,甚至在不分模块的简单系统里面也是问题不大的。但是想这样一个问题,如果客户端调用的是一个模块,那么我们不仅需要知道这个模块的接口,还需要知道实现那些类,而一个模块里面用到的类是非常多的。这样调用起来非常麻烦,而且还暴露了模块的内部实现逻辑,没有做好模块的内部封装。这样一思考问题就显而易见了。

  简单工厂演化

  根据模块的封装性,把上面的实现调整一下。

 1 /**
 2  * 引入工厂类
 3  * @author Administrator
 4  */
 5 public class StaticFactory {
 6     //这里是 static 方法
 7     public static iTest createAPI(){
 8         iTest it = new CTest();
 9         return it;
10     }
11 }

  引入简单工厂,这个工厂用来创建具体实现,返回的是接口类型。那么再看下客户端调用有什么变化

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //iTest it = new CTest();
        //it.funTest("I am CTest class!");
        
        /******简单工厂方法的调用*****/
        iTest its = StaticFactory.createAPI();
        its.funTest("i am created class by StaticFactoy!");
    }
}

这儿可以看出来客户端调用已经不用知道具体实现的类型了,具体实现类型已经放入了引入的工厂类来显示了,虽然只是一个小小的变动,但是如果放入了实际的场景中,就有质的变化。

  实际运用中的简单工厂模式,当然不是这么简单了,应该有更多的逻辑,这里稍微扩展一下,一个接口一般是实现不同的类,那么可以根据不同的类型来选择不同的实现的类。

 1 /**
 2  * 引入工厂类
 3  * @author Administrator
 4  */
 5 public class StaticFactory {
 6     /**
 7      * 参数注释1
 8      */
 9     public static final  String Type1 = "1";
10     /**
11      * 参数注释2
12      */
13     public static final String Type2 = "2";
14     //这里是 static 方法
15     public static iTest createAPI(String Type){
16         iTest it =null;
17         if(Type.equals(Type1)){
18             it = new CTest();
19         }
20         else if(Type.equals(Type2)){
21             it = new Ctest2();
22         }
23         return it;
24     }
25 }
26 
27 /************  客户端调用   ****************/
28 
29 public class Client {
30     public static void main(String[] args) {
31         // TODO Auto-generated method stub
32         //iTest it = new CTest();
33         //it.funTest("I am CTest class!");
34         
35         /******简单工厂方法的调用*****/
36         //iTest its = StaticFactory.createAPI();
37         //its.funTest("i am created class by StaticFactoy!");
38         
39         /******改善简单工厂方法的调用*****/
40         iTest its = StaticFactory.createAPI(StaticFactory.Type1);
41         its.funTest("我是第一个接口实现");
42         its = StaticFactory.createAPI(StaticFactory.Type2);
43         its.funTest("我是第二个接口实现");
44     }
45 }

  根据不同的参数实现不同的类,而且我们可以把参数在工厂类里面写出来。一方面是便于客户查看,明白参数的用法;另外也可以判断客户是不是输入了非法参数,这儿没有判断非法参数。

  上面没有展示通过配置文件来实现简单工厂类,实际上就是把例子中需要传入的参数放入了配置文件中,让客户端调用无需再输入参数。在系统配置连接不同数据库的话,应该就是用的这样的方式。本文不在累述。

  总结

  定义:提供一个创建对象实例的功能,而不用关心其具体实现。被常见的对象可以是接口、抽象类,具体的类。

  分析:简单工厂模式,本质上就是在普通代码上添加一个工厂类,创建对象装在了这个类里面,而且对象具体实现不在这个里面。

  优点:

  • 调用的接口的封装性更好了,没有暴露内部的逻辑实现。
  • 解耦,实现了客户端和具体实现类解耦
  • 接口的实现类统一管理了。可以扩展也是只要简单工厂类改动就可以了。

  缺点:

  • 增加了代码复杂度。

  虽然这个简单工厂模式非常简单,但是在系统代码里面运用非常普遍。可能你已经运用了,但是自己没有意识到。简单工厂模式的介绍就到这里了。

原文地址:https://www.cnblogs.com/pengweiqiang/p/10562045.html