策略模式——Strategy Pattern

策略模式
面向对象的基础包括:继承、封装、多态、抽象
模拟鸭子的应用:
其中,使用继承的好处是能够实现代码的复用,如
public abstract class Duck
{
	public void quack(){}
	public void swim(){}
    public void fly(){}
    public void otherbehavior(){} 
}
public class Greenheadduck extends Duck{}
public class Redheadduck extends Duck{}
然而,并非所有的继承都是有用的,有时我们需要用到覆盖,如
public class Woodduck extends Duck
{
	//木头鸭子不能嘎嘎叫
	pubilic void quack(){}
	//覆盖此方法,但是什么也不做
}
显然,每次加入一种新的鸭子后,继承并不能解决所有问题,我们需要不断的进行覆盖
有时,我们可以使用接口解决这样的问题(分开会变化和不会变化的部分,会变化的作为接口使用),如
public abstract class Duck
{
	public void swim(){}
    public void otherbehavior(){} 
}
public interface quackable
{
	public void quack();
}
public class Redheadduck extends Duck implements quackable
{
	public void quack()
	{	
		System.out.println("嘎嘎叫");	
	}
}
public class Woodduck extends Duck implements quackable
{
	pubilic void quack()
	{
		System.out.println("不会叫");
	}
}
然而,使用接口却无法实现代码的复用,而且当鸭子的新种类越来越多时,使用接口无异于覆盖
现在我们知道使用继承和接口都无法很好地解决问题
而关键在于鸭子的行为quack()会随着鸭子的不同而改变
显现我们面对的问题是“如何分开会变化和不会变化的部分”
使用策略模式可以解决这个问题,我们需要将会变化的部分分离出来并封装起来
策略模式:定义算法族并封装起来,让它们能够互相替换,使算法的变化独立于使用算法的客户
代码演示:

//第一种策略
public interface First_Strategy 
{
    public void algorithm_one(); 
}
public class FStrategy_one implements First_Strategy 
{
    public void algorithm_one() 
    {
        System.out.println("FStrategy_one's algorithm_one");
    }
}
public class FStrategy_two implements First_Strategy 
{
    public void algorithm_one() 
    {
        System.out.println("FStrategy_two's algorithm_one");
    }
}
//第二种策略
public interface Second_Strategy 
{
    public void algorithm_two(); 
}
public class SStrategy_one implements Second_Strategy 
{
    public void algorithm_two() 
    {
        System.out.println("SStrategy_one's algorithm_two");
    }
}
public class SStrategy_two implements Second_Strategy 
{
    public void algorithm_two() 
    {
        System.out.println("SStrategy_two's algorithm_two");
    }
}
/*------第N种策略------*/
public abstract class Client 
{
    //可变部分分离为接口变量
	First_Strategy firststrategy;
    Second_Strategy secondstrategy;
    public void use_First_Strategy() 
    {
        firststrategy.algorithm_one();
    }//使用第一种策略算法
    public void use_Second_Strategy() 
    {
       secondstrategy.algorithm_two();
    }//使用第二种策略算法
}
public class Client_one extends Client
{
    public Client_one()
    {
		firststrategy = new FStrategy_one();
		secondstrategy = new SStrategy_one();
    }
}//定义客户一及其需要使用的策略
public class Client_two extends Role
{
    public Client_two()
    {
	firststrategy = new FStrategy_two();
	secondstrategy = new SStrategy_two();
    }
}//定义客户二及其需要使用的策略
public class StrategyPatternDemo
{
    public static void main(String[] args) 
    {
		Client one = new Client_one();
		Client two = new Client_two();
		one.use_First_Strategy();
		two.use_First_Strategy();
		one.use_Second_Strategy();	
		two.use_Second_Strategy();		
    }
}
鸭子实例:
public interface FlyBehavior
{
	public void fly();
}
public class FlyWithWings implements FlyBehavior
{
	public void fly()
	{
		System.out.println("flying");
	}
}
public class FlyNoWay implements FlyBehavior
{
	public void fly()
	{
		System.out.println("can't fly");
	}
}
public interface QuackBehavior
{
	public void quack();
}
public class Quack implements QuackBehavior
{
	public void quack()
	{
		System.out.println("Quack");
	}
}
public class MuteQuack implements QuackBehavior
{
	public void quack()
	{
		System.out.println("Silence");
	}
}
public abstract class Duck
{
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	public void swim(){}
	public void otherbehavior(){} 
	public void performQuack()
	{
		flyBehavior.fly();
	}
	public void performFly()
	{
		quackBehavior.quack();
	}
}
public class MallardDuck extends Duck
{
	public MallardDuck()
	{
		quackBehavior = new Quack();
		flyBehavior = new FlyWithWings();
	}//野鸭子
}
public class ModelDuck extends Duck
{
	public ModelDuck()
	{
		quackBehavior = new Quack();
		flyBehavior = new FlyNoWay();		
	}//模型鸭子
}
public class Demo
{
	public static void main(String args[])
	{
		Duck mallard = new MallardDuck();
		mallard.performQuack();
		mallard.performFly();
		Duck model = new ModelDuck();
		model.performQuack();
		model.performFly();
	}
}
另外,使用了策略模式不仅可以解决问题,而且可以实现动态设定行为
当我们需要再添加一种新的鸭子,并且这种鸭子又有了新的飞行行为(新策略)时,我们可以这样
public abstract class Duck
{
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	public void swim(){}
	public void otherbehavior(){} 
	public void performQuack()
	{
		flyBehavior.fly();
	}
	public void performFly()
	{
		quackBehavior.quack();
	}
	public void setFlyBehavior(FlyBehavior fb)
	{
		flyBehavior = fb;
	}//新增加的方法,用于动态设定行为
}
public class FlyRockPowered implements FlyBehavior
{
	public void fly()
	{
		System.out.println("flying with a rocket");
	}
}//新增加的策略
public class Demo
{
	public static void main(String args[])
	{
		Duck model = new ModelDuck();
		model.performQuack();
		model.performFly();//更改行为前print:"can't fly"
		model.setFlyBehavior(new FlyRockPowered);
		model.performFly();//更改行为后print:"flying with a rocket"
	}
}
策略模式的设计原则       
       设计原则1------把会变化的部分取出来并封装起来
       当新的需求到来时会使某部分的代码发生改变,我们可以确定这部分的代码为可变部分
       此处是将Duck的fly()行为和quack()行为分离出来

       设计原则2------针对接口编程而不是针对实现编程
       使用多态,将变量的声明类型设计为超类型(抽象类或接口)
       此处是声明
FlyBehavior flyBehavior接口和QuackBehavior quackBehavior接口

       设计原则3------多用组合少用继承

       使用组合(有一个)可能比使用继承(是一个)更好
       此处是将FlyBehavior行为和QuackBehavior行为设计为组合而不是使用继承来实现



参考书籍《Head First 设计模式》






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值