设计模式之简单工厂模式
简单工厂模式
首先实现一个计算器控制台程序。
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对象就将这些代码都复制一遍吗?我们可以把创建对象前的预备工作放进工厂里,这样就可以做到复用了。

浙公网安备 33010602011771号