开发模式之策略模式

接触java、Android好长时间,常看一些前辈们写的代码,却发现很精辟。但是又很难理解。不久前看完了很多人推荐的《Head First Java》,此书很适合我这种的新人读,充分挖掘大脑,让我们更容易理解,并记忆。后来,在taobao搜了下Head First系列书籍,发现 《Head First 设计模式》这本书很畅销,好评如潮。买了一本后,读起来热血膨胀。理解前辈们代码为什么这么写。晚生以后常会将此书的观点整理给大家,如有错误请指出!




应用环境:

               某公司要开发一个模拟鸭子的游戏,鸭子主要有 叫quack(),游泳swim(),行为display()方法。此公司为了在众公司脱颖而出,给鸭子duck实现飞fly(),功能。现在有以下几个方案:

方案一:用继承

public class Duck {
	public void quack() {
	}

	public void swim() {
	}

	public void display() {
	}

	public void fly() {
	}
}
public class MallardDuck extends Duck {

	@Override
	public void display() {
		// 外观是橡皮鸭
	}

	@Override
	public void quack() {
		// 覆盖成吱吱叫
	}

}

public class ReadHeadDuck extends Duck {

	@Override
	public void display() {
		//外观是绿头
	}
	
}
public class RubberDuck extends Duck {

	@Override
	public void display() {
		// 外观是红头
	}

}
问题:并不是所有的鸭子都会飞。改变会牵一发动全身,造成其他鸭子不想要的改变。————否决


方案二:用接口


问题:代码变得很多,如果有50个Duck子类都要修改行为,那怎么办?


设计原则一:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要的变化的代码混在一起。

此原则思考方式:把会变化的那部分“封装”起来,好让其他部分不会受到影响。


解决:我们知道Duck类内的fly()和quack()会随着雅子的不同而改变.为了要把这两个行为从Duck类中分开,我们将把它们从Duck类中取出来,建立一组新类来代表每个行为。


设计鸭子行为:

我们希望设计的 具有弹性,让鸭子的行为可以动态的改变。也就是,我们应该在鸭子类中包含设定行为的方法,这样就可以再“运行时”动态地“改变”绿头鸭的飞行行为。


设计原则二:针对接口编程,而不是针对实现编程。


从现在开始,鸭子的行为将被放在分开的类中,此类撰文提供某行为接口的实现。


针对接口编程和针对实现编程的比较。

Dog d = new Dog();

d.bark();


Animal animal = new Dog();

animal.makeSound();


public class Animal{
	public void makeSound(){}
}
public class Dog extends Animal{
	public void makeSound(){
		bark();
	}
	public void bark(){
	}
}
public class Cat extends Animal{
	public void makeSound(){
		meow();
	}
	public void meow(){
	}
}


优点:子类实例化的动作不在需要在代码中硬编码。而是,在运行时才制定具体的实现的对象。



鸭子行为整合:

public abstract class Duck {
	/**
	 * 行为接口类型声明两个引用变量,所有鸭子子类(在同一个package中)都继承它们
	 */
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public Duck() {
	}

	public abstract void display();

	/**
	 * 委托给行为类
	 */
	public void performFly() {
		flyBehavior.fly();
	}

	public void performQuack() {
		quackBehavior.quack();
	}

	public void swim() {
		System.out.println("All ducks float ,even decoys!");
	}
}

//--------------------------------------------------------------------------------
/**
 * 所有飞行必须实现的接口
 *
 */
public interface FlyBehavior {
	public void fly();
}


public class FlyWithWings implements FlyBehavior {
	/**
	 * 飞行实现,给真会飞的鸭子用
	 */
	@Override
	public void fly() {
		System.out.println("I'm flying!!");
	}

}


public class FlyNoway implements FlyBehavior {
	/**
	 * 不会飞的鸭子用
	 */
	@Override
	public void fly() {
		System.out.println("I cat't fly!!");
	}

}


//----------------------------------------------------------------------------------
public interface QuackBehavior {
	public void quack();
}


public class Quack implements QuackBehavior {

	@Override
	public void quack() {
		System.out.println("Squeak");
	}

}


public class MuteQuack implements QuackBehavior {

	@Override
	public void quack() {
		System.out.println("Quack");
	}

}


public class Squeak implements QuackBehavior {

	@Override
	public void quack() {
		System.out.println("Quack");
	}

}



动态设定行为:

1.在duck类中加入两个新方法:

public void setFlybehavior(FlyBehavior fb){
	flyBehavior=fb;
}
public void setQuackBehavior(QuackBehavior qb){
	quackBehavior =qb;
}



2.制造一个新的鸭子类型:ModelDuck

public class ModeDuck extends Duck{
	public ModelDuck(){
		flyBehavior = new flyNoWay();
		quackBehavior = new Quack();
	}
	public void display(){
		Sysout.out.println("I'm a model duck");
	}
}



3.建立一个新的FlyBehavior类型。

public class FlyRocketPowered Implements FlyBehavior{
	public void fl(){
		Sysout.out.println("I'm flying with a rocket!");
	}
}



4.改变测试类。使模型鸭具有火箭动力。


public class MiniDuckSimulator{
	public static void main(String[] args){
		Duck model = new MallardDuck();
		model.setFlyBehavior(new FlyRocketPowered());
		model.performFly();
	}
}


类图如下:



组合:将两个类结合起来使用


设计原则三:多用组合,少用继承

刚才使用的设计模式就是:策略模式

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



组成:

—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。

应用场景:

1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
策略模式UML


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值