zoukankan      html  css  js  c++  java
  • 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);
    }

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

  • 相关阅读:
    系统架构技能之设计模式组合模式
    系统架构师基础到企业应用架构单机软件架构
    设计模式系列装饰模式
    设计模式系列命令模式
    设计模式系列外观模式
    设计模式系列原型模式
    设计模式系列代理模式
    设计模式系列桥接模式
    设计模式系列适配器模式
    设计模式系列享元模式
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7258885.html
Copyright © 2011-2022 走看看