策略模式(Strategy)简介

一, 回顾简单工厂模式(SimpleFactory)

上一篇博文: http://blog.csdn.net/nvd11/article/details/41855937

还是用回那个计算器作例子.

用简单工厂模式实现的UML图是这样的:

客户端关键代码:

private void BtnClicked_btnDel(){
			int i = Integer.parseInt(tb_i.getText());
			int j = Integer.parseInt(tb_j.getText());
			
			Operation oper = OperationFactory.getOperationObj(i,j,"-");
			lblResult.setText("" + oper.getResult());
}

可见, 使用简单工厂后,  在客户端只知道算法是Operation的子类实现的,  但是不知道具体是哪个子类(OperationAdd 还是 OperationDel).

也就是将真正的业务子类对客户端隐藏了.

正专业的讲法就是把业务类封装起来.

但是, 在上面的例子中, 即使使用了简单工厂模式把业务类封装起来, 但是还是暴露了真正的算法(方法)名字  GetResult().

二,策略模式(Strategy)定义

所谓策略模式其实跟简单工厂模式在定义上有点类似, 只不过简单工厂封装的是业务类, 而策略模式封装了方法(算法),

也就讲令客户端无法知道真正的业务方法名字.

再简单点讲,

就是利用面向对象多态, 根据子类的不同而调用不同的重写方法.

对于上面计算器的例子.

我们移除OperationFactory类,   类似地, 添加1个叫做OperationContext的类, 它的作用有点类似与工厂类OperationFactory

Factory类:  工厂, 具有1个静态方法. 根据参数的不同返回不同的类的对象. 通常不实例化工厂类, 只调用其静态方法生成对象.

Context类:    具有非静态1个方法,  根据参数对象的不同调用相同(重写自同一超类)的方法. 客户端通常会实例化这个类.

上所提到的对象所属的类都是继承(或间接继承)自同1个超类.

三,具体代码

3.1 Operation 类

跟上次的例子变化不大, 加上了Set方法.

public abstract class Operation {
	private int i;
	private int j;
	
	public int getI(){
		return i;
	}
	
	public void setI(int i){
		this.i = i;
	}
	
	public void setJ(int j){
		this.j = j;
	}
	
	public int getJ(){
		return j;
	}
	
	public abstract int getResult();
}

3.2 OperationAdd 类

public class OperationAdd extends Operation{
	
	@Override
	public int getResult(){
		return this.getI() + this.getJ();
	}
}

3.3 OperationDel 类

public class OperationDel extends Operation{
	
	@Override
	public int getResult(){
		return this.getI() - this.getJ();
	}
}

3.3 OperationContext 类

public class OperationContext {
	private Operation oper;
	
	public OperationContext(Operation oper){
		this.oper = oper;
	}
	
	public int compute(int i, int j){
		oper.setI(i);
		oper.setJ(j); 
		return oper.getResult();
	}
}


可见它可以根据oper对象的不同, 而调用不同的同名方法,  这就是多态的基本特性!

3.5 客户端代码

	private void BtnClicked_btnDel(){
			int i = Integer.parseInt(tb_i.getText());
			int j = Integer.parseInt(tb_j.getText());
			
			Operation oper = new OperationDel();
			OperationContext context = new OperationContext(oper);
			
			
			lblResult.setText("" + context.compute(i,j));
	}

3.6 UML

 

四, 策略模式和简单工厂模式相结合

策略模式对客户端封装(隐藏)了 业务的具体方法,   也就是说上面例子中的客户端调用OperationContext类的compute方法来计算, 而不知道真正的方法是getResutl().

但是上面的客户端暴露了OperationDel类...

而简单工厂模式的好处就是可以封装具体业务类.

所以将两个模式结合就可以同时封装业务类和业务方法(算法).

简单修改下OperationContext:

package strategy.bizobj;

public class OperationContext {
	private Operation oper;
	
	public OperationContext(Operation oper){
		this.oper = oper;
	}
	
	//Simple Factory 
	public OperationContext(String symbol){
		switch(symbol){
		case "+": this.oper = new OperationAdd();
		case "-": this.oper = new OperationDel();
		}
	}
	
	public int compute(int i, int j){
		oper.setI(i);
		oper.setJ(j); 
		return oper.getResult();
	}
}

or

class OperationContext{
    private Operation operation;

    public OperationContext(String symbol){
        this.operation = OperationFactory.getOperation(symbol);
    }

    public int cal(int i, int j){
        return this.operation.getResult(i,j);
    }

}

class OperationFactory{
    public static Operation getOperation(String symbol){
        switch (symbol){
            case "+": return new OperationAdd();
            case "-": return new OperationDel();
        }
        return null;
    }
}

上面的Context类就是简单工厂模式和策略模式的集合了.

此时的客户端代码:

private void BtnClicked_btnDel(){
			int i = Integer.parseInt(tb_i.getText());
			int j = Integer.parseInt(tb_j.getText());
			
			OperationContext context = new OperationContext("-");
			lblResult.setText("" + context.compute(i,j));
}


相当简洁, 同时隐藏(封装)了业务类和业务方法.

 

 

扩展性同样很强大, 如果需要增加乘法button, 只需要增加1个乘法类, 以及修改简单工厂内的switch 代码.

                

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值