一天一个设计模式:简单工厂模式

存在的目的:

  解耦,在a类中如何想使用b类的某种功能,必须new 一个b对象出来,假如有一个c类,跟b实现了同一个接口,后续想要将b替换成c就需要更改在a中的代码,以此类推,代码的耦合度会随着项目复杂度越来越高,维护成本也会越来越高。

  使用简单工厂,使a类与工厂做耦合,然后工厂来提供接口的实现类即可,这样只需要对工厂进行维护就可以实现替换了成功解耦。

 

核心思想:

  不在乎工厂是如何生产产品的,而是将产品的生产与产品的使用分开。
       注:这里的产品指的是功能类的对象

 

实际的应用:

  jdk中的线程池:ThreadPoolExecutor,根据自己的需求传入corePoolSize、maximumPoolSize、keepAliveTimem、keepAliveTimem、unit、threadFactory、handler这几个参数,new一个指定的ThreadPoolExecutor出来。

  jdk提供了Executors这个类,让开发者对线程池的使用与生产分离开,开发者只需要调用不同的方法就可以获取到不同的线程池,开发者不用关心线程池的实现细节,只需要调用api即可获取不同的线程池。

      如:Executors.newSingleThreadExecutor()        获取单线程的线程池
             Executors.newCachedThreadPool()        获取无界线程池

 

优点:
    简单优化了软件体系结构,明确了各自功能模块的职责和权力,
    通过工厂类,外界不需要直接创建具体产品对象,只需要负责消费,不需要关心内部如何创建对象。
缺点:
    如果只是使用简单的if else这样来做生产,随着产品的增多,势必要对工厂类进行不断的维护,
    使用反射的工厂效率会低一些。

实现案例

以登录系统为例,支持多种登录体系:口令登录、域登录。那么需要建立一个各种登录方式都适合的接口,uml图如下:

登录接口:

public interface Login {
    //登录验证
    public boolean verify(String name , String password);
}
View Code

域登录:

public class DomainLogin implements Login {

    @Override
    public boolean verify(String name, String password) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        return true;
    }

}
View Code

口令登录:

public class PasswordLogin implements Login {

    @Override
    public boolean verify(String name, String password) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        return true;
    }

}
View Code

工厂类LoginManager,根据需求创建对象,如果不合法就跑出异常,会返回一个Runtime异常

public class LoginManager {
    public static Login factory(String type){
        if(type.equals("password")){
            
            return new PasswordLogin();
            
        }else if(type.equals("passcode")){
            
            return new DomainLogin();
            
        }else{
            /**
             * 这里抛出一个自定义异常会更恰当
             */
            throw new RuntimeException("没有找到登录类型");
        }
    }
}
View Code

测试类:

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String loginType = "password";
        String name = "name";
        String password = "password";
        Login login = LoginManager.factory(loginType);
        boolean bool = login.verify(name, password);
        if (bool) {
            /**
             * 业务逻辑
             */
        } else {
            /**
             * 业务逻辑
             */
        }
    }
}
View Code

实际上的结构图:

基于上面的,使用反射来实现

public class LoginManager {
    public static Login factory(String path) {
        Class<?> c = Class.forName(fruitPath);
        return (Fruit)c.newInstance();
    }   
}

这样仅需要控制入参就可以获取对应的实例了,不需要那么多if else了结构上更加清爽。

 参考链接:

https://www.cnblogs.com/java-my-life/archive/2012/03/22/2412308.html

https://www.cnblogs.com/xrq730/p/4902597.html

posted @ 2018-10-25 11:05  萌新啊萌新是我  阅读(199)  评论(0编辑  收藏  举报