Java 设计模式 (1) 策略模式

在学习策略模式之前我们首先看一段有趣的对话: 

大师与门徒 <来自Head First设计模式>

大师:徒儿,告诉我你在面向对象的道路上,你学到了什么?

门徒:大师,我学到了,面向对象之路承诺了“复用”。

大师:继续说……

门徒:大师,借由继承,好东西可以再被利用,所以程序开发时间就会大幅减少,就好像在林中很快的砍竹子一样。

大师:徒儿呀!软件开发玩成“前”以及玩成"后",何者需要花费更多的时间啊。

门徒:答案是”后“,我们总是需要花许多时间在系统维护和变化上,比原先开发花的时间更多。

大师:对呀,那么我们是不是应该致力于提高可维护性和可拓展性上的复用呀?

门徒:是的大师,的确是如此。

大师:我觉得你还有很多东西要学,希望你在深入研究继承。你会发现,继承有它的问题,还有一些其他的方式可以达到。


所以本文的目标是为了提高代码的可维护性和可拓展性上的复用,并解决继承所产生的问题。


我们一般都会将相同事物或方法抽离出来,封装成一个类,然后让其他子类继承它。但是如果有些子类的具体实现方法不一样,就会导致很多子类需要覆盖并实现父类的方法。

这不仅会导致。子类的代码量变多,而且没有实现复用。如果需要修改这个方法,那么凡是用到了这个方法的子类都需要修改,给后期的维护带来了很多问题。那么怎么解决这个问题呢?接下来我用一个例子来教大家怎么解决。



上图定义了一个Person类,里面包含了run(),see(),以及skill()三个方法,因为所有人都具备上面三个特性,所以将其封装到Person类里面,让其他子类去继承它。

因为run()和see()方法,所有人都是一样的,所以继承并不会出现问题。但是skill()方法的的实现因人而异,不同的人具备不同的skill。按照以前的做法,我们会将skill方法教给子类去实现。但是这样产生的问题有:

1、代码无法复用,每个子类的skill方法都不同

2、子类中的代码量变大了。

3、如果后期维护需要修改skill方法,那么所有实现了skill方法的子类都需要修改,维护带来了困难。

所以我们不能将skill方法交给子类去实现,而是定义一个SkillManager接口来管理skill();让不同类型的子类去继承实现。然后在Person类的skill方法中调用SkillManager的skill方法就行了。而子类就不用关心skill方法的具体实现了,只需要获取对应SkillManager的实例就行了。这样做的好处:

1、提高了代码复用,子类无需实现skill方法。

2、减少了子类中的代码量。

3、如果后期维护需要修改skill方法,我们只需要修改SkillManager对应的子类就行了。而不需要去修改Person类的子类。


下面是代码实现:

public  class Person {
	
	public SkillManager  skillmanager;
	
	//每个人都能双脚,跑步的方式是一样的
	public void run(){
		System.out.println("我有双脚,我能跑步");
	}
	//每个人都有双眼,看东西的方式是一样的
	public void see(){
		System.out.println("我有眼睛,我能看见东西");
	}
	//每个人的职业不同所以 技能不一样,所以需要将该方式交给专门的类去实现
	public void skill(){
		skillmanager.skill();
	}
	
	public SkillManager getSkillmanager() {
		return skillmanager;
	}
	
	public void setSkillmanager(SkillManager skillmanager) {
		this.skillmanager = skillmanager;
	}

}

public interface SkillManager {
	public void skill();
}

public class Student extends Person{
	
	public Student(){
		skillmanager = new Learning();
	}

}

public class Programmer extends Person{
	public Programmer(){
		skillmanager = new Coding();
	}
}

public class Learning implements SkillManager{

	@Override
	public void skill() {
		// TODO Auto-generated method stub
		System.out.println("我拥有学习能力");
	}
	
}

public class Coding implements SkillManager{

	@Override
	public void skill() {
		// TODO Auto-generated method stub
		System.out.println("我有写代码的能力");
	}

}

public class Test {
	public static void main(String[] args)
	{
		Student student = new Student();
		Programmer programmer = new Programmer();
		
		student.run();
		programmer.run();
		student.see();
		programmer.see();
		student.skill();
		programmer.skill();
		
		//这个学生学了编程之后 具备了编程的技能
		student.setSkillmanager(new Coding());
		student.skill();
		
	}
	/*
	out~
	我有双脚,我能跑步
	我有双脚,我能跑步
	我有眼睛,我能看见东西
	我有眼睛,我能看见东西
	我拥有学习能力
	我有写代码的能力
	我有写代码的能力
	*/
}

 
 

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

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






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值