四、设计模式——策略模式
四、设计模式——策略模式
文森特梵高 发表于3年前
四、设计模式——策略模式
  • 发表于 3年前
  • 阅读 107
  • 收藏 12
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: 设计模式是骨灰级大神们通过多年的开发总结出来的软件设计思想。 良好的设计能够让工程可扩展、易维护,减少工作量,让你从容应付产品狗的各种调戏,达到早下班的效果。 自从用活了设计模式,老婆再也不用担心我凌晨下班啦.....

面向对象的设计方案

产品狗今天跟你说,要做一个“模拟鸭子游戏”,需求如下:

鸭子有共同的功能,比如游泳和叫。

鸭子也有不同的功能,比如有绿头鸭和红头鸭。

所以想到了通过使用OO的方式,将共同的功能放在抽象类Duck中,而不同的用abstract修饰供子类实现。

public abstract class Duck {
	public Duck() {
	}
	public void Quack() {
		System.out.println("~~gaga~~");
	}
	public abstract void display();//不同样子的鸭子,有不同的实现
	public void swim() {
		System.out.println("~~im swim~~");
	}
}
public class GreenHeadDuck extends Duck {//绿头鸭
	@Override
	public void display() {
		System.out.println("**GreenHead**");
	}
}
public class RedHeadDuck extends Duck {//红头鸭
	@Override
	public void display() {
		System.out.println("**RedHead**");
	}
}

通过面向对象的思想,我们实现了复用,完成了需求。


新需求


看看这种设计在增加新功能的时候,其扩展性如何。

新需求:添加会飞的鸭子

public abstract class Duck {
        //...略...
	public void Fly() {
	     System.out.println("~~im fly~~");
	}
}

如果在超类中添加这段代码,那么问题马上就来了,超类中添加的方法对所有之类都生效,而不是所有的鸭子都需要这个功能。

public class GreenHeadDuck extends Duck {
        //...略...
	public void Fly() {
		System.out.println("~~no fly~~");
	}
}

那我们可以覆盖掉不会飞的鸭子的fly方法,不就可以了吗~~~

问题又来了,如果有10种不会飞的鸭子,岂不是要重复做10次重复性的工作?

那可不可以把超类中的fly方法弄成abstract呢?

这样所有的之类不就都要实现fly方法吗~如果50种鸭子,那就需要实现50次!

如果又有新需求,比如石头鸭子,既不会飞也不会叫 ,如何实现? +_+

看来上述都不是很好的设计方案。



思路


分析软件设计需要考虑两方面的问题

1)分析项目变化和不变的部分,对于变化的部分,抽象成接口+实现;

2)找到那些功能会根据新需求而变化。

这个模拟鸭子的游戏中,鸭子的叫声和飞行方式会变。



策略模式实现

对飞行和叫分别设计接口,对于不同的叫声和飞行再通过实现的方式完成。

public interface FlyBehavior {
	void fly();
}
public	interface QuackBehavior {
	void quack();
}

这样新增行为变得很简单,只需要实现相同的接口即可。

在鸭子超类中,通过组合抽象的飞行和抽象的叫声,具体的叫和飞交给之类补充。

import com.java.hexter.stimulateduck.flybehavior.FlyBehavior;
import com.java.hexter.stimulateduck.quackbehavior.QuackBehavior;

public abstract class Duck {
	FlyBehavior mFlyBehavior;
	QuackBehavior mQuackBehavior;
	public Duck() {
	}
	public void Fly() {
		mFlyBehavior.fly();
	}
	public void Quack() {
		mQuackBehavior.quack();
	}
	public abstract void display();
	public void SetQuackBehavoir(QuackBehavior qb) {
		mQuackBehavior = qb;
	}
	public void SetFlyBehavoir(FlyBehavior fb) {
		mFlyBehavior = fb;
	}
	public void swim() {
		System.out.println("~~im swim~~");
	}
}

看到没有,抽象超类中没有任何具体的实现类耦合,而是通过接口调用。

里面的fly还是quack函数,都是根据之类mFlyBehavior和mQuackBehavior的不同而不同。

看看绿头鸭以及红头鸭的实现过程。

public class GreenHeadDuck extends Duck {
	public GreenHeadDuck() {
		mFlyBehavior = new GoodFlyBehavior();
		mQuackBehavior = new GaGaQuackBehavior();
	}
	@Override
	public void display() {
		System.out.println("**GreenHead**");
	}
}

public class RedHeadDuck extends Duck {
	public RedHeadDuck() {
		mFlyBehavior = new BadFlyBehavior();
		mQuackBehavior = new GeGeQuackBehavior();
	}
	@Override
	public void display() {
		System.out.println("**RedHead**");
	}
}

很强大,又木有~~~ 脑洞打开的赶脚


策略模式:

行为抽象成接口,并且实现算法族,在超类中放行为接口对象,子类里具体设置行为对象。

原则是分离变化部分,封装接口,基于接口编程各种功能,让行为的实现能单独变化。


  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 2
博文 24
码字总数 15386
×
文森特梵高
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: