概述
今天就要来说说工厂模式了。
工厂负责将大量有共同接口的类实例化。工厂模式可以决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。
工厂模式的使用有很多种,简单工厂(静态工厂),工厂方法,抽象工厂,工厂+策略。
今天我会一一阐述。
1,简单工厂
/**
* 简单工厂模式的基类
*/
public
class Operation {
private double numberA;//算法的第一个值
private 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;
}
/**运算结果调用该方法
* @return 简单工厂处理加减乘除的运算,返回相应的结果
*/
public double getResult(){
return 0;
}
}
这是简单工厂模式的基类,一切拓展或者需要处理的类都要依赖于它。
/**
* 加法
*/
public class OperationAdd extends Operation {
/**重写算法结果
* @return
*/
@Override
public double getResult() {
return getNumberA()+getNumberB();
}
}
/**
* 减法
*/
public class OperationSub extends Operation {
/**重写算法结果
* @return
*/
@Override
public double getResult() {
return getNumberA()-getNumberB();
}
}
/**
* 乘法
*/
public class OperationMul extends Operation {
/**重写算法结果
* @return
*/
@Override
public double getResult() {
return getNumberA()*getNumberB();
}
}
/**
* 除法
*/
public class OperationDiv extends Operation {
/**重写算法结果
* @return
*/
@Override
public double getResult() {
if(getNumberB()==0)return 0;
return getNumberA()/getNumberB();
}
}
加减乘除是四个类,我只是统一写在代码块里面,并不代表这四个类在一起。
加减乘除这四个类都继承了简单工厂的基类。也就是拥有两个参数的get/set方法和运算结果方法的Operation类。
/**
* 具体操作工厂的类
*/
public class OperationFactory {
public static Operation createOperation(String operate) {
Operation operation;
switch (operate) {
case "+":
operation = new OperationAdd();
break;
case "-":
operation = new OperationSub();
break;
case "*":
operation = new OperationMul();
break;
case "/":
operation = new OperationDiv();
break;
default:
operation = null;
break;
}
return operation;
}
}
这个类的作用就是处理逻辑。根据用户输入的符号(+-*/)来处理相对应的逻辑。
/**
* 简单工厂模式的测试类
*/
public class OperationTest {
/**简单工厂模式说明:
* 一个总代理类,
* 确定好参数,传入,传出。
* 确定好使用到的方法,以便子类重写
*
* 所有实现具体算法的类都要继承这个代理类
* 内部实现具体的算法
* 按照设计模式的四大原则,必须实现父类的全部方法
*
* 提供一个供外部调用的类
* 外部传入参数,这个类根据参数的不同获取不懂的算法,得到不懂的结果
* 而方法的多少是根据之前写好的实现类而定
* */
private Operation operation;
public void testAdd() {//+
operation = OperationFactory.createOperation("+");
operation.setNumberA(1);
operation.setNumberB(2);
Log.e("test", "简单工厂模式运算结果(+):" + operation.getResult());
}
public void testDiv() {///
operation = OperationFactory.createOperation("/");
operation.setNumberA(1);
operation.setNumberB(2);
Log.e("test", "简单工厂模式运算结果(/):" + operation.getResult());
}
public void testMul() {//*
operation = OperationFactory.createOperation("*");
operation.setNumberA(1);
operation.setNumberB(2);
Log.e("test", "简单工厂模式运算结果(*):" + operation.getResult());
}
public void testSub() {//-
operation = OperationFactory.createOperation("-");
operation.setNumberA(1);
operation.setNumberB(2);
Log.e("test", "简单工厂模式运算结果(-):" + operation.getResult());
}
}
根据这个加减乘除的小栗子可以看出简单工厂模式的好处。
如果不用简单工厂模式,那么你需要实现四个逻辑,重复大量代码。后期的拓展和维护都不好做。
而是用简单工厂模式处理后的代码可以看出,逻辑清晰。若想要增加某个新功能,比如模运算,那么我们只需要新建一个OperationMi类添加如下代码:
/**
* 模运算
*/
public class OperationMi extends Operation {
/**重写算法结果
* @return
*/
@Override
public double getResult() {
return getNumberA()%getNumberB();
}
}
这样,“新功能”写完了。新功能没有影响原来的任何一个功能也没有使工厂的基类改变。
而是用新功能则只需要在Operation里的switch方法中加入:
case "%":
operation = new OperationMi();
break;
怎么样?是不是拓展性很好,而且遵循了设计模式的“最少知道原则”。
类于类之间根本没有互相通讯
这就是简单工厂或者叫静态工厂模式。写起来很简单,使用起来很方便的一个设计模式。
不过,这种设计模式也有它的缺点在里面。也常常被否定为经典24种设计模式中的一种。
它的缺点就是没有遵循“开闭原则”。对拓展开放做到了,但是没有对修改关闭。
每当添加一种工厂的时候就要在OperationFactory类中createOperation方法中添加一个case方法。
这就已经修改了代码。所以,简单工厂模式应该不符合设计模式的“要求”。
那么,简单工厂还可以进一步的进行优化。
接下来的代码是把简单工厂和策略模式混合运用。算是对简单工厂的用法进一步的优化。
2,简单工厂+策略
借用简单工厂的代码,并加以稍微的修改:
将简单工厂的基类换成策略模式的基类。
/*
* 策略模式的基类
*/
public abstract class Strategy {
/**定义所有支持算法的公共接口*/
private double numberA;//算法的第一个值
private 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 abstract double GetResultInterface(double a,double b);
}
可以看出,它是一个抽象类。
修改操作简单工厂的类为:
public class ConcreteStrategy {
/**策略模式+简单工厂模式
* 相当于用策略模式把工厂模式的调用方法简化
* 传入相应的值,就会得到相应的方法。
* 获得该算法以后
* 通过公用的接口得到算法结果或者自定义的想要的结果
* */
private Strategy strategy;
/**
* 初始化传入具体的策略对象
*
* @param i 算法要求:加减乘除
*/
public ConcreteStrategy(String i) {
switch (i) {
default:
case "+":
strategy=new ConcreteStrategyA("+");
break;
case "-":
strategy=new ConcreteStrategyB("-");
break;
case "*":
strategy=new ConcreteStrategyC("*");
break;
case "/":
strategy=new ConcreteStrategyD("/");
break;
}
}
/**
* 上下文的接口,根据具体的策略对象调用其算法方法
*/
public void contextInterface(double a,double b) {
strategy.GetResultInterface(a,b);
}
}
算法逻辑实现类
/*
*加法类
*/
public class ConcreteStrategyA extends Strategy {
private String status;
public ConcreteStrategyA(String status) {
this.status= status;
}
/**
* 算法A的实现
*/
@Override
public double GetResultInterface(double a,double b) {
if(status.equals("+"))
return a+b;
return 0;
}
}
接下来是策略的具体实现类:
public class StrategyTest {
private ConcreteStrategy concreteStrategy;
/**选择计算模式
* @param i
*/
public void StrategyTest(String i) {
concreteStrategy = new ConcreteStrategy(i);
}
/**输入金额
* @param money
*/
public void getResult(double a,double b) {
concreteStrategy.contextInterface(a,b);
}
}
简单工厂+策略模式能够让简单工厂更加的灵活。不需要创建和实例化多个类。想要得到一个结果只需要new出一个ConcreteStrategy对象,传入想到对应的计算模式,再调用contextInterface方法,传入需要计算的值就可以得到想要的结果。
我们来比较一下:
简单工厂
operation = OperationFactory.createOperation("-");
operation.setNumberA(1);
operation.setNumberB(2);
operation.getResult();//得到结果
简单工厂+策略
concreteStrategy = new ConcreteStrategy("+");
concreteStrategy.contextInterface(1,2);//得到结果
通过代码就一目了然。
简单工厂+策略模式的代码比单纯的简单工厂模式要简单的很多。
这就是通过模式的组合运用来达到简化代码的方式。
那么,接下来这种工厂就能够弥补简单工厂的缺点。
3,工厂方法模式
借用
上面简单工厂的代码接着写
首先写一个工厂方法类的接口
public interface IFactory {
//创建工厂的抽象类
Operation createOperation();
}
再来写一个运算法则的具体工厂类
* 算法加减乘除
*/
public class ConcreteFactoryA implements IFactory {
//加法类工厂
@Override
public Operation createOperation() {
return new OperationAdd();
}
}
public class ConcreteFactoryB implements IFactory {
//减法类工厂
@Override
public Operation createOperation() {
return new OperationSub();
}
}
public class ConcreteFactoryC implements IFactory {
//乘法类工厂
@Override
public Operation createOperation() {
return new OperationMul();
}
}
public class ConcreteFactoryD implements IFactory {
//除法类工厂
@Override
public Operation createOperation() {
return new OperationDiv();
}
}
加上上面简单工厂的基类Operation和逻辑类OperationAdd等
就组成了工厂方法类。
使用方法:
private void testAdd() {
IFactory iFactory = new ConcreteFactoryA();//实例化工厂加法
Operation operation = iFactory.createOperation();//获得加法逻辑类的实例
operation.setNumberA(1);
operation.setNumberB(2);
operation.getResult();
}
这样一来。添加逻辑类就添加:
public class OperationMi extends Operation {
/**重写算法结果
* @return
*/
@Override
public double getResult() {
return getNumberA()%getNumberB();
}
}
再添加模运算的工厂类:
public class ConcreteFactoryE implements IFactory {
//加法类工厂
@Override
public Operation createOperation() {
return new OperationMi();
}
}
这样看起来是不是就成就了两个设计模式的原则。“最少知道原则”和“开闭原则”。
“最少知道原则”在简单工厂里就已经实现了。而“开闭原则”则利用工厂接口和工厂类实现了。
这样,即便最后添加了新的逻辑运算也不用去修改代码,而是相对应的添加一个新逻辑的具体工厂类。
工厂方法模式是定义一个用于创建对iangd接口让子类去决定实例化哪一个类。
当然,看懂了“简单工厂+策略模式”的程序员们也自然能够做出“工厂方法+策略”的组合代码。
通常在面对较大改动。需要添加很多的工厂以及方法类的时候,显然我们不可能一个方法一个类的去添加。
这时候 我们就需要一种更加简单方便的方法。
3,抽象工厂模式
因为抽象工厂的实现比较麻烦,代码量比较多,所以特意拿出一章来写抽象工厂。
需要看抽象工厂的程序员们可以看我的下一篇连载。
Android 内功心法(1.2.1)——android常用设计模式之工厂模式后续抽象工厂模式
最后
以上就是瘦瘦百褶裙为你收集整理的常用设计模式之工厂模式的全部内容,希望文章能够帮你解决常用设计模式之工厂模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复