`

里氏替换原则在装饰模式中的体现

阅读更多

     今天继续学习CBF4LIFE的设计模式,看到了第13章-----装饰模式。以前看thinking in Java中IO部分,讲到IO管道之间的套接时,作者就说到了此处运用到了装饰模式,当时没太留意什么装饰模式到底是个啥玩意,今天再次接触到它,以免以后忘记了,还是写下来为妙啊。

    CBF4LIFE中装饰模式中,举到的“修饰”成绩单的例子很是经典,在这里,我也就照搬啦(故事情节太长,这里主要是看里氏替换原则使用,在此就不用祥讲了)。

      先定义抽象的学生成绩单

    

package com.lonton.decorator;

public abstract class SchoolReport {
	public abstract void report();
	
	public abstract void sign(String name);
}

 

    填写成绩单的内容

  

package com.lonton.decorator;
/**
 * 
 * @author opalshine
 *
 */
public class FouthGradeSchoolReport extends SchoolReport {

	@Override
	public void report() {
		System.out.println("尊敬的XXX家长:");
		System.out.println(" ......");
		System.out.println(" 语文 62 数学65 体育 98 自然 63");
		System.out.println(" .......");
		System.out.println(" 家长签名: ");

	}

	@Override
	public void sign(String name) {
		System.out.println("家长签名为:"+name);
	}
}

 

  拿回家给老爸签名

 

package com.lonton.decorator;

public class Father {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SchoolReport sr = new FouthGradeSchoolReport();

		sr.report();
		sr.sign("爸爸");
	}
}

 

  成绩单啥样

 

尊敬的XXX家长:
 ......
 语文 62 数学65 体育 98 自然 63
 .......
 家长签名: 

  

  这成绩,老爸气的够呛的,还会给你签名吧,首先准备挨板子吧。当然咯,为了避免一顿板子,我首先得将成绩单修饰修饰哈

  定义修饰模板

  

package com.lonton.decorator;
/**
 * Decorator抽象类的目的很简单,就是要让Decorator子类来封装SchoolReport的子类
 * @author opalshine
 *
 */
public abstract  class Decorator extends SchoolReport{
	private SchoolReport sr;
	
	public Decorator(SchoolReport sr){
		this.sr = sr;
	}
	
	public void report(){
		this.sr.report();
	}
	
	public void sign(String name){
		this.sr.sign(name);
	}
}

 

  怎么修饰呢?弄虚作假肯定不行,那样被发现了,那就不是一顿板子的事咯。其实这次考试成绩都不高,语文最高分75,数学    

  78,自然80,嘿嘿,我那60几分跟最高分也差不了多少了(其实也是最后几名啊),另外,班上转学了10几个人,我的排名也

  理 所当然的前进了十几名,排到38名了(这个当然就不必和老爸说了)

  定义最高分数模板

  

package com.lonton.decorator;

public class HighScoreDecorator extends Decorator {

	public HighScoreDecorator(SchoolReport sr) {
		super(sr);
	}
	
	private void reportHighScore(){
		System.out.println("这次考试语文最高分75,数学78,自然80");
	}
	
	public void report(){
		this.reportHighScore();
		super.report();
	}
}

 

  定义排名模板

 

package com.lonton.decorator;

public class SortDecorator extends Decorator {

	public SortDecorator(SchoolReport sr) {
		super(sr);
		// TODO Auto-generated constructor stub
	}
	
	private void reportSort(){
		System.out.println("我这次排名38----");
	}
	
	public void report(){
		super.report();
		this.reportSort();
	}

}

 

  然后,老爸看到的成绩单就不一样咯

 

package com.lonton.decorator;
/**
 * @author opalshine
 * 
 */
public class Father {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SchoolReport sr = new FouthGradeSchoolReport();
		/**里氏替换原则,基类能出现的地方,子类也一定能够出现
		 * 里氏替换原则,父类引用指向子类对象
		 * HighSocreDecorator构造函数中的参数应该是SchoolReport,但这里却是SchoolReport的子类FouthGradeSchoolReport
		 * 同样,SortDecorator构造函数中的参数也应该是SchoolReport,但是这里却是HighScoreDecorator
		 * 装饰模式中,充分的体现出了里氏替换原则
		 * 
		 */
		sr = new HighScoreDecorator(sr);
		sr = new SortDecorator(sr);
		sr.report();
		sr.sign("爸爸");
	}
}

 

 

这次考试语文最高分75,数学78,自然80
尊敬的XXX家长:
 ......
 语文 62 数学65 体育 98 自然 63
 .......
 家长签名: 
我这次排名38----
家长签名为:爸爸

 

 以高兴,爽快的签了名。嘿嘿,我理解的运用到的里氏替换原则在Father类注释也说明了。

 

 

 

 

 

分享到:
评论
1 楼 空谷悠悠 2010-07-09  
作者在讲到装饰模式有一个非常好的优点时,就提到了扩展性非常好。而又提到了Java编程中,子类父类的层次结构最好不要超过2层,这一点好理解,但是装饰模式不也同样采用是通过继承来扩展功能吗?假如功能多了,子类父类的层次结构不同样会复杂吗?为何不使用桥梁模式呢?开始接触装饰模式时,我就抱着深深的怀疑的态度看着它,通过这个例子,最后总算弄明白了。
这里我们在修饰schoolReport时,并没有直接继承SchoolReport类,而是通Decorator修饰类来包装SchoolReport,假如我们要添加功能如显示最高成绩,我们可以继承Decorator生成HighScoreDecorator,然后包装SchoolReport,再继续增加功能如排名,我们同样在Decorator基础上派生出SortDecorator类,来包装SchoolReport。你会发现,不管我们增加多少功能,这些派生出来的类都是Decorator的子类,整个层次结构并为增加,这样为以后的维护也方便多了

相关推荐

    里氏替换原则Demo

    总结一下,里氏替换原则是面向对象设计中的关键原则,它指导我们如何正确地使用继承,避免因滥用而导致的代码耦合和错误。遵循LSP,我们的代码会更加灵活、可维护,并能更好地适应需求的变化。在实际编程中,我们...

    第二十八讲:基础三里氏代换原则

    LSP规定,在一个软件系统中,如果一个软件实体(如类、对象或接口)可以被它的子类型替换而不影响程序的正确性,那么我们就说这个子类型遵循了三里氏代换原则。换句话说,子类型的实例必须能够完全替代其基类型,...

    设计模式(23种)与设计原则(6种)

    9. **装饰模式**:动态地给一个对象添加一些额外的职责,既扩展了功能,又保持了接口的一致性。 10. **门面模式**:提供一个统一的接口,用来访问子系统的一组接口。 11. **享元模式**:使用共享对象,有效支持大量...

    Java23种设计模式6大原则总结.doc

    里氏替换原则是指子类可以继承父类的方法和属性。其优点是代码共享,减少创建类的工作量,提高代码的可重用性和可扩展性,提高产品或项目的开放性。 依赖倒置原则是指高层模块不应该依赖低层模块,两者都依赖其抽象...

    剖析设计模式与设计原则

    3. 里氏替换原则(LSP):子类型必须能够替换它们的基类型,且程序的行为不会发生变化。这是多态性的基础。 4. 接口隔离原则(ISP):客户端不应该被迫依赖它不使用的方法。提倡创建更小、更专一的接口,而不是大的...

    设计模式2-结构型模式&设计模式基本原则

    3. **里氏替换原则**:子类必须能够替换掉它们的基类,而不影响程序的正确性。 4. **依赖倒置原则**:依赖于抽象,不要依赖于具体实现。 5. **接口隔离原则**:客户端不应该依赖它不需要的接口;一个类对另一个类的...

    第03章 从架构层面看设计模式01.pdf

    在设计模式中,有几个核心原则需要遵循,即单一职责原则、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、合成复用原则和迪米特法则。这些原则指导我们如何构建更加灵活、可扩展的系统。 单一职责原则强调一...

    设计模式实例讲解

    这些原则包括单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)和依赖倒置原则(DIP)。单一职责原则强调一个类只应有一个引起其变化的原因;开闭原则意味着软件实体应对扩展开放,...

    design-pattern-java-2 设计模式-java版

    里氏替换原则强调程序中的基类应该能够被子类所替换;依赖倒置原则要求依赖于抽象,不要依赖于具体类;接口隔离原则要求应该将大的接口拆分为小的和更具体的接口;迪米特法则强调最少知道原则,降低类之间的耦合度;...

    设计模式面试专题.zip

    - 理解并能解释设计原则,如开闭原则、依赖倒置原则、里氏替换原则等,它们是设计模式的基础。 - 了解并能够讨论面向切面编程(AOP)和设计模式的关系。 通过深入学习和掌握这些设计模式,不仅可以提升你在面试中的...

    JAVA设计模式(java设计)

    通过对这些设计模式的学习和应用,开发者能够更好地理解软件设计的原则,如单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则和接口隔离原则。这有助于编写出更具弹性、易于理解和维护的代码。在实际项目中,...

    Java与模式.pdf

    书中还会讨论到面向对象设计的原则,如单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)和依赖倒置原则(DIP)。这些原则是指导良好代码设计的基石,遵循它们可以使代码更加灵活、...

    设计模式C#版

    里氏代换原则指出,在软件中,如果一个父类可以被替换成它的子类,而程序的行为不会发生变化,那么这些子类就可以被看作父类的类型。LSP有助于增强程序的健壮性,是多态和继承的基础。 八、依赖倒置原则(DIP) 依赖...

    java与模式

    当我们谈到Java与模式时,也离不开面向对象设计的原则,如单一职责原则、开闭原则、里氏替换原则、依赖倒置原则和接口隔离原则。这些原则指导我们写出更符合设计模式精神的代码。 在实际开发中,我们需要根据项目...

    设计模式相关资料

    1. **设计原则**:设计模式的基础是面向对象设计的七大原则,包括单一职责原则(SRP)、开放封闭原则(OCP)、里氏替换原则(LSP)、接口隔离原则(ISP)、依赖倒置原则(DIP)、迪米特法则(LoD)和合成复用原则。...

    软件开发方法与环境--设计模式(ppt)

    - 它们基于面向对象设计原则,如单一职责原则、开闭原则、里氏替换原则、依赖倒置原则和接口隔离原则。 2. **设计模式的分类**: - 创建型模式:如单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式,它们...

    设计模式课件

    它们体现了面向对象设计原则,如单一职责原则(Single Responsibility Principle, SRP)、开闭原则(Open-Closed Principle, OCP)、里氏替换原则(Liskov Substitution Principle, LSP)、依赖倒置原则(Dependency...

    java与模式 源代码

    7. **面向对象原则**:设计模式通常遵循面向对象的四大原则——单一职责原则、开闭原则、里氏替换原则和依赖倒置原则。这些原则在源代码中得到体现,可以帮助开发者养成良好的编程习惯。 8. **软件设计**:设计模式...

    24种设计模式介绍与6大设计原则

    3. 里氏替换原则:子类必须能够替换掉它们的基类,而不影响程序的正确性。 4. 接口隔离原则:客户端不应该依赖它不需要的接口,接口应尽量小且具有针对性。 5. 依赖倒置原则:依赖于抽象而不是具体实现,高层模块不...

Global site tag (gtag.js) - Google Analytics