码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式——策略模式

时间:2015-08-14 06:33:35      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:

面向对象的设计方案

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

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

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

所以想到了通过使用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**");
	}
}

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


策略模式:

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

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


设计模式——策略模式

标签:

原文地址:http://my.oschina.net/gaohongtian/blog/492113

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!