简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建
出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
相应的角色:
1. 抽象产品角色
2. 具体产品角色(实现抽象工厂角色,具体实现细节)
3. 工厂角色(用于生产具体角色)
代码:
首先是抽象产品,以计算操作为例
public abstract class MyOperation {
private BigDecimal number1;
private BigDecimal number2;
MyOperation(BigDecimal number1,BigDecimal number2){
this.number1 = number1;
this.number2 = number2;
}
public BigDecimal getNumber1() {
return number1;
}
public void setNumber1(BigDecimal number1) {
this.number1 = number1;
}
public BigDecimal getNumber2() {
return number2;
}
public void setNumber2(BigDecimal number2) {
this.number2 = number2;
}
public abstract BigDecimal getResult();
}
然后是四种具体产品的角色:
加法操作产品:
public class MyOperattionAdd extends MyOperation {
MyOperattionAdd(BigDecimal number1, BigDecimal number2) {
super(number1, number2);
}
public BigDecimal getResult() {
return this.getNumber1().add(this.getNumber1());
}
}
减法操作产品:
public class MyOperationSub extends MyOperation {
MyOperationSub(BigDecimal number1, BigDecimal number2) {
super(number1, number2);
}
public BigDecimal getResult() {
return this.getNumber1().subtract(this.getNumber2());
}
}
乘法操作产品:
public class MyOpreationMulti extends MyOperation {
MyOpreationMulti(BigDecimal number1, BigDecimal number2) {
super(number1, number2);
}
public BigDecimal getResult() {
return this.getNumber1().multiply(this.getNumber2());
}
}
除法操作产品:
public class MyOperationDivide extends MyOperation {
MyOperationDivide(BigDecimal number1, BigDecimal number2) {
super(number1, number2);
}
public BigDecimal getResult() {
return this.getNumber1().divide(this.getNumber2(),10,BigDecimal.ROUND_HALF_DOWN);
}
}
为了避免代码中有魔法值,我们增加一个产品类型的枚举:
public enum OperationType {
ADD,
SUB,
MULTI,
DIVIDE
;
}
工厂角色(使用了枚举):
/**
* 工厂角色
*/
public class OperationFactory {
public static MyOperation getOperation(OperationType operationType, BigDecimal number1,BigDecimal number2) throws Exception{
switch (operationType){
case ADD:
return new MyOperattionAdd(number1, number2);
case SUB:
return new MyOperationSub(number1,number2);
case MULTI:
return new MyOpreationMulti(number1,number2);
case DIVIDE:
return new MyOperationDivide(number1,number2);
default:
throw new Exception("NO this Opreation");
}
}
}
然后就是要测试了:
public class SimpleFactoryTest {
public static void main(String[] args) throws Exception {
// 初始化BigDecimal建议用String
BigDecimal number1 = new BigDecimal("2.8");
BigDecimal number2 = new BigDecimal("2.9");
add(number1,number2);
subtract(number1,number2);
multiply(number1, number2);
divide(number1,number2);
}
public static void add(BigDecimal number1,BigDecimal number2) throws Exception {
MyOperation add = OperationFactory.getOperation(OperationType.ADD, number1,number2);
BigDecimal result = add.getResult();
System.out.println("加法:"+result);
}
public static void subtract(BigDecimal number1,BigDecimal number2) throws Exception {
MyOperation sub = OperationFactory.getOperation(OperationType.SUB,number1,number2);
BigDecimal result = sub.getResult();
System.out.println("减法:"+result);
}
public static void multiply(BigDecimal number1,BigDecimal number2) throws Exception {
MyOperation multi = OperationFactory.getOperation(OperationType.MULTI,number1,number2);
BigDecimal result = multi.getResult();
System.out.println("乘法:"+result);
}
public static void divide(BigDecimal number1,BigDecimal number2) throws Exception {
MyOperation divide = OperationFactory.getOperation(OperationType.DIVIDE,number1,number2);
BigDecimal result = divide.getResult();
System.out.println("除法:"+result);
}
}
上面的代码就简单的实现了简单工厂模式
其实简单工厂就是把创建对象和操作对象进行解耦,创建对象的操作交给工厂,操作对象(调用方法)交给调用者,其实上面的测试代码的那些计算方法是可以抽取到一个类中,这样就更好的实现了封装。
简单工厂的优势:
1. 如果要生产新的产品,只要加新的产品类然后修改工厂的代码以及在枚举中加一个类型,改动代码的地方很少。实现了创建和操作解耦。
2. 操作只关心操作,不用关心如何去创建对象,体现了迪米特法则,工厂只需掌握如何创建对象的知识,调用者只需掌握如何操作的知识。
3. 抽象的工厂类的时候,符合依赖倒置和里氏替换原则
4. 工厂只创建对象,不做其他的事,体现了单一职责原则
缺陷:
1. 没有很好的符合开闭原则,在增加新产品后,还是需要改动代码。
2. 接口隔离原则这里也没有很好的体现,因为只有一个方法需要实现,并不涉及到接口的分割