设计模式-策略模式

一、策略模式的核心思想

策略模式定义了一系列的算法,并将每一个算法封装起来,使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。

策略模式将一系列的算法包装为一个接口抽象类的子类,并由调用者决定调用某一个子类。其中定义了3种角色。

  • 策略接口类ICaculator:为各种策略具体类定义了统一的计算器接口。
  • 具体策略类:它们都实现了策略接口类ICaculator,以得到同样的策略接口函数,并继承了抽象类 AbstractCalculator,可以拥有共同的辅助函数。
  • 策略抽象类 AbstractCalculator:为各种策略具体类定义公用的辅助函数;当然如果没有公用函数时,可以不需要该抽象类。

其结构图如下所示

在这里插入图片描述
下面来看具体的实现。

(1) 策略接口ICaculator.java用来定义一个计算策略的接口,calculate(的输入参数为一个加、减、乘、除的计算表达式,例如:

12+3       //加法样例
10-4       //减法样例
8*9        //乘法样例
9/3        //除法样例

其源代码如下程序所示。

package behavior.strategy;

/**
* @author Minggg
* 计算器接口类
*/
public interface ICalculator {

	/**
	* 计算表达式接口
	* @param expression 待计算的表达式
	* @retumn 计算结果
	*/
	public int calculate(String expression);

}

(2) 根据以上简单表达式的特点,它们均包含了两个数字和一个运算符号,在进行计算之前都需要将它们拆分出来,因此我们可以在策略抽象类 AtstractCalculator.java中定义一个拆分表达式的公用函数,它将 expression 表达式按照运算符 deliString 拆分为一个整型数组。其源代码如下程序所示。

package behavior.strategy;

/**
* @author Minggg
* 计算器抽象类
*/
public abstract class AbstractCalculator {

	/**
	* 根据计算表达式,提取待计算的数值
	* @param expression 计算表达式
	* @param deliString 分隔符
	* @return 待计算数值的数组
	*/
	public int[] split(String expression, String deliString) {
		String[] array= expression.split(deliString);
		int[] arrayInt= new int[2];
		arrayInt[0]= Integer,parseInt(array[0]);
		arrayInt{1]= Integer.parselnt(array[1]);
		return arrayInt;
	}

}

(3) 加法策略类 Plus.java用来进行加法运算,它继承了策略抽象类AtstractCalculator.java,从而能够调用 split()函数取得加法的两个数值,并实现了策略接口ICaculator.java,在 calculate()中计算两个数字的和。其源代码如下程序所示。

package behavior.strategy;

/**
* @author Minggg
* 加法计算类
*/
public class Plus extends AbstractCalculator implements ICalculator {

	public int calculate(String expression){
		int[] arrayInt= split(expression, "\\+");
		return arrayInt[0]+ arrayInt[1];
	}

}

(4) 减法策略类 Minus.java 用来进行减法运算,它继承了策略抽象类 AtstractCalculator.java,从而能够调用 split()函数取得减法的两个数值,并实现了策略接口ICaculator.java,在calculate()中计算两个数字的差。其源代码如下程序所示。

package behavior.strategy;

/**
* @author Minggg
* 减法计算类
*/
public class Minus extends AbstractCalculator implements ICalculator {

	public int calculate(String expression){
		int[] arrayInt= split(expression, "-");
		return arrayInt[0] - arrayInt[1];
	}

}

(5) 乘法策略类 Multiply.java用来进行乘法运算,它继承了策略抽象类 AbstractCalculator.java,从而能够调用 splitO)函数取得乘法的两个数值,并实现了策略接口ICaculator.java,在 calculate()中计算两个数字的积。其源代码如下程序所示。

package behavior.strategy;

/**
* @author Minggg
* 乘法计算类
*/
public class Multiply extends AbstractCalculator implements ICalculator {

	public int calculate(String expression){
		int[] arrayInt= split(expression, "\\*");
		return arrayInt[0] * arrayInt[1];
	}

}

(6) 除法策略类 Devide.java用来进行除法运算,它继承了策略抽象类 AtstractCalculator.java,从而能够调用 split()函数取得除法的两个数值,并实现了策略接口ICaculator.java,在 calculate()中计算两个数字的商。其源代码如下程序所示。

package behavior.strategy;

/**
* @author Minggg
* 除法计算类
*/
public class Devide extends AbstractCalculator implements ICalculator {

	public int calculate(String expression){
		int[] arrayInt= split(expression, "/");
		return arrayInt[0] / arrayInt[1];
	}

}

(7) 默认策略类 Default.iava 用来进行加法、减法、乘法、除法之外的表达式运算,它继承了策略抽象类 AtstractCalculator.java,并实现了策略接口ICaculator.java,在 calculate()中直接返回 0。其源代码如下程序所示。

package behavior.strategy;

/**
* @author Minggg
* 默认计算类
*/
public class Default extends AbstractCalculator implements ICalculator {

	public int calculate(String expression){
		return 0;
	}

}

使用以上策略类的方法很简单,只需要创建ICalculator 的各种策略实现,根据表达式的不同选用不同的策略类。为了测试,我们编写一个从控制台接收用户输入表达式的程序。其源代码如下程序所示。

package behavior.strategy;


public class Test {

	public static void main(String[] args) {
		while (true){
			// 接收表达式输入
			System.out.println("准备输入:");
			String expression = System.console().readLine();
			
			// 初始化实例
			ICalculator calculator;
			if (expression.indexOf"+")!=-1){
				calculator = new Plus();
			} else if (expression.indexOf"-")!= -1){
				calculator = new Minus();
			} else if (expression.indexOf("*")!= -1){
				calculator = new Multiply();
			} else if (expression.indexOf"/") !=-1){
				calculator = new Devide();
			}  else {
				calculator = new Default();
			}

			// 开始运算
			int value = calculator.calculate(expression);
			System.out.println("="+value);
		}
	}

}

二、何时使用策略模式

策略模式是一个提倡“针对接口编程”的模式,而使用接口的目的是为了统一标准或着说是制定一种强行的规定。策略模式的使用是由用户发起的,根据用户的操作决定使用什么具体的策略角色。策略模式仅仅封装算法,提供新的算法加入到已有系统和算法间的相互替换,以及方便老算法从系统中“退休”。策略模式并不决定在何时使用何种算法,因为使用何种算法决定权在用户,也就是说我们需要调用策略模式中定义好的算法方法之前,必须选择一种具体的策略算法。

因此,策略模式的应用也十分广泛。根据策略模式的特点,它通常应用在算法决策系统中,它提供对不同算法的封装,外部系统只需要决定调用哪一种策略。

三、Java 中的应用–AWT 布局管理器

为了实现跨平台的特性并且获得动态的布局效果,Java 将容器内的所有组件安排给一个“布局管理器”负责管理,如排列顺序、组件的大小、位置。当窗口移动或调整大小后组件如何变化等功能授权给对应的容器布局管理器来管理,不同的布局管理器使用不同的算法和策略,容器可以通过选择不同的布局管理器来决定布局。

AWT提供了下面的布局管理器(全部在java.awt包中,“*”表示接口):
在这里插入图片描述
它们使用了策略模式,其中的 LayoutManager 是顶层的策略接口,LayoutManager2 是扩展的策略接口,具体的实现类都是策略类,如下图所示。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值