浅谈设计模式之简单工厂模式

设计模式:是指在软件开发中,经过验证的,用于解决在特定环境下、重复出现的、特定问题的解决方案。

简单工厂是一个简单而又神奇的设计模式,接下来我们进入正题。

面向接口编程是java编程中的一个重要原则,在java程序设计里面,非常讲究层的划分和模块的划分。通常按照三层来划分java程序,分别是表现层、逻辑层和数据层,他们之间都要通过接口来通信。在每一层里,又有很多的小模块,每一个模块对外则是一个整体,所以每一个模块对外都应该提供接口。其他地方需要使用此模块时,则调用这个模块的接口即可。

通过组件封装的面向接口编程:

首先定义接口

package com.itheima;

/**

 * @author hezhiyu

 *    定义接口:用于约束实现类的行为,相当于一份合同,约定了实现类应该要实现的功能

 */

public interface Api { 

      public void operation(String str);

}

实现类:

package com.itheima;

/**

 * @author hezhiyu

 */

public class ImplA implements Api{

  /* (non-Javadoc)

   * @see com.itheima.Api#test(java.lang.String)

   * 对接口的实现

   */

  @Override

  public void operation(String str) {

      System.out.println("ImplA:" + str);

  }

}

不同的实现类:

package com.itheima;

/**

 * @author hezhiyu

 */

public class ImplB implements Api{

    /* (non-Javadoc)

     * @see com.itheima.Api#test(java.lang.String)

     * 对接口的实现

     */

    @Override

    public void operation(Stringstr) {

        System.out.println("ImplB:" + str);

    }

}

客户端,按照java接口知识,接口是不能直接使用的,需要使用接口的实现类:

package com.itheima;

/**

 * @author hezhiyu

 *  客户端测试

 */

public class Client {

    public staticvoid main(String[] args) {

        Apiapia = new ImplA();

        Apiapib = new ImplB();

        apia.operation("林青霞来也");

        apib.operation("徐霞客来也");

    }

}

此时,弊端就体现出来了,客户端不但知道了接口,还知道了接口的实现类。接口的思想是“封装隔离”,也就是说客户端根本就不应该知道接口的实现类。

只知接口而不知实现,该怎么做呢?

简单工厂的定义:

        提供一个创建对象实例的功能,而无需关心其具体的实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。

使用简单工厂

                    

package com.itheima;

/**

 * @author hezhiyu

 */

public class Factory {

    /**

     * 创建具体Api对象 

     * @param type 客户端传入的选择创建接口的条件

     * @return Api

     */

    public static Api createApi(inttype){

        /*

         * 选择究竟哪一个具体的实现

         */

        Apiapi = null;

        if(type == 1){

            api = new ImplA();

        }elseif(type == 2){

            api = new ImplB();

        }

        return api;

    }

}

客户端没什么变化,只是在调用Factory的createApi方法时需要传入参数:

package com.itheima;

/**

 * @author hezhiyu

 *    客户端测试

 */

public class Client {

  public staticvoid main(String[] args) {

      Apiapi = Factory.createApi(1);

      api.operation("正在使用简单工厂");

  }

}

这种方法有一个缺点,就是从客户端在调用工厂模式的时候传入选择的参数,这就说明客户端必须知道每个参数的含义.这就向客户暴露一定的内部实现细节.

每次新增加一个实现类都来修改工厂类的实现,肯定不是一个好的实现方式.一个好的解决方法就是使用配置文件.当然也可以使用IoC/DI来实现,这个不在这里讨论.

package com.itheima;

 

import java.io.IOException;

import java.io.InputStream;

import java.util.Properties;

 

/**

 * @author hezhiyu

 *

 */

public class FactoryProperties {

  public static Api createApi(){

      //直接读取配置文件来获取需要创建实例的类,至于如何读取配置的,如何使用反射这里就不做解释了

      Propertiesp = new Properties();

      InputStreamin =null;

      in = FactoryProperties.class.getResourceAsStream("Factory.properties");

      try {

          p.load(in);

      }catch (IOException e) {

          System.out.println("装载工厂配置文件错误:");

          e.printStackTrace();

      }finally {

          try {

              in.close();

          }catch (IOException e) {

              e.printStackTrace();

          }

      }

      Apiapi = null;

      try {

          api = (Api) Class.forName(p.getProperty("Impl")).newInstance();

      }catch (InstantiationException e) {

          e.printStackTrace();

      }catch (IllegalAccessException e) {

          e.printStackTrace();

      }catch (ClassNotFoundException e) {

          e.printStackTrace();

      }

      returnapi;

  }

}

客户端测试:这样就不用写参数了

package com.itheima;

/**

 * @author hezhiyu

 *    客户端测试

 */

public class Client {

  public staticvoid main(String[] args) {

     Apiapi = FactoryProperties.createApi();

      api.operation("正在使用可配置的简单工厂");

  }

}

总结:

    简单工厂有以下优点:

    帮助封装

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

    解耦

        实现了客户端和具体实现类的解耦


猜你喜欢

转载自blog.csdn.net/qq_28524127/article/details/80111532
今日推荐