编程是一门技术,更是一门艺术
简单工厂模式简介
简单工厂模式在于工厂类中包含了必要逻辑判断,根据客户端的选择动态实例化相关的类,对于客户端来说去除了与具体产品相关的依赖。实现一个计算器使用简单工厂模式下,需要在工厂类中进行逻辑的判断,是加法返回Add实例,减法返回Sub实例。但是这时候我添加新的计算的时候,首先创建一个对应类继承运算父接口,然后需要修改工厂类中的逻辑。这时简单工厂模式的应用。
/**
* 运算类的父类,每添加一个运算类需要继承该类,并且重写getResult方法
* @author colin
*
*/
public class Operation {
private double num1;
private double num2;
public double getNum1() {
return num1;
}
public void setNum1(double num1) {
this.num1 = num1;
}
public double getNum2() {
return num2;
}
public void setNum2(double num2) {
this.num2 = num2;
}
public double getResult() {
double result = 0;
return result;
}
}
/**
* 运算子类,需要实现父类,重写getResult方法实现对应的逻辑运算
* @author colin
*
*/
public class Div extends Operation {
@Override
public double getResult() {
double result = 0;
try {
result = getNum1()/getNum2();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
/**
* 工厂类,对传递进来的运算符进行判断,返回对应的实例
* @author colin
*
*/
public class OperationFactory {
public static Operation getOperation(String operate){
Operation ope = null;
if("+".equals(operate))
ope = new Add();
else if("-".equals(operate))
ope = new Sub();
else if("*".equals(operate))
ope = new Mul();
else if("/".equals(operate))
ope = new Div();
return ope;
}
}
/**
* 客户端直接输入数字及运算符返回对应的结果
* @author colin
*
*/
public class Client {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("please input num1");
double num1 = sc.nextDouble();
System.out.println("please input operate");
String operate = sc.next();
System.out.println("please input num2");
double num2 = sc.nextDouble();
Operation ope = OperationFactory.getOperation(operate);
ope.setNum1(num1);
ope.setNum2(num2);
System.out.println("result:"+ope.getResult());
}
}
工厂模式
简单工厂模式的问题在于,如果我添加新的功能需要修改工厂类,这样不仅对扩展开放了而且对修改开放了,这样就违背了开放-封闭原则了。而工厂模式就是定义一个接口,让子类决定实例化哪一个类。工厂方法将使一个类的实例化延迟到子类。
/**
* 定义创建对象的接口,让子类决定实例化哪一个类
* @author colin
*
*/
public interface IFactory {
public Operation createOperation();
}
/**
* 新添加的方法还是只需继承父操作类
* @author colin
*
*/
public class Mul extends Operation {
@Override
public double getResult() {
double result = 0;
result = getNum1()*getNum2();
return result;
}
}
/**
* 子类工厂方法,这样每次添加新功能,只需要添加子类工厂就行
* @author colin
*
*/
public class MulFactory implements IFactory{
@Override
public Operation createOperation() {
return new Mul();
}
}
/**
* 客户端直接输入数字及运算符返回对应的结果,这里决定使用哪一个子类工厂,所以其实逻辑判断移到客户端了
* @author colin
*
*/
public class Client {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("please input num1");
double num1 = sc.nextDouble();
System.out.println("please input operate");
String operate = sc.next();
System.out.println("please input num2");
double num2 = sc.nextDouble();
//Operation ope = OperationFactory.getOperation(operate);
IFactory factory = new MulFactory();
Operation ope = factory.createOperation();
ope.setNum1(num1);
ope.setNum2(num2);
System.out.println("result:"+ope.getResult());
}
}
这样整个工厂和产品就只有扩展变化,没有修改变化了,符合了开放-封闭原则。
工厂模式就是克服了简单工厂模式的开放-封闭原则的缺点,保留了封装对象创建过程的优点。
明天在继续抽象工厂模式的干活吧!!!