Strategy Pattern(策略模式)

Strategy Pattern enables selecting an algorithm at runtime. 
In more detail, code receives run-time instructions as to which in a family of algorithms to use.

策略模式—— 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

策略模式:使得具有共性的一组算法独立于调用方。

隐喻(Metaphor):

在足球场上踢球时需要带一把扳手🔧去踢球,但是正真见到对方球员时感觉扳手没什么大用需要返回到休息室换成一个狼牙棒,也许一个人来来回回浪费不了多少人力物力但是如果整个球队这样做就太费力气了。
这时可以想象一个空间足够大可以随身携带的箱子里面放置足以满足整个球队需要的“工具“。在球场上根据对方的球员在身边的箱子里选择相应的工具这样整个操作更加灵活快捷!
**箱子的工具(共性:“应对”对方球员的工具) ===》 不同的算法**
**箱子 ===》 算法的组合场所**
**己方球员 ===》 算法的调用者**
**对方球员 ===》 客户端的不同请求**

设计原则:

  • 面向接口编程而非面向实现;
  • 使用组合而非继承;
  • 在系统之中找到一组具有共性的变化,将其独立出来;

好处:

在策略模式中,行为被定义为单独的接口和实现这些接口的特定类。
这样可以在行为与使用行为的类之间实现更好的解耦。
可以在不破坏使用行为的类的情况下更改行为,并且这些类可以通过更改所使用的特定实现在行为之间进行切换,而无需进行任何重大的代码更改。

例子:

例子代码实现:

1- interface: ShotMethod.java

package ink.openmind.pattern.strategypattern.demo03;

public interface ShotMethod {
	String shot();
}

2-Class: ManualSingleShotting.java

package ink.openmind.pattern.strategypattern.demo03;

public class ManualSingleShotting implements ShotMethod {

	@Override
	public String shot() {
		// TODO Auto-generated method stub
		String shotInfo = "🔫 射击方式:手动单点射击💥";
		return shotInfo;
	}

}

3-Class: ThreeRoundBurstShotting.java

package ink.openmind.pattern.strategypattern.demo03;

public class ThreeRoundBurstShotting implements ShotMethod {

	@Override
	public String shot() {
		// TODO Auto-generated method stub
		String shotInfo = "🔫 射击方式:三发点放射击💥💥💥";
		return shotInfo;
	}

}

4-Abstract Class: Gun.java

package ink.openmind.pattern.strategypattern.demo03;

public abstract class Gun {
	protected ShotMethod shotMethod;
	
	public abstract String originDisplay();

	public ShotMethod getShotMethod() {
		return shotMethod;
	}

	public void setShotMethod(ShotMethod shotMethod) {
		this.shotMethod = shotMethod;
	}
	
	public String performShot() {
		return this.shotMethod.shot();
	}	
}

5-Class: AWPSniperRifle.java

package ink.openmind.pattern.strategypattern.demo03;

public class AWPSniperRifle extends Gun{

	public AWPSniperRifle() {
		super.shotMethod = new ManualSingleShotting();
	}
	
	@Override
	public String originDisplay() {
		// TODO Auto-generated method stub
		String originInfo = "🥚 Made in UK(United Kingdom)";
		return originInfo;
	}

}

6-Class: M16A2Rifle.java

package ink.openmind.pattern.strategypattern.demo03;

public class M16A2Rifle extends Gun {

	public M16A2Rifle() {
		super.shotMethod = new ThreeRoundBurstShotting();
	}
	@Override
	public String originDisplay() {
		// TODO Auto-generated method stub
		String originInfo = "🥚 Made in USA(United States of America)";
		return originInfo;
	}

}

7-Class: Test.java

package ink.openmind.pattern.strategypattern.demo03;

public class Test {
	public static void main(String[] args) {
		M16A2Rifle m16 = new M16A2Rifle();
		// 初始射击方式
		System.out.println("M16A2 => " + m16.performShot());
		// 切换射击方式
		m16.setShotMethod(new ManualSingleShotting());
		// 更改之后的射击方式
		System.out.println("M16A2(切换射击方式之后) =>: " + m16.performShot());
		System.out.println("M16A2产地信息: " + m16.originDisplay());
		System.out.println("====================================");
		AWPSniperRifle awp = new AWPSniperRifle();
		// 初始射击方式
		System.out.println("AWP => " + awp.performShot());
		System.out.println("AWP产地信息:" + awp.originDisplay());
		
	}
}

// 输出
/*
M16A2 => 🔫 射击方式:三发点放射击💥💥💥
M16A2(切换射击方式之后) =>: 🔫 射击方式:手动单点射击💥
M16A2产地信息: 🥚 Made in USA(United States of America)
====================================
AWP => 🔫 射击方式:手动单点射击💥
AWP产地信息:🥚 Made in UK(United Kingdom)
*/

参考链接:
https://www.runoob.com/w3cnote/state-vs-strategy.html
https://zh.wikipedia.org/wiki/精密國際AWP狙擊步槍
https://en.wikipedia.org/wiki/Strategy_pattern

posted @ 2020-07-27 17:56  Felix_Openmind  阅读(323)  评论(0)    收藏  举报
*{cursor: url(https://files-cdn.cnblogs.com/files/morango/fish-cursor.ico),auto;}