一、简单工厂模式
1、定义
简单工厂模式属于创建型模式,又叫静态工厂方法(Static Factory Method)。简单工厂模式是由一个工厂类对象决定创建哪一种产品类的实例。
2、实现和角色
1) 实现:
简单工厂模式的实质是由一个工厂类的对象根据实际传入的参数,动态的决定创建哪一种产品类的实例。
2)角色:
工厂角色(Creator):简单工厂模式的核心,负责实现创建产品类的实例的内部逻辑。
抽象产品角色(Product):所有产品类共有的公共接口。
具体产品角色(Concrete Product):简单工厂模式的创建目标,所创建的对象是此角色的具体类的实例。
3、优缺点:
1)优点:工厂类根据客户传入的参数动态的创建相应的实例,使得客户端不再依赖具体的产品,解耦和。
2)缺点:工厂类实现了所有产品类的实例化逻辑,耦合度较高。当需要增加新的产品时,需要修改工厂类。
4、举例
1)UML图(UML图说明,祥见)
2)运算操作符,工厂类:OperateFactory, 抽象产品类:Operate,具体产品类NumberAdd等
/**
* 工厂角色
* 工厂类
*/
public class OperateFactory {
public static Operate createOperate(String operateStr){
Operate operate = null;
switch(operateStr){
case "+" :
operate = new NumberAdd();
break;
case "-":
operate = new NumberSub();
break;
case "*":
operate = new NumberMul();
break;
case "/":
operate = new NumberDiv();
break;
default:
break;
}
return operate;
}
}
抽象产品类
/**
* 抽象产品角色
*/
public class Operate {
double numberA;
double numberB;
public double getNumberA() {
return numberA;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
public double getResult(){
return 0d;
}
}
具体产品类:加法
/**
* 具体产品角色
* 加法类
*/
public class NumberAdd extends Operate {
@Override
public double getResult(){
double result = numberA + numberB;
return result;
}
}
减法:
/**
* 具体产品角色
* 减法类
*/
public class NumberSub extends Operate {
@Override
public double getResult(){
double result = numberA - numberB;
return result;
}
}
乘法:
/**
* 具体产品角色
* 乘法
*/
public class NumberMul extends Operate {
@Override
public double getResult(){
double result = numberA * numberB;
return result;
}
}
除法:
/**
* 具体产品类角色
* 除法
*/
public class NumberDiv extends Operate {
@Override
public double getResult(){
if(numberB == 0){
try {
throw new Exception("除数不能为0");
} catch (Exception e) {
e.printStackTrace();
}
return 0d;
}
double result = numberA / numberB;
return result;
}
}
从简单工厂模式可以看出,当需要增加新的运算时,如numberA+numberA/numberB,就需要修改工厂类,增加case语句,这违背了开闭原则。
二、工厂模式
工厂模式去掉了简单工厂模式中的静态方法,分为抽象工厂接口,以及多个具体工厂子类,这样分解了简单工厂模式中工厂类的压力,由不同的子类工厂创建实例对象。即工厂方法将实例化对象延迟到了子类。
二,四个角色:(后文引用http://blog.csdn.net/qq_28055429/article/details/51628921)
工厂接口:工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。在实际编程中,有时候也会使用一个抽象类来作为与调用者交互的接口,其本质上是一样的。
工厂实现:在编程中,工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。
产品接口:产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。
产品实现:实现产品接口的具体类,决定了产品在客户端中的具体行为。
三,优点:创建对象的接口,让子类去决定具体实例化的对象,把简单的内部逻辑判断移到了客户端代码。工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
四,理解:如下图,上面那个例子可这样改:
利用依赖倒置原则,把工厂类抽象出一个接口,里面只有一个创建抽象产品的方法,然后所有的要生成具体类的工厂去实现这个接口,这样:
一个简单工程模式的工厂类就变成了一个工厂抽象接口和多个具体生成对象的工厂,当我们需要增加例如M的N次方时,就不需要去修改原有的工厂类,只需要增加此功能的运算类和相应的工程类即可。如上图所示。
先构建工厂接口:
interface IFactory {
public Operate createOperation();
}
具体工厂类:AddFactory等
public class AddFactory implements IFactory {
@Override
public Operate createOperation() {
return new NumberAdd();
}
}
public class SubFactory implements IFactory {
@Override
public Operate createOperation() {
return new NumberSub();
}
}
public class MulFactory implements IFactory {
@Override
public Operate createOperation() {
return new NumberMul();
}
}
public class DivFactory implements IFactory {
@Override
public Operate createOperation() {
return new NumberDiv();
}
}
客户端:
public class Client {
public static void main(String[] args){
IFactory iFactory = new AddFactory();
Operate operate = iFactory.createOperation();
operate.setNumberA(1);
operate.setNumberB(2);
double result = operate.getResult();
System.out.print(result);
}
}
总结:
简单工厂模式是工厂类包含了必要的逻辑,根据传入的参数动态的决定需要实例化的类。这样由于新增加产品类时,就需要
修改工厂类,违反了开闭原则。
工厂模式避免了简单工厂模式的弊端,将实例化延迟到子类,新增加产品类时不需要修改工厂类,而是增加相应的工厂方法即
可。但实例化哪个类的逻辑却放到了客户端。