1 、设计模式 简单工厂设计模式

 

客户需要某个产品,客户直接和生成该产品的工厂打交道,工厂具体来负责产品的实现

 

package cn.javass.dp.simplefactory.example4;
/**
 * 某个接口(通用的、抽象的、非具体的功能的) 
 */
public interface Api {
    /**
     * 某个具体的功能方法的定义,用test1来演示一下。
     * 这里的功能很简单,把传入的s打印输出即可 
     * @param s 任意想要打印输出的字符串
     */
    public void test1(String s);
}

 

package cn.javass.dp.simplefactory.example4;
/**
 * 对某个接口的一种实现 
 */
public class Impl implements Api{
    
    public void test1(String s) {
        System.out.println("Now In Impl. The input s=="+s);
    }
}
package cn.javass.dp.simplefactory.example4;
/**
 * 对接口的一种实现 
 */
public class Impl2 implements Api{
    
    public void test1(String s) {
        System.out.println("Now In Impl2. The input s=="+s);
    }
}

 

package cn.javass.dp.simplefactory.example4;

/**
 * 工厂类,用来创造Api的
 */
public class Factory {
    /**
     * 具体的创造Api的方法,根据客户端的参数来创建接口
     * @param type 客户端传入的选择创造接口的条件
     * @return 创造好的Api对象
     */
    public static Api createApi(int type){
        //这里的type也可以不由外部传入,而是直接读取配置文件来获取
        //为了把注意力放在模式本身上,这里就不去写读取配置文件的代码了
        
        //根据type来进行选择,当然这里的1和2应该做成常量
        Api api = null;
        if(type==1){
            api = new Impl();
        }else if(type==2){
            api = new Impl2();
        }
        return api;
    }
}

 

package cn.javass.dp.simplefactory.example4;
/**
 * 客户端:测试使用Api接口
 */
public class Client {
    public static void main(String[] args) {
        //重要改变,没有new Impl()了,取而代之Factory.createApi()
        //注意这里传递的参数,修改参数就可以修改行为,试试看吧
        Api api = Factory.createApi(2);
        api.test1("哈哈,不要紧张,只是个测试而已!");
    }
}

 上面这种存在一定的问题:

就是客户端在调用Api api = Factory.createApi(2);必须知道参数1 2 3的意思,可以采用下面的办法进行解决,我们通过配置文件来解决,这样客户端不需要内部的参数的意思了

 

我们在src目录下编写一个配置文件

FactoryTest.properties

ImplClass=cn.javass.dp.simplefactory.example5.Impl
package cn.javass.dp.simplefactory.example5;
import java.util.*;
import java.io.*;
/**
 * 工厂类,用来创造Api对象
 */
public class Factory {
    /**
     * 具体的创造Api的方法,根据配置文件的参数来创建接口
     * @return 创造好的Api对象
     */
    public static Api createApi(){
        //直接读取配置文件来获取需要创建实例的类
        
        //至于如何读取Properties还有如何反射这里就不解释了
        Properties p = new Properties(); 
        InputStream in = null;
        try {
            in = Factory.class.getResourceAsStream("FactoryTest.properties");
            p.load(in);
        } catch (IOException e) {
            System.out.println("装载工厂配置文件出错了,具体的堆栈信息如下:");
            e.printStackTrace();
        }finally{
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //用反射去创建,那些例外处理等完善的工作这里就不做了
        Api api = null;
        try {
            api = (Api)Class.forName(p.getProperty("ImplClass")).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return api;
    }
}

 

调用者就是不需要具体参数的意见了

package cn.javass.dp.simplefactory.example5;

/**
 * 客户端:测试使用Api接口
 */
public class Client {
    public static void main(String[] args) {
        //重要改变,没有new Impl()了,取而代之Factory.createApi()
        Api api = Factory.createApi();
        api.test1("哈哈,不要紧张,只是个测试而已!");
    }
}

 简单工厂的本质是:选择而不是实现,选择的参数可以来自客户端,也可以来自配置文件,通过参数来选择不同类型的实现,实现类的功能不能放在工厂中去实现,实现类应该提前就做好

public static Api createApi(int type){
        //这里的type也可以不由外部传入,而是直接读取配置文件来获取
        //为了把注意力放在模式本身上,这里就不去写读取配置文件的代码了
        
        //根据type来进行选择,当然这里的1和2应该做成常量
        Api api = null;
        if(type==1){
            api = new Impl();
        }else if(type==2){
            api = new Impl2();
        }
        return api;
    }

 

 不能把Impl的具体实现放在工厂类中是写,工厂类是依据参数来选择不同的实现类

 

补充三:

简单工厂的扩充

上面只提供了一个业务类

package cn.javass.dp.simplefactory.example4;
/**
 * 某个接口(通用的、抽象的、非具体的功能的) 
 */
public interface Api {
    /**
     * 某个具体的功能方法的定义,用test1来演示一下。
     * 这里的功能很简单,把传入的s打印输出即可 
     * @param s 任意想要打印输出的字符串
     */
    public void test1(String s);
}

 

如果还存在其他的业务操作,也可以采用下面的简单工厂来实现

 

posted on 2017-07-30 13:07  luzhouxiaoshuai  阅读(138)  评论(0编辑  收藏  举报

导航