Strategy Pattern(策略模式)

         学习Object Oriented(OO)也有段时间了,但一直没有学习Pattern Design方面的东西,感觉使用OO的时候完全不给力啊。So, balabala........

          Sorry,扯了一点废话。

          Strategy Pattern,在WikiPedia中解释为:a particularsoftware design pattern, whereby algorithms can be selected at runtime. 也就是说,Strategy Pattern在运行时能够改变算法的一种设计模式。那么,这个算法是什么呢?这里的算法,指的是Object的行为,比如一个Duck,它拥有Fly的行为,但是运行时改变算法,使其can't Fly。这就是Strategy Pattern的优势所在。当然,《Head First 设计模式》中对它也有定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

           OK,我们以《Head First 设计模式》中的例子来说明。

               我们要设计以下两个类,MallarDuck(绿头鸭)和RedheadDuck(红头鸭)。既然都是Duck(鸭),会OO的人都会想到--inherit(继承)。那这两种鸭子有什么共有的特性,我们可以将它们抽象出来放入一个父类Duck中呢。哦,它们都会quack,还有swim!于是,有了下面的设计:


            嗯,看起来不错的样子。但是过了一天,老板(产品经理,又或者其他**,你明白的)说,我们要新的功能,MallardDuck和RedheadDuck都要有fly( )的行为!嗯,不怕,OO的好处来了。只要在Duck类中新加入fly( )行为,这下所有的子类都有fly( )的行为了,一切OK!

            等等,让我想想,真的OK吗?第3天,**(who?)又说,我们仅有MallardDuck与RedheadDuck太少了,我们需要一个RubberDuck ! OK,so easy。

            Hold on !   RubberDuck好像不会飞啊。但是为什么RubberDuck有fly( )这个行为!那也行,好吧,在RubberDuck中覆盖fly( )方法,但是什么也不做吧。


class RubberDuck extend Duck {
        ......
        @override
        public fly() {
                 // do nothing
        }
        ......
}

           看上去还成。但是如果不止增加RubberDuck呢,还有ModelDuck, 以及**Duck, balabala........那不是每个类都要覆盖fly( )方法?你怎么知道只有fly( )方法。要是**Duck不会swim呢(我们假设有这样一种Duck)?OMG,我的OO呢,说好的方便呢?

           嘿,谁说没有好方法。且看:

 

            这下,谁看要什么方法就让它有吧,想要fly( )方法,就实现Flyable这个接口;想要quack方法,就实现Quackable接口。Oh, No !   这不是N多代码重复吗!MallardDuck与RedheadDuck的fly( )方法是一样的啊,说好的代码复用呢?

            等等,好像灵感又来了!代码复用?参考Duck类的做法不就行了!

                   Oh, 终于告一段落了,这样就可以了!再等等!什么,还有?!学习OO的时候,前人都告诫说:少用继承,多用组合。似乎继承过多了。。。还是多重的。。。那再修改!

               这么修改,还增加了一个功能:运行时可以替换Object的行为啊,组合果然是个good choice !

               其实,最后一个版本就是刚开始就提到的Strategy Pattern, 真是“千呼万唤始出来”啊。


              另外,附上最终的Java代码,让我们更好的理解它。


Duck.java:

// Duck.java

public abstract class Duck {
	
	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 void setFlyBehavior(FlyBehavior fb) {
		flyBehavior = fb;
	}
	
	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}
}

FlyBehavior.java:

// FlyBehavio.java

public interface FlyBehavior {
	public void fly();
}

FlyWithWings.java:

// FlyWithWings

public class FlyWithWings implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I'am flying!");
	}

}

FlyNoWay.java:

// FlyNoWay.java

public class FlyNoWay implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I can't fly!");
	}

}

FlyRockedPowered.java:

// FlyRockedPowered

public class FlyRockedPowered implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I' am flying with a rocked!");
	}

}

QuackBehavior.java:

// QuackBehavior.java

public interface QuackBehavior {
	public void quack();
}

Quack.java

// Quack.java

public class Quack implements QuackBehavior {

    @Override
    public void quack() {
        // TODO Auto-generated method stub
        System.out.println("Quack");
    }

}



MuteQuack.java

// QuackBehavior.java

public class MuteQuack implements QuackBehavior {

    @Override
    public void quack() {
        // TODO Auto-generated method stub
        System.out.println("<< Silence >>");
    }

}

Squeak.java

// Squeak.java

public class Squeak implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("Squeak");
	}

}

MallardDuck.java:

// MallardDuck

public class MallardDuck extends Duck {
	
	public MallardDuck() {
		quackBehavior = new Quack();
		flyBehavior = new FlyWithWings();
	}
	
	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("I'm a real Mallard duck");
	}

}

ModelDuck.java:

// ModelDuck

public class ModelDuck extends Duck {

	ModelDuck() {
		flyBehavior = new FlyNoWay();
		quackBehavior = new Quack();
	}
	
	@Override
	public void display() {
		// TODO Auto-generated method stub
		System.out.println("I'm a model duck!");
	}

}

Test.java

// Test.java

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Duck mallard = new MallardDuck();
		mallard.performFly();
		mallard.performQuack();
		
		System.out.println("------------------- now, change the duck! --------------------");
		
		Duck model = new ModelDuck();
		model.performFly();
		System.out.println("------------------- now, set rocked on the model! --------------------");
		model.setFlyBehavior(new FlyRockedPowered());
		model.performFly();
}

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值