今天我来教大家怎么从一个青铜的渣渣上黄金,我想说的是,策略很重要。如果你今天的段位仍然是青铜,那么你有必要看看我的策略。
首先我的得理解什么是策略,来先看一看维基百科
策略,指计策;谋略。一般是指:
有的时候策略能够决定你对线时的能力,能够帮助你取得胜利,举个简单的例子,有一个叫西门的直播专打剑姬,我们看他对线的时候基本上都是吊打对方,可是轮到我们自己玩的时候,基本上就会被对方吊打,这是为什么啦,手速和操作这是一方面,我觉得最重要的是策略,比方说对面选择一个德玛跟你对线。你如果第一件不出破甲攻,等到德玛黑切,反甲出来了,虐你基本就无压力。比如说对方选择现版本最流行的武器和你对线,如果你用不好W技能,那么你就会被武器吊打;
看了我上面的阐述,你一定以为我是在讲游戏,或者跟你们扯淡,其实不然,我今天要说的是模式与设计中的策略模式;言归正传,开始进入主题;
1.什么是策略模式?
策略模式就是根据不同的环境和条件去选择其对应的算法和策略来解决不同的问题;
2.为什么要使用策略模式?
在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择。这两种实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码将较复杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。
3.策略模式角色组成?
一般的,策略模式主要分为以下三个角色:
1. 环境角色(Context):持有一个策略类引用
2. 抽象策略(Strategy):定义了多个具体策略的公共接口,具体策略类中各种不同的算法以不同的方式实现这个接口;Context使用这些接口调用不同实现的算法。一般的,我们使用接口或抽象类实现。
3. 具体策略(ConcreteStrategy):实现抽象策略类中的相关的算法或操作。
4.场景举例:
今天我就要教大家怎么使用剑姬吊打各种上单型选手;
首先我们得有一个抽象策略,我们可以把他当成是一切策略的接口,不管是面对强势性上单瑞雯,武器,还是肉型上单大虫子,德玛。亦或者是全能型上单,鳄鱼,洛克。还是法师流上单,流浪,火女。还是非主流上单。。;我们都可以去选择其对应的策略来打败敌人;
/*/
* 上单策略接口
*/
public interface TpStrategr {
//得到我想要的上单策略
public void getTpStrategy();
}
有了这个万能上单接口,我们就需要去实现我们的具体策略了;首先给大家带来剑姬VS瑞雯,这两个上单最容易被大家拿来比较;
VS
public class FioraVsRivan implements TpStrategr{
/*/
* (non-Javadoc)
* 剑姬打瑞雯的策略如下,打不过就是你的问题了
*/
@Override
public void getTpStrategy() {
System.out.println("锐雯是个高机动英雄,对抗她最好是以逸待劳,"
+ "锐雯的招牌技能是q三段击飞和w眩晕,新版剑姬w正好可以招架控制技能,当他突进过来,"
+ "用w招架锐雯的w,切记不要过早交掉招架而被吊打,q不要主动突进过去,尽量等他突击"
+ "到你身边来,因为如果对不过,q还可以帮你逃生,前期尽量别和他硬拼,到6以后跑过去"
+ "挑衅,他开大立刻q反响突进,等他大招时间到了你就可以和他贴脸站撸了,注意补刀,打"
+ "消耗他对不过你,如果硬拼吃力,大一波换血后跑回去补血,切记不要打的太激进,新版剑姬续航防御和机"
+ "动性显著加强,相对的,剑姬的爆发被削弱,所以对抗锐雯这类高爆发英雄,消耗战才是好的打法");
}
}
一个策略不能代表什么,接下来给大家带来剑姬吊打诺手的策略;
public class FioraVsNuoke implements TpStrategr{
/*/
* 剑姬吊打诺手的策略
*
*/
@Override
public void getTpStrategy() {
System.out.println("一级学q,等他身上出你这边方向的弱点就走过去,"
+ "他开q出圈圈你就q进去,吃他内圈q。q到他的弱点你会加速的,一直找弱点a。"
+ "他开w的时候就是斧子突然发红光的时候秒按w。如果手速不够,就qaea一下马上开w。"
+ "如果挡了他的w,就继续拼,拼到死。如果他没用w,你有加速的,往回走,他被你w减速了只能勾你。"
+ "然而你qcd马上好了,q出来就行了。打诺手出半肉,不然是打不过的。");
}
}
好了,有了抽象策略和具体策略之后,接下来就需要我们的环境了。
现在我们来到了召唤师峡谷,进入选人画面,并且根据选择的敌人找到对应的策略;
/*/
* 策略环境
*/
public class TpContext {
//持有一个具体策略的对象
private TpStrategr tpStrategr;
/**
* 构造函数,传入一个具体策略对象
* @param strategy 具体策略对象
*/
public TpContext(TpStrategr tpStrategr) {
super();
this.tpStrategr = tpStrategr;
}
/**
* 策略方法
*/
public void contextInterface(){
tpStrategr.getTpStrategy();
}
}
接下来到客户端环境执行以下;
public static void main(String[] args) {
TpStrategr strategr=new FioraVsNuoke();
TpContext context=new TpContext(strategr);
context.contextInterface();
}
策略环境会根据我们所传入的具体策略来执行所对应的方法;
5.疑点?
策略模式和状态模式有什么不同?
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单化。
上面的解释太过于抽象了,我们来具体分析下,策略模式是我们的客户端知道我要使用哪种策略然后才去构造出其对应的策略类,但是我们的服务端是不知道的,我们的服务端会给你很多策略,让你去选择;而状态模式,就是我们的客户端对一个事物的状态转换时间与顺序并不是很清楚才会发生的。
所以区别一就出来了,即策略模式客户端会很清楚我们在哪种情况下使用哪种策略;而状态模式是不清楚我在上面情况下转换哪种状态,这种状态也有可能是随机的;
区别二:当我们在召唤师峡谷都选好了英雄的时候,其对应的策略也都会执行,那么我们的策略会发生变化吗?答案是肯定不会的,比如我选择了剑姬,敌方选择了瑞雯。那么在我们进入召唤师峡谷的时候就已经选择了其对应的策略;
相反,我们的状态是随时随地都可能发生改变。互相切换的;
如何动态的去创建我们的具体策略对象?
我们可以使用工厂模式;根据我们的客户端所配置的数据不同,去选择对应的策略;
@Service("backContextImpl")
public class BackContextImpl implements ApplicationContextAware {
private ApplicationContext applicationContext;//上下文对象
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
/**
* @param beanName beanName
*/
public Object getServiceInstance(String beanName) throws Exception{
Object bean = applicationContext.getBean(beanName);
return bean;
}
}