扩展功能==继承?

学过面向对象的我们都知道,通过继承:能够重用和扩展已经被彻底测试过的代码,且无需修改之。但就像策略模式中所讲到的,继承会禁锢类的方法。那么如果要扩展功能,我们还是必须使用继承吗?

答案当然是否定的,因为设计模式中为我们提供了一个很好的模式--装饰模式:动态地将责任附加到对象上。这里所谓的动态可以简单理解为灵活。那么不使用继承,又要如何帮助我们达到目的呢?下面一起来看。

先来看一个例子,我们去咖啡店买咖啡,光咖啡类型就有不同的选择:综合、深焙、低咖啡因、浓缩。但喝咖啡可没这么简单,它还需要加入相应的配料来满足顾客口味需求:牛奶、豆浆、摩卡、奶泡。现在咖啡店要增加一些新口味和类型,那么原先使用继承的系统将不再适用,一旦增加的类型和种类增多下面的这张图就变成一坨了吧:

那么使用装饰模式应该是什么样的呢?

像上面这幅图显示的这样,我们将具体的咖啡类型和配料都作为一个类的子类,通过类型和配料的自由组合实现功能的同时实现代码的复用性,提高后期的可维护性。其代码如下:

1.抽象类

<span style="font-size:18px;">package 巴兹咖啡;
//这是一个抽象类。
public abstract class Beverage {
	String description ="Unknown Beverage";

	public String getDescription (){
		//获取咖啡调配方法
		return description;
	}

	public abstract double cost();
}
</span>

2.具体组件

public abstract class CondimentDecorator extends Beverage {
	public abstract String getDescription();
}

public class DarkRoast extends Beverage {

	public DarkRoast() {
		description ="DarkRoast Coffee";
	}

	public double cost(){
		return .99;
	}

}
</span>
public class Espresso extends Beverage {

	public Espresso ()
	{
		description ="Espresso";
	}

	public double cost(){
		return 1.99;
	}
}
public class HouseBlend extends Beverage {
	public HouseBlend(){
		description ="House Blend Coffee";
	}

	public double cost(){
		return .89;
	}
}
</span>

其他几个类和上面列举的类似,大家可以动手实现。最终会实现下面的效果:

如果店内有需求,要实现杯型大小来进行收费,那么我们可以在CondimentDecorator中添加中杯、小杯、大杯三个类,抽象类中添加方法:getSize()对杯型进行获取,然后通过杯型、咖啡类型和配料的不同搭配来实现灵活收费。这样一来也就实现了动态的添加的同时也达到了解耦的效用。岂不是一举两得?

总结:

1.装饰模式中使用组合和委托在系统运行时对系统动态的增加功能。而该模式也就意味着我们要创建一堆的装饰者类,而它们又恰好是用来装饰组件的,比如:Mocha、Whip等四个配料都是用来装饰HouseBlend、 DarkRoast这
些咖啡类型的。

2.我们可以使用一个或者多个装饰者包装一个组件:调配出一个中杯的,加入牛奶、摩卡等的低咖啡因咖啡。

3.装饰者会导致设计中出现许多小对象,如果过度使用,程序依旧会变得复杂。也就是说,我们不能将咖啡的类型和配料的种类无限的扩张,否则系统会因为过多的咖啡种类和配料而运行缓慢甚至瘫痪。凡事遵循一个度的问题,东西再好吃也不能撑死,模式再好用也不能拖死系统。

所以说,在一定程度上,装饰者模式还是很棒的呢。

最后祝大家软考顺利,考试加油,let‘s  go !!

时间: 2024-10-27 02:36:39

扩展功能==继承?的相关文章

抽象类 接口 多态

一 抽象类(abstract) 抽象类的概念只抽取了很多类的方法的声明,方法声明用abstract修饰.一个类如果有抽象方法,那么这个类必须是抽象类.抽象类里边可以没有抽象方法,如果这么做只有一个目的:不让你创建这个类的对象.抽象类不能被实例化,不能创建对象.如果一个类继承抽象类,那么,它要么重写抽象类中的所有抽象方法,要么本身也是抽象类. 抽象类的成员成员变量:可以是常量,也可以是变量.子类可以直接继承抽象类中的成员变量.成员方法:可以是抽象的,也可以是非抽象的.抽象方法在子类中必须要被实现.

Android(java)学习笔记204:自定义SmartImageView(继承自ImageView,扩展功能为自动获取网络路径图片)

1.有时候Android系统配置的UI控件,不能满足我们的需求,Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高. 2.下面我们是自定义一个SmartImageView继承自ImageView,扩展了ImageView的功能:     步骤: • 新建一个SmartImageView类,让继承自ImageView(放置特定的包下): • 实现SmartImageView类下的构造方法,最好全部实现,这个不容易出

java特性之继承

继承这一特性是面向对象的重要概念,好处就是提高代码的复用,节约开发时间. 在java中继承是指在父类的基础上扩展功能,继承中分为子类和父类. 类有两种重要成员:成员变量和方法. java中子类通过关键字extends可以获得父类的成员变量和方法.子类的成员中可以有自己声明定义的变量,也有从父类继承的. java中继承的特点: 1.单根继承,向上只有一个节点,所有的类继承的根节点都是Object类. 2.java不支持多继承.一个类不能同时继承多个类*(可以实现多喝接口). 3.子类重写父类的方法

继承NSString,NSArray 怎么写

今天在进行一个字符串测试的时候,自定义了一个继承自NSString的类,但是出现了一些问题,查阅官方文档后得到了下面这些结论 在Objective-C中,对于NSString.NSArray等一些系统的基础类,苹果公司不推荐继承创建新类的,要想给它们扩展功能只能给它们添加新的categroy(类目). 但是直接继承的话,也是可行的,只是会出现各种问题 以NSString为例 首先,创建一个NSString的子类 BFString,不添加任何方法和属性 直接创建一个BFString的实例对象,是没

C++基础之三大特性之继承的本质(要当就当富二代,否则自己动手才能丰衣足食)

继承,正如字面意思可以理解,拿到财产,不过不是先人故去的时候才能拿到,在写这篇博文前看了会书,快看的睡着了就直接动手写吧,感觉看书没有什么收获,果然实践才是出真知 继承 继承的方式:private(默认).public.protect(区别:子类中能不能用到,子类对象可不可以访问的到,一般我用的public,其他的用不到,我不再这赘述,有需求百度就可以了) 继承后的结果:1.得到父类的财产(变量,不论是公有私有还是保护的):2.访问到父类的所有(变量和函数)----说的是public继承方式,其

smartjs 0.2 OOP讲解 - Klass 类继承

SmartJS2.0加入OOP的功能.OOP包括klass与factory两个对象. Klass 类继承 与其他的类继承相比,smartjs使用了执行指针的概念(后面例子中会介绍),另外提供base基类和初始化控制的扩展功能. 首先来看看接口: var _klass = st.klass(name, prop, parent, config); //new _klass() 与 _klass()效果相同,实现了自初始化功能更 var obj = new _klass(); name : 类名 p

2015/9/22 Python基础(18):组合、派生和继承

一个类被定义后,目标就是把它当成一个模块来使用,并把这些对象嵌入到你的代码中去,同其他数据类型及逻辑执行流混合使用.有两种方法可以在你的代码中利用类.第一种是组合,就是让不同的类混合并加入到其他类中,来增强功能和代码重用性.你可以在一个大点的类中创建你自己的类的实例,实现一些其他属性和方法来增强原来的类对象.另一种是派生,通过子类从基类继承核心属性,不断地派生扩展功能实现. 组合举例来说,我们想对之前做过的地址本类作加强性设计.如果在设计的过程中,为names.addresses等创建了单独的类

黑马程序员——Java基础——面向对象——继承、抽象类、接口、多态、包、内部类、异常等

第一讲 继承 1.继承: 当多个类拥有相同的功能时,那么这些类不需要每个都写这些相同的功能,只需要把相同功能抽到 一个单独的类中,继承这个类就能获得这些相同的功能: (1)继承的体系结构:就是对要描述的事物进行不断的向上抽取,就出现了体系结构. 要了解这个体系结构中最共性的内容,就看最顶层的类. 要使用这个体系的功能,就用最底层的类创建对象 (2)好处: A.提高代码复用性: B.继承的出现,让类与类之间产生关系,为多态的前提 (3)特点: A.只能单继承(准确的说是java对多继承进行优化,避

多态&amp;抽象&amp;继承

多态 package cn.itcast.extend; public class ExtendDemo2 { public static void main(String[] args) { A a=new B();//多条 System.out.println(a.num); a.show();//非静态 a.say();//静态方法 } } class A{ int num=10; //静态方法 public static void say(){ System.out.println("父