Java设计模式篇之策略模式

记得之前一个帖子说过,设计模式不用刻意的学,可以在代码实践中慢慢总结,但是我觉得想要阅读一个现有系统或者一个框架的源码,学习一些常用的设计模式还是有必要的,废话不多说,直接将进入正题。

  • 定义:策略模式定义算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
  • 原则:封装变化;组合优于继承;针对接口而不是针对实现编程

看着感觉有点似懂非懂的,直接上代码示例吧。
示例:

public abstract class Dogs{
	public Dogs(){}//构造类
	public void eatFood(){System.out.println("All dogs can eat!");}
	public abstract void makeSound();
	public abstract void runSpeed();
}

上面定义了一个狗的基类,很容易理解,狗分很多种类,比如哈斯奇、金毛、泰迪等等,基类中有狗的各种行为,如果时共性的,比如进食,那这种行为就可以在基类中直接实现,所有的子类都继承这种行为,毕竟这是不可变的,还有一些可变的行为,比如叫声,奔跑速度,每种狗可能不一样,这就需要子类来实现了。
示例:分别实现一个哈斯奇和金毛

public class Hasiqi extends Dogs{
	@Override public void makeSound(){System.out.println("wo wo wo!");}
	@Override public void runSpeed(){System.out.println("run slowly!");}
}
public class Jinmao extends Dogs{
	@Override public void makeSound(){System.out.println("wang wang!");}
	@Override public void runSpeed(){System.out.println("run fast!");}
}

这段代码也很容易理解,实现了两个子类,然后覆盖基类中的方法,使得子类有自己的行为。这么使用继承有几个缺点:

  • 代码在多个子类中重复,如果某些子类的行为相同,你不得不编写相同的代码来实现
  • 运行时的行为不容易改变,行为一旦确定就很难修改
  • 很难知道所有的行为,因为每个行为的实现都是在子类中进行的
  • 改变会牵一发而动全身,造成不必要的修改

如何避免这些缺点呢?就是把这些可变的行为封装起来,如何做呢?
示例:

public interface Sound(){void makeSound();}
public class Wowo implements Sound{
	@Override public void makeSound(){System.out.println("wo wo wo!");}
}
public class Wangwang implements Sound{
	@Override public void makeSound(){System.out.println("wang wang!");}
}
public interface Spedd{void runSpeed();}
public class RunSlowly implements Speed{
	@Override public void runSpeed(){System.out.println("run slowly!");}
}
public class RunFast implements Speed{
	@Override public void runSpeed(){System.out.println("run fast!");}
}

上面的定义了两个行为接口:叫声和奔跑速度。针对每一种行为都实现了两种行为类,有些狗时呜呜叫,有些时旺旺叫,有些跑的快,有些跑的慢这样就可以在创建子类的示例用到这些行为类,具体怎么用呢?
示例:

//首先需要先将基类修改一下
public abstract class Dogs{
	Sound sound;//叫声行为类
	Speed speed;//奔跑行为类
	public Dogs(){}
	public void eatFood(){System.out.println("All dogs can eat!");}
	public void makeSound(){sound.makeSound();}
	public void runSpeed(){speed.runSpeed();}
}
//这样我们在子类中只需要指定基类中的两个行为类就可以了
public class Hasiqi extends Dogs{
	public Hasiqi(){
		sound=new Wowo();
		speed=new RunSlowly();
	}
	//其他方法。。。
}
public class Jinmao extends Dogs{
	public Jinmao(){
		sound=new Wangwang();
		speed=new RunFast();
	}
	//其他方法。。。
}

上面的也不难理解,就是在子类的构造器总指定了子类改由的行为行。如果想在子类实例化之后再改变对象的行为,怎么做呢?
示例:在基类中加两个set方法就搞定了

public void setSound(Sound sound){this.sound=sound;}
public void setSpeed(Speed speed){this.speed=spedd;}

看到这里应该对策略模式了解的差不多了,再来一个测试类加强一下:

public class HasiqiTest{
	public static void main(String args[]){
		Dogs hasiqi = new Hasiqi();
		hasiqi.makeSound();//呜呜叫
		hasiqi.setSound(new Wangwang());//改变行为变成汪汪叫
		hasiqi.makeSound();//汪汪叫 
	}
}

总结:看上去好像挺简单的,实际上确实是挺简单的,策略模式的核心就是:将变化的行为或者算法封装起来,使得它能够独立于使用该行为或者算法的客户。学习设计模式要记住一句话:不要刻意的使用设计模式,除非能帮你解决实际问题,因为使用设计模式虽然能有助于系统的扩展,但是也增加的系统的复杂度。

参考文献:《Head First设计模式》 作者:Eric Freeman&Elsabeth Freeman&Kathy Sierra&Bert Bates

菜鸟手书,欢迎指正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值