设计模式学习笔记------简单工厂

                                         简单工厂

一、实例1

 1 /**
 2  * 定义接口
 3  * @author abc
 4  *
 5  */
 6 public interface Api {
 7     public void test1();
 8 }
 9 
10 /**
11  * 接口实现类1
12  * @author abc
13  *
14  */
15 public class Impl1 implements Api {
16 
17     @Override
18     public void test1() {
19         System.out.println("实现test1方法");
20     }
21 }
22 
23 /**
24  * 接口实现类2
25  * @author abc
26  *
27  */
28 public class Impl2 implements Api {
29 
30     @Override
31     public void test1() {
32         System.out.println("实现test1方法");
33     }
34 }
35 
36 /**
37  * 工厂类
38  * @author abc
39  *
40  */
41 public class Factory {
42     /**
43      * 根据条件创建不同的实现来
44      * @param condition 实现条件
45      * @return
46      */
47     public static Api createImpl(int condition) {
48         Api api = null;
49         if (condition == 1) {
50             api = new Impl1();
51         } else if (condition == 2) {
52             api = new Impl2();
53         }
54         return api;
55     }
56     
57     public static void main(String[] args) {
58         Api api = Factory.createImpl(1);
59         api.test1();
60         api = Factory.createImpl(2);
61         api.test1();
62         
63     }
64 }

用户可以通过工厂来获取接口的实现类,可直接操作接口定义的方法。用户不需要知道具体方法是如何实现的。

实例1可以实现简单工厂模式,但是存在一个缺点,用户需要传入选择参数,这就说明用户必须知道每个参数的含义,也需要理解每个参数对应的功能处理,从一定的程度上想用户暴露了内部实现细节

二、实例2--配置文件实现

/**
 * 定义接口
 * @author abc
 *
 */
public interface Api {
    public void test1();
}

/**
 * 接口实现类1
 * @author abc
 *
 */
public class Impl1 implements Api {

    @Override
    public void test1() {
        System.out.println("实现test1方法");
    }
}

/**
 * 接口实现类2
 * @author abc
 *
 */
public class Impl2 implements Api {

    @Override
    public void test1() {
        System.out.println("实现test1方法");
    }
}

package cn.itcast.demo;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.xml.ws.FaultAction;

/**
 * 工厂类
 * @author abc
 *
 */
public class Factory {
    /**
     * 根据条件创建不同的实现来
     * @param condition 实现条件
     * @return
     */
    public static Api createImpl() {
        Properties p = new Properties();
        InputStream in = null;
        Api api = null;
        try {
            in = Factory.class.getResourceAsStream("FactoryTest.properties");
            p.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                    in = null;
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        try {
            api = (Api)Class.forName(p.getProperty("FactoryTest")).newInstance();
        } 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 api;
    }
    
    public static void main(String[] args) {
        Api api = Factory.createImpl();
        api.test1();
    }
}

FactoryTest.properties
#配置文件
FactoryTest=cn.itcast.demo.Impl1

在实例一中,如果需要添加一个实现类,则需要更改工厂类。二在实例二中,可以通过反射和配置文件(这里用的式properties,一般实际都使用xml配置)就可以实现在调节实现类后,无需更改代码就能将实现类添加到应用中。

三、简单工厂优缺点

优点:

  1.帮助封装

    简单工厂虽然很简单,但是非常友好地帮助我们实现了组件的封装,然后让组件外部能真正面向接口编程。

  2.解耦

    通过简单工厂,实现了客户端和具体实现类的解耦

    如同上面的例子,客户端根本就不知道具体是由谁类实现,也不知道具体是如何实现的,客户端只是通过工厂获取需要它的接口对象。

缺点:

  1.可能增加客户端的复杂度

    如果通过客户端的参数了现在具体的实现类,那么就必须让客户端你理解各个参数所代表的具体功能和含义,这样会增加客户端使用的难度,也部分暴露了内部实现,这种情况可以      选用可配置的方式来实现。

  2.不方便扩展子工厂

    私有化简单工厂的构造方法,使用静态方法来创建几口,也就不能通过写简单工厂类的子类来改变创建接口的方法的行为。不过,通常情况下是不需要为简单工厂创建子的。

四、简单工厂的本质

  简单工厂的本质是:选择实现 

  简单工厂的重点在选择,实现是已经做好了的。就算实现再简单,也要有具体的实现类类实现,而不是在简单工厂里面来实现。简单工厂的目的在于为客户端来选择相应的实现,从而使得客户端和实现之间解耦。这样一来,具体实现发生了变化,就不用变动客户端,这个变化会被简单工厂吸收和屏蔽掉。

五、何时选择简单工厂模式

  1. 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂,让客户端通过工厂来获取相应的接口,而无需关心具体实现。

  2.如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多的、不相关的对象,可以把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制。

posted @ 2018-01-02 11:04  有悟还有迷  阅读(181)  评论(0编辑  收藏  举报