设计模式(一):简单工厂
程序员文章站
2024-01-21 20:31:16
...
定义:
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
需求:
模拟一个计算器的实现,输入一个数,再输入加减乘中的一个运算符,再输入第二个数字,运算结果返回
简单实现:
public static void main(String args[]) {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入第一个数");
String strA = scanner.nextLine();
System.out.println("请输入符号");
String operator = scanner.nextLine();
System.out.println("请输入第二个数");
String strB = scanner.nextLine();
Integer numA = Integer.parseInt(strA);
Integer numB = Integer.parseInt(strB);
if (operator.equals("+"))
System.out.println("结果为:" + (numA + numB));
else if (operator.equals("-"))
System.out.println("结果为:" + (numA - numB));
else if (operator.equals("*"))
System.out.println("结果为:" + numA*numB);
else
System.out.println("请输入正确的符号");
} catch (Exception e) {
System.out.println("输入有误");
}
}
如上我们实现了一个简单的计算器功能。但是我们现在只有加减乘的功能,如果我们现在要添加一个除法功能,我们就要去修改我们的计算器,在if中添加分支,这就会导致我们的计算器经常需要修改,不符合我们的解耦思想。
改进
我们可以将其中判断的那部分抽离出来,这样以后有新的功能加进来,只需要改进我们的计算的代码,而不需要对我们的计算器进行修改。
public static void main(String args[]) {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入第一个数");
String strA = scanner.nextLine();
System.out.println("请输入符号");
String operator = scanner.nextLine();
System.out.println("请输入第二个数");
String strB = scanner.nextLine();
Integer numA = Integer.parseInt(strA);
Integer numB = Integer.parseInt(strB);
Integer result = CalculateFactory.calculate(numA, operator, numB);
if (null != result)
System.out.println("结果为:" + result);
else
System.out.println("输入有误");
} catch (Exception e) {
System.out.println("输入有误");
}
}
public class Calculate {
public static Integer calculate(Integer numA, String operator, Integer numB) {
if (operator.equals("+"))
return numA + numB;
else if (operator.equals("-"))
return numA - numB;
else if (operator.equals("*"))
return numA * numB;
else
return null;
}
}
这样我们假如需要添加一个计算就只需要在计算类中添加,就将计算的部分和计算器界面的部分分开来,相当于是完成了解耦。
抽象与多态,紧耦合和松耦合
假如说,我们在添加一个新的计算运算符时,不小心修改了其他的运算的运算比如将numA+numB改成了numA+numA,那么就会导致问题。(不要在这里觉得不回犯这种错误,事实上到了真正的项目中,逻辑并不会像这么简单)
同时,在我们工作的过程中,我们会碰到很多相似的类,实现了类似的功能,比如缓存,根据不同的情况选择用memcache或是ehcache。
在这里,大家都是计算类,不过有的是加法计算有的是减法计算。
我们将计算类抽象成为一个抽象类:
public abstract class Calculate {
protected Integer numA;
protected Integer numB;
public abstract Integer result();
}
接着定义各运算符的计算类
public class CalculateAdd extends Calculate {
@Override
public Integer result() {
return numA + numB;
}
}
public class CalculateMinus extends Calculate {
@Override
public Integer result() {
return numA - numB;
}
}
public class CalculateMulti extends Calculate {
@Override
public Integer result() {
return numA * numB;
}
}
根据运算符生产计算类的工厂类:
public class CalculateFactory {
public static Calculate getOpr(String operator) {
Calculate opr = null;
switch (operator) {
case "+":
opr = new CalculateAdd();
break;
case "-":
opr = new CalculateMinus();
break;
case "*":
opr = new CalculateMulti();
break;
}
return opr;
}
}
最后,改进我们的计算器:
public class OperatorDemo1 {
public static void main(String args[]) {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入第一个数");
String strA = scanner.nextLine();
System.out.println("请输入符号");
String operator = scanner.nextLine();
System.out.println("请输入第二个数");
String strB = scanner.nextLine();
Integer numA = Integer.parseInt(strA);
Integer numB = Integer.parseInt(strB);
Calculate calculate = CalculateFactory.getOpr(operator);
calculate.numA = numA;
calculate.numB = numB;
Integer result = calculate.result();
if (null != result)
System.out.println("结果为:" + result);
else
System.out.println("输入有误");
} catch (Exception e) {
System.out.println("输入有误");
}
}
}
优缺点:
优点
- 简单工厂模式实现了对责任的分割,提供了专门的工厂类用于创建对象。
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点
- 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
使用场景
- 工厂类负责创建的对象比较少。
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心。
下一篇: 微信支付的那些坑