策略模式(二)

东方不败希望自己可以文武双全,既能够快意江湖,又可以学富五车,于是改了个名,叫做东方快车。(摘抄的~~)

软件开发一个不变的真理就是:CHANGE 改变 

问题归零:继承不能解决问题,因为鸭子的行为在子类里不断地改变,并且让所有的子类都有这些行为是不恰当的。

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

          把会变化的部分取出并“封装”

通过观察下面超类Duck,找出会变化的部分。

package com.zl.strategy.two;

public abstract class Duck {

	public void quack(){//鸭子的叫的方式有很多种,嘎嘎叫,吱吱叫~~ 所以该方法会改变
	   
		System.out.println("Duck Quack");
	}
	
	public void swim(){
		   
		System.out.println("Duck swim");
	}
	
	public void fly(){//鸭子飞行会改变,飞与不飞		   
		System.out.println("Duck swim");
	}
	abstract void display();
	
}

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

把这些可变的行为放置在一个新的行为接口,然后具体的行为实现该接口即可。

package com.zl.strategy.two;

public interface QuackBehavior {

	public void quack();
}
package com.zl.strategy.two;

public interface FlyBehavior {

	public void fly();
}
具体实现如下:
package com.zl.strategy.two;

public class Squeak implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub

		System.out.println("Duck Squeak");
	}

}
package com.zl.strategy.two;

public class Quack implements QuackBehavior {

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

}
package com.zl.strategy.two;

public class FlyWithWings implements FlyBehavior {

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

}
package com.zl.strategy.two;

public class FlyNoWays implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub

		System.out.println("Duck FlyNoWays");
	}

}

现在开始重新构造Duck类

Duck类中引入实例变量FlyBehavior,QuackBehavior 并且提供方法进行访问这两个实例变量的方法入口

package com.zl.strategy.two;
public abstract class Duck {

	public FlyBehavior tFlyBehavior;
	public QuackBehavior tQuackBehavior;
	
	public void swim(){
		System.out.println("Duck swim");
	}
	
	public void performQuack(){
		tQuackBehavior.quack();
	}
	
	public void performFly(){
		tFlyBehavior.fly();
	}
	abstract void display();
}

编写一个子类继承Duck:

package com.zl.strategy.two;

public class MallarDuck extends Duck {

	public MallarDuck(){
		tQuackBehavior=new Quack();
		tFlyBehavior=new FlyWithWings();
	}
	@Override
	void display() {
		// TODO Auto-generated method stub
        
		System.out.println("MallarDuck display");
	}

}

编写测试类:

package com.zl.strategy.two;

public class TestDuck {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Duck tMallarDuck=new MallarDuck();
		tMallarDuck.display();
		tMallarDuck.performFly();
		tMallarDuck.performQuack();
		tMallarDuck.swim();
	}

}

此处的一个弊端是,在MallarDuck.java中构造器处对接口进行具体实现类实例化,如果日后鸭子飞行行为,叫行为改变时,就需要修改代码。所以应该进行动态进行实例化具体的实现类。

在Duck.java中添加两个set方法,向外界提供入口,进行传入接口的具体实现类。这里运用了多态。在程序运行时,动态的改变行为。

改造如下:

package com.zl.strategy.two;

public abstract class Duck {

	public FlyBehavior tFlyBehavior;
	public QuackBehavior tQuackBehavior;
	
	public void swim(){
		System.out.println("Duck swim");
	}
	
	public void performQuack(){
		tQuackBehavior.quack();
	}
	
	public void performFly(){
		tFlyBehavior.fly();
	}
	abstract void display();
	
	public void setFlyBehavior(FlyBehavior fly){
		tFlyBehavior=fly;		
	}
	
	public void setQuackBehavior(QuackBehavior quack){
		tQuackBehavior=quack;		
	}
}

测试类如下:

package com.zl.strategy.two;

public class TestDuck {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Duck tMallarDuck=new MallarDuck();
		tMallarDuck.display();
		tMallarDuck.performQuack();
		tMallarDuck.setQuackBehavior(new Squeak());
		tMallarDuck.performQuack();
	}

}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值