设计模式之简单工厂模式

简单工厂模式

首先实现一个计算器控制台程序。

public class Program {
    public static void main(String[] args) throws Exception{
        try {
            Scanner scanner = new Scanner(System.in);
            System.out.println("输入数字A:");
            BigDecimal a = scanner.nextBigDecimal();
            System.out.println("输入数字B:");
            BigDecimal b = scanner.nextBigDecimal();

            System.out.println("输入操作符");
            String s = scanner.next();

            switch (s) {
                case "+":
                    System.out.println(a.add(b));
                    break;
                case "-":
                    System.out.println(a.subtract(b));
                    break;

                case "*":
                    System.out.println(a.multiply(b));
                    break;

                case "/":
                    if (b != BigDecimal.valueOf(0)) {
                        System.out.println(a.divide(b));

                    } else {
                        System.out.println("除数不能为零");
                    }
                    break;
            }
        } catch (Exception e) {
            System.out.println("输入有误");
        }

    }
}

接下来我们对代码进行修改,将业务逻辑层和UI层分离:


/*
      业务逻辑层
      运算类
*/
public class Operation {
    public static BigDecimal getResult(BigDecimal numberA, BigDecimal numberB,
                                       String operate){
        switch (operate) {
            case "+":
                return numberA.add(numberB);
            case "-":
                return numberA.subtract(numberB);
            case "*":
                return numberA.multiply(numberB);
            case "/":
                if (numberB != BigDecimal.valueOf(0)) {
                    return numberA.divide(numberB);
                } else {
                    System.out.println("除数不能为零");
                }
        }
        return null;
    }
}
/*      
      UI层
      客户端代码
*/
public class Client {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入数字A:");
        BigDecimal a = scanner.nextBigDecimal();
        System.out.println("输入数字B:");
        BigDecimal b = scanner.nextBigDecimal();

        System.out.println("输入操作符");
        String s = scanner.next();

        System.out.println(Operation.getResult(a, b, s));

    }
}

然而上述代码没有很好的可扩展性,继续修改:

    //运算类
public class Operation {

        public  BigDecimal getResult(BigDecimal numberA, BigDecimal numberB){
            BigDecimal result = null;
            return result;
        }

}

public class Add extends Operation{

    public  BigDecimal getResult(BigDecimal numberA, BigDecimal numberB){
        return numberA.add(numberB);
    }
}

public class Subtract extends Operation{

    public  BigDecimal getResult(BigDecimal numberA, BigDecimal numberB){
        return numberA.subtract(numberB);
    }
}
public class Multiply extends Operation{
    public  BigDecimal getResult(BigDecimal numberA, BigDecimal numberB){
        return numberA.multiply(numberB);
    }
}
public class Divide extends Operation{
    public  BigDecimal getResult(BigDecimal numberA, BigDecimal numberB){
        return numberA.divide(numberB);
    }
}

将Operation作为基类,让其导出类都重写getResult()方法。这样我们在添加新的操作的时候只需要继承Operation类并重写getResult()方法就可以了。
接下来就是如何去实例化对象了,我们来写一个工厂类:

public class OperationFactory {
    public static Operation creatOperation(String operate) {
        Operation operation = null;

        switch (operate) {
            case "+":
                operation = new Add();
                break;
            case "-":
                operation = new Subtract();
                break;

            case "*":
                operation = new Multiply();
                break;

            case "/":
                operation = new Divide();
                break;
        }
        return operation;
    }
}

我们可以通过工厂创建任何我们想要的对象。

public class Client {
    public static void main(String[] args) {
        BigDecimal A = BigDecimal.valueOf(3);
        BigDecimal B = BigDecimal.valueOf(3);

        Operation operation;
        operation = OperationFactory.creatOperation("+");
        System.out.println(operation.getResult(A, B));

    }
}

当然,最让我们疑惑的是:上述客户端代码明明就可以直接用new创建Add类的对象,为什么多此一举的创建个工厂类再通过工厂创建对象呢?
原因是上面的例子太简单了,我们在创建Add()对象前要准备 BigDecimal A = BigDecimal.valueOf(3)和BigDecimal B = BigDecimal.valueOf(3)
如果我们要在实例化对象之前先读取某些配置,做各种各样的预备工作呢?也就是说在创建Add对象前要可能准备N多个 BigDecimal A = BigDecimal.valueOf(3)和BigDecimal B = BigDecimal.valueOf(3)难道要每创建一个Add对象就将这些代码都复制一遍吗?我们可以把创建对象前的预备工作放进工厂里,这样就可以做到复用了。

posted @ 2020-09-27 22:21  xxgbl  阅读(145)  评论(0)    收藏  举报