天天看点

大话设计模式系列——简单工厂模式总结

emmm......之所以写这个系列,是因为想去进阶,感觉写自己代码不够精简,亢沉臃肿;想写好写优雅写优秀,却不知道是不是优秀,模棱两可的感觉;想去入手源码,却不知道从拿下手,又或者说看不懂,为什么这么写。

所以想入手设计模式系列,当然这些理解或者示例代码是建立在《大话设计模式》——程杰著的基础之上的。感觉这本书还是值得推荐的_

仅属个人理解,如果有误,欢迎各位指正^_^

在未接触到设计模式之前,你的代码或许是这样的:

/**(模拟一个计算器的功能)*/
public class General {
    public static void main(String[] args) {
        //普通代码
        try {
            Scanner sc = new Scanner(System.in);
            System.out.println("输入数字A:");double strNumberA = sc.nextInt();
            System.out.println("输入数字B:");double strNumberB = sc.nextInt();
            System.out.println("输入运算符:");String opera = sc.next();
            String result = "";

            result = getResult(strNumberA, opera, strNumberB, result);
            if(Optional.ofNullable(result).isPresent()){//判断是否返回空,false为空
                System.out.println("您输出的结果为:"+result);
            }else{
                System.out.println("请输入正确的运算符");
            }
        }catch (Exception ex){
            System.out.println("您的输入有误"+ex.getMessage());
        }
    }

    public static String getResult(double strNumberA, String opera, double strNumberB, String result) {
        switch (opera){
            case "+":
                result = String.valueOf(strNumberA + strNumberB);
                break;
            case "-":
                result = String.valueOf(strNumberA - strNumberB);
                break;
            case "*":
                result = String.valueOf(strNumberA * strNumberB);
                break;
            case "/":
                result = String.valueOf(strNumberA / strNumberB);
                break;
            default:
                result = null;
                break;
        }
        return result;
    }
}
           

其实,乍一看这段代码也没什么问题,并且也运用到了面向对象三大特征——封装,而且也捕获了异常,按道理也挺完善了,但是,如果让你同时用到面向对象的三大特征呢?又或者说这个代码能否做到灵活的修改和扩展呢?

引入简单工厂模式(工厂模式细分为:简单工厂,工厂模式,抽象工厂)划重点

从以上代码你也可以看出,耦合性很高,每次拓展一个功能(比如我在增加个幂运算),都要在switch加一个分支,从而导致加减乘除运算都得重新编译,而且是在原写好的类上修改,极不利于维护和拓展。

而此时,如果你用到了简单工厂模式,就可以巧妙的避开这些。

优点:

  1. 解耦:调用方不用负责对象的创建,只需要使用,明确各自的职责;
  2. 维护方便:后期如果创建对象时需要修改代码,也只需要去工厂方法中修改,易拓展;

运用简单工厂模式改造的思路如下:

  1. 定义元数据类(抽象类,不需要实例,需要子类重写),运用到了封装;
  2. 具体实体类(加减乘除类)运用到了继承;
  3. 简单工厂类(选择传来的是加减乘除哪一个算法)运用到了多态。

具体代码实现:

  1. 定义元数据类:
public abstract class MetaData {
    private double numberA;
    private double numberB;
	//具体方法,需要子类去重写
    public abstract String getResult(double numberA,double numberB);
    get/set方法...
}
           
  1. 定义具体实现类:
    //加法
    public class MetaDataAdd extends  MetaData{
        public  String getResult(double numberA,double numberB){
            String result = String.valueOf(numberA + numberB);
            return  result;
        }
    }
               
    //减法
    public class MetaDataReduce extends  MetaData{
        public  String getResult(double numberA,double numberB){
            String result = String.valueOf(numberA - numberB);
            return  result;
        }
    }
               
    //乘法
    public class MetaDataMul extends  MetaData{
        public  String getResult(double numberA,double numberB){
            String result = String.valueOf(numberA * numberB);
            return  result;
        }
    }
               
    //除法
    public class MetaDataDivision extends  MetaData{
        public  String getResult(double numberA,double numberB){
            String result = String.valueOf(numberA / numberB);
            return  result;
        }
    }
               
  2. 简单工厂类
    public class MetaDataFactory {
        public static MetaData getAlgorithm(String operator){
            MetaData metaData = null;
            switch (operator){
                case "+":
                    metaData = new MetaDataAdd(); //多态的实现
                    break;
                case "-":
                    metaData = new MetaDataReduce();//多态的实现
                    break;
                case "*":
                    metaData = new MetaDataMul();//多态的实现
                    break;
                case "/":
                    metaData = new MetaDataDivision();//多态的实现
                    break;
                default:
                    metaData = null;
                    break;
            }
            return metaData;
        }
    }
               

总结

这样下来,如果你增加一个幂运算,直接在工厂类里面添加一个switch分支,在创建一个幂算法。而这样对于日后的维护和扩展会更加友好。

当然,简单工厂的缺点你或许也看出来了,而工厂方法模式刚好可以解决其缺点:工厂方法模式总结及与简单工厂的区别

继续阅读