java工厂模式1(简单工厂+工厂方法)
工厂模式负责将有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,而不必事先知道每次要实例化哪一个类,并且在创建对象时不会对客户端暴露创建逻辑,通过使用一个共同的接口来指向新创建的对象。
简单工厂模式
简单工厂模式主要是通过一个工厂类来实现对具体对象的创建,用户不需要知道创建对象的具体实现,它的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类,简单工厂模式不属于23中设计模式之一,它主要含有三中角色
- 工厂类角色:根据客户需求决定具体要创建哪个类的对象。
- 抽象产品角色:是具体产品继承的父类或者实现的接口。
- 具体的产品角色:产品的具体实现,由工厂类创建根据需求创建对象。
简单工厂模式的UML图如下
下面采用基本的运算举例:
第一步:创建抽象的计算类
public abstract class Operation {
public Operation(){}
/**
* 抽象的计算方法,具体实现放在子类中实现
* @return 计算结果
*/
public abstract double calculate(double number1,double number2);
}
第二步创建具体的计算类
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:加法计算
* Date:2017/11/27
* Time:16:58
*/
public class AddOperation extends Operation{
public AddOperation(){
super();
}
public double calculate(double number1 ,double number2) {
return number1 + number2;
}
}
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:减法计算
* Date:2017/11/27
* Time:17:00
*/
public class MinusOperation extends Operation {
public MinusOperation(){super();}
@Override
public double calculate(double number1, double number2) {
return number1 - number2;
}
}
第三步:创建工厂类
public class CalculatorFactory {
public static Operation createOperation(String opera ){
Operation operation = null;
switch (opera){
case "+":
operation = new AddOperation();
break;
case "-":
operation = new MinusOperation();
break;
}
return null;
}
}
第四步:测试
public class Test {
public static void main(String agrs[]){
/**
* 用户不用直接创建一个运算对象,
* 只需要通过工厂获取一个运算对象
* 运算对象的创建由计算的工厂实现
*/
Operation operation = CalculatorFactory.createOperation("+");
double result = operation.calculate(1 ,2);
System.out.print(result);
}
}
简单工厂模式有一定的优点比如:用户不需要直接创建对象,仅仅使用对象就可以了,还有假如,某个需求需要在计算加法前有一些其他的操作,如果我们在代码里多次使用了new 加法计算,我们就需要在代码里多次修改,但是使用了简单工厂模式只需要修改工厂类就可以了,在工厂类中的获取加法计算前添加我们的新需求。
不过简单工厂模式也有缺点,比如:现在系统原来的计算不能满足新的需求了,我们需要加一个乘法运算。我们就需要完成下面的一些操作:
第一步增加乘法计算
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:乘法计算
* Date:2017/11/28
* Time:9:38
*/
public class MultiplyOperation extends Operation{
public MultiplyOperation(){super();}
@Override
public double calculate(double number1, double number2) {
return number1 * number2;
}
}
第二部修改工厂类
public class CalculatorFactory {
public static Operation createOperation(String opera ){
Operation operation = null;
switch (opera){
case "+":
operation = new AddOperation();
break;
case "-":
operation = new MinusOperation();
break;
case "*"://增加乘法的逻辑
operation = new MultiplyOperation();
break;
}
return operation;
}
}
经过上面的修改,虽然达到了我们的需求,可以计算乘法了,但是这样修改违反了设计模式的开闭原则(对扩展开放,对修改关闭),在这里我们增加了乘法计算类(对扩展开放),但是我们修改了计算工厂类(违反对修改关闭),所以我们这样是违反了开闭原则的。所以简单工厂模式适用于工厂类创建对象的类型比较少的情况下,但是一般不建议使用。
工厂方法模式
工厂方法模式是简单工厂模式的延伸,它完全实现‘开闭原则’,实现了可扩展。可以应用于产品结果复杂的场合。在工厂方法模式中工厂类不再负责所有的对象的创建,它将具体创建产品的工作交给子类工厂去做。这个工厂类是一个抽象工厂角色,负责给出具体子类工厂必须实现的接口,而不是决定哪一个产品类应当被实例化这种细节,实例化产品细节应该放在子类工厂中。
在工厂方法模式中设计到的角色有以下几种:
工厂方法模式的用例图大致为:
1. 抽象工厂角色:是工厂方法模式的核心,规定了子类工厂必须实现的方法,在模式中创建对象的工厂都要实现这个接口
2. 具体工厂角色:实现了抽象工厂模式的接口,它含有具体创建产品的逻辑,何时创建产品由它决定。
3. 抽象产品角色:是具体产品继承的父类或者实现的接口。规定了产品的公共特性
4. 具体产品角色:继承自抽象产品角色,由具体工厂角色创建。
下面还是使用算数计算的例子:
第一步:创建抽象产品角色
public abstract class Operation {
public Operation(){}
/**
* 抽象的计算方法,具体实现放在子类中实现
* @return 计算结果
*/
public abstract double calculate(double number1,double number2);
}
第二步:创建具体的产品角色
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:加法计算
* Date:2017/11/27
* Time:16:58
*/
public class AddOperation extends Operation{
public AddOperation(){
super();
}
public double calculate(double number1 ,double number2) {
return number1 + number2;
}
}
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:减法计算
* Date:2017/11/27
* Time:17:00
*/
public class MinusOperation extends Operation {
public MinusOperation(){super();}
@Override
public double calculate(double number1, double number2) {
return number1 - number2;
}
}
第三部:创建抽象工厂角色
public interface CalculatorFactory {
/**
* 创建计算方式
* @return
*/
public Operation createOperation( );
}
第四步:创建具体的工厂角色
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:加法工厂
* Date:2017/11/28
* Time:11:06
*/
public class AddOperationFactory implements CalculatorFactory{
@Override
public Operation createOperation() {
//这里可以做一些其他的操作
return new AddOperation();
}
}
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:减法工厂
* Date:2017/11/28
* Time:11:07
*/
public class MinusOperationFactory implements CalculatorFactory {
@Override
public Operation createOperation() {
//这里可以做一些其他的操作
return new MinusOperation();
}
}
第五步:测试
public class Test {
public static void main(String agrs[]){
/**
* 用户不用直接创建一个运算对象,
* 只需要通过具体的工厂获取一个运算对象
* 运算对象的创建由具体的工厂实现
*/
CalculatorFactory add = new AddOperationFactory();
Operation operation = add.createOperation();
double result = operation.calculate(1 ,2);
System.out.print(result);
}
}
工厂模式方法中解决了简单工厂模式不符合开放封闭原则,假如我们现在需要增加一个乘法计算。只需要增加一个具体的乘法产品和乘法的工厂
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:乘法
* Date:2017/11/28
* Time:9:38
*/
public class MultiplyOperation extends Operation{
@Override
public double calculate(double number1, double number2) {
return number1 * number2;
}
}
/**
* Created by IntelliJ IDEA.
* User:hubin
* Description:乘法工厂
* Date:2017/11/28
* Time:14:26
*/
public class MultiplyOperationFactory implements CalculatorFactory {
@Override
public Operation createOperation() {
//这里可以做一些其他的操作
return new MultiplyOperation();
}
}
这样就不用修改原有的工厂,只需要增加一个乘法工厂就可以解决问题而不需要修改原来的代码,而且在创建计算对象采用相应的工厂创建,避免了直接new 对象的硬编码,便于修改。