设计模式学习:开闭原则2016-02-19上面讲完序,就开始讲开闭原则,有点不太优雅,不过,正如我说的,在学之前,周围的人和老师,网络上的人都觉得这个不错,你不太清楚,那么就学学吧,学完之后,再仔细去整合,思考,去除杂质,保留精华。在学的过程中总是不断自己停下来仔细思考的方式,我并不推荐学技术的人干(当然立志科研的人一定要有这种钻研精神),因为太耗时间。而且有时候你会发现,你疑问的就是后面提到的。唠叨完毕,开始讲讲开闭原则。1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造(Object Oriented Software Construction)》中提出了开闭原则,它的原文是这样:“Softwareentities should be open for extension, but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”。定义有点虚,可能你也会觉得矛盾,其实就是,你要改程序的,增加新的功能,那么不准修改原来的程序代码,只能增加新的代码。为什么要这样呢?疑问在心头,解决疑问的方式,让我们用举例来回答吧。让我们来用NBA的篮球明星来举例好不好(体谅下作者是篮球迷吧!)。不懂篮球的同学也没关系,不会要求有专业知识。我们都明白,每个人的习惯是不一样的,篮球明星是人,所以篮球明星们的一些习惯是不一样的(这句话是为了回忆那些证明题╮(╯▽╰)╭)。有些篮球明星,比如科比,身体比较平均。詹姆斯,身体比较粗壮。艾弗森,身体比较瘦小。既然他们的身体不一样,那么他们的得分技巧必然不同,我们就写一个能够表示NBA球星的吧!
import java.util.*;//将技巧抽象为一个方法,单独拿出来interface Skill{public void skill();};//詹姆斯的技巧class JamesSkill implements Skill{public void skill(){System.out.println("詹姆斯的技巧:战斧式扣篮");}};//科比的技巧class KobeSkill implements Skill{public void skill(){System.out.println("科比的技巧: 后仰跳投");}};//艾弗森的技巧class AISkill implements Skill{public void skill(){System.out.println("艾弗森的技巧: 变相");}};/* URL地址:http://www.bianceng.cn/Programming/project/201602/49625.htm抽象的方法拿出来后,有不同的类来实现抽象方法这个接口,让不同的选手持有不同的行为类,这个设计方案叫做封装可变形。同时,在后面的设计模式中我们也会讲到,这个叫做策略模式 */class NBAPlayer {//姓名private String name;private Skill skill;public NBAPlayer(String name,Skill skill){this.name=name;this.skill=skill;}public void setSkill(Skillskill){this.skill=skill;}public SkillgetSkill(){return skill;}public String getName(){return name;}public void action(){skill.skill();}};public class Main{public static void main(String args[]){//不同的技巧Skill jamesSkill=new JamesSkill();Skill kobeSkill=new KobeSkill();Skill aiSkill=new AISkill();//不同的球员NBAPlayer james=new NBAPlayer("James",jamesSkill);NBAPlayer kobe=new NBAPlayer("kobe",kobeSkill);NBAPlayer ai=new NBAPlayer("AI",aiSkill);//会有不同的表现james.action();kobe.action();ai.action();}}
代码可以这里下载https://github.com/ZHONGHuanGit/DesignPattern从代码中我们看到,不同的NBAPlayer的行为被抽象为一个接口,具体的实现放在具体的类中。之所以这样设计,是为了符合开闭原则。现在我们可以想想,当我们有新的球员来了,它的技巧是不一样的,这个时候我们就可以新建一个类,实现Skill接口,然后作为对象属性存在球员对象中。这样的优点,就是做的优点就是,新的球员增加不会更改原有的代码,只需要增加新的代码即可。是不是很不错啊,在设计中,我们尽量把代码中,将来可能会发生变化的地方封装起来,拿出去,用抽象的类封装,具体的实现放在后面的具体类中。因为我们更改起代码会特别方便。Author:csdn博客 钟桓