策略模式(Strategy Pattern)

2018-12-23  本文已影响0人  chenplus

1. 故事背景

假如你们公司要开发一个5v5对战游戏,像LOL, 要你设计开发那么多英雄,你会怎那么设计呢?
ps: 直接看类图吧,我自己都看不下去了!!!

聪明如我, 此设计图一出,我就是这条街最亮的仔! 赫 呸!

image.png

两个类都继承了抽象类Element, 复用代码,完美!!!

2. 需求变了

老板有一天说要加一个英雄,对你来说都是小意思!

3. 人在江湖飘,哪能不挨刀,我说的不是老板!

但是有一天老板说要加一个再正中间加一个可以种植的防御塔【WTF】,种下后就不能移动,你还是继承了抽象类Element; 丫的,玩家在玩的时候,发现防御塔成精了,可以移动,因为父类给他提供了移动的功能。

这个时候怎么办?

image.png

你灵机一动,我可以覆盖父类的move方法啊

Tower extends Element {
    move(){} //重写父类方法,搞定
}

隔不久,老板又加了游戏元素,大鸟,三狼,etc... 你们老板反复强调你们没有剽窃Tencent...
但是你确不关心他说的话,只是在思考这无穷无尽的修改...崩溃
老板整天这样加,整天加班让你开始吃不消,但是你心里觉得这个代码还有优化的空间,终于有一天你狠下心要重新大改一次.....

针对公司的问题,你决定把move() 提取出来(各元素的move是不同的);
你把shoot方法提取出来。

image.png

现在在Element中声明一个MoveBeheaver,
现在代码就可以这样写了

//防御塔类
Tower extends Emelent{
  Tower (){
      move = new CantMove();
  }
}

//盖伦类
Galen extends Emelent{
  Galen (){
      move = new GalenMove();
  }
}

但是 你同事给你看了一眼,这样还是在构造方法给 new 出来的啊,还不是写死的吗?
所有你又改了一把,在Element中给move加了setter方法

Element{

  public void setMoveBehaver(MoveBehaver mv){
    this.moveBehaver  =  mv;
  }

}

image.png
main(){
  Tower  t = new Tower ();
  t.setMoveBehaver(new CantMove());
}

原则:找出应用中可能需要变化之处,把他们独立出来,不要把那些不需要变化的代码混在一起
针对接口编程,而不是针对实现类编程
这里的接口是泛指,并不是指java中的接口,抽象类也算是接口**

诚恳希望大家可以指正错误,共同进步!

上一篇 下一篇

猜你喜欢

热点阅读