`
TheMatrix
  • 浏览: 7357 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
最近访客 更多访客>>
社区版块
存档分类
最新评论

一个简单的装饰器类

阅读更多

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gnuhpc/archive/2009/10/21/4710427.aspx

 

“三明治”的例子:三明治必不可少的是两块面包片,然后可以在夹层里加上蔬菜、沙拉、咸肉等等,外面可以涂上奶油之类的。假如现在你要为一个三明治小店构造一个程序,其中要设计各种三明治的对象。可能你已经创建了一个简单的Sandwich对象,现在要产生带蔬菜的就是继承原有的Sandwich添加一个蔬菜的成员变量,看起来很“正点”的做法,以后我还要带咸肉的、带奶油的、带蔬菜的又分为带青菜的、带芹菜的、生菜的……还是一个一个继承是吧!假如我们还需要即带蔬菜又带其它肉类,设置我们还要求这些添加成分的任意组合,那你就慢慢继承吧!下面我们就使用装饰器模式来设计这个库吧!下图是我们的设计图:

 

下面是以上各个类的意义:

1. Ingredient(成分):所有类的父类,包括它们共有的方法,一般为抽象类且方法都有默认的实现,也可以为接口。它有Bread和Decorator两个子类。这种实际不存在的,系统需要的抽象类仅仅表示一个概念,图中用红色表示。

2. Bread(面包):就是我们三明治中必须的两片面包。它是系统中最基本的元素,也是被装饰的元素,和IO中的媒质流(原始流)一个意义。在装饰器模式中属于一类角色,所以其颜色为紫色。

3. Decorator(装饰器):所有其它成分的父类,这些成分可以是猪肉、羊肉、青菜、芹菜。这也是一个实际不存在的类,仅仅表示一个概念,即具有装饰功能的所有对象的父类。图中用蓝色表示。

4. Pork(猪肉):具体的一个成分,不过它作为装饰成分和面包搭配。

5. Mutton(羊肉):同上。

6. Celery(芹菜):同上。

7. Greengrocery(青菜):同上。

总结一下装饰器模式中的四种角色:1.被装饰对象(Bread);2.装饰对象(四种);3.装饰器(Decorator);4.公共接口或抽象类(Ingredient)。其中1和2是系统或者实际存在的,3和4是实现装饰功能需要的抽象类。

写段代码体会其威力吧!(程序很简单,但是实现的方法中可以假如如何你需要的方法,意境慢慢体会吧!)

//Ingredient.java

public abstract class Ingredient {

public abstract String getDescription();

public abstract double getCost();

public void printDescription(){

System.out.println(" Name "+ this.getDescription());

System.out.println(" Price RMB "+ this.getCost());

}

}

所有成分的父类,抽象类有一个描述自己的方法和一个得到价格的方法,以及一个打印自身描述和价格的方法(该方法与上面两个方法构成模板方法哦!)

//Bread.java

public class Bread extends Ingredient {

private String description ;

public Bread(String desc){

this.description=desc ;

}

public String getDescription(){

return description ;

}

public double getCost(){

return 2.48 ;

}

}

面包类,因为它是一个具体的成分,因此实现父类的所有的抽象方法。描述可以通过构造器传入,也可以通过set方法传入。同样价格也是一样的,我就很简单地返回了。

//Decorator.java

public abstract class Decorator extends Ingredient {

Ingredient ingredient ;

public Decorator(Ingredient igd){

this.ingredient = igd;

}

public abstract String getDescription();

public abstract double getCost();

}

装饰器对象,所有具体装饰器对象父类。它最经典的特征就是:1.必须有一个它自己的父类为自己的成员变量;2.必须继承公共父类。 这是因为装饰器也是一种成分,只不过是那些具体具有装饰功能的成分的公共抽象罢了。在我们的例子中就是有一个Ingredient作为其成员变量。Decorator继承了Ingredient类。

//Pork.java

public class Pork extends Decorator{

public Pork(Ingredient igd){

super(igd);

}

public String getDescription(){

String base = ingredient.getDescription();

return base +"\n"+"Decrocated with Pork !";

}

public double getCost(){

double basePrice = ingredient.getCost();

double porkPrice = 1.8;

return basePrice + porkPrice ;

}

}

具体的猪肉成分,同时也是一个具体的装饰器,因此它继承了Decorator类 。猪肉装饰器装饰可以所有的其他对象,因此通过构造器传入一个Ingredient的实例,程序中调用了父类的构造方法,主要父类实现了这样的逻辑关系。同样因为方法是具体的成分,所以getDescription得到了实现,不过由于它是具有装饰功能的成分,因此它的描述包含了被装饰成分的描述和自身的描述。价格也是一样的。价格放回的格式被装饰成分与猪肉成分的种价格哦!

从上面两个方法中我们可以看出,猪肉装饰器的功能得到了增强,它不仅仅有自己的描述和价格,还包含被装饰成分的描述和价格。主要是因为被装饰成分是它的成员变量,因此可以任意调用它们的方法,同时可以增加自己的额外的共同,这样就增强了原来成分的功能。

//Mutton.java

public class Mutton extends Decorator{

public Mutton(Ingredient igd){

super(igd);

}

public String getDescription(){

String base = ingredient.getDescription();

return base +"\n"+"Decrocated with Mutton !";

}

public double getCost(){

double basePrice = ingredient.getCost();

double muttonPrice = 2.3;

return basePrice + muttonPrice ;

}

}

羊肉的包装器。

//Celery.java

public class Celery extends Decorator{

public Celery(Ingredient igd){

super(igd);

}

public String getDescription(){

String base = ingredient.getDescription();

return base +"\n"+"Decrocated with Celery !";

}

public double getCost(){

double basePrice = ingredient.getCost();

double celeryPrice =0.6;

return basePrice + celeryPrice ;

}

}

芹菜的包装器。

//GreenGrocery.java

public class GreenGrocery extends Decorator{

public GreenGrocery (Ingredient igd){

super(igd);

}

public String getDescription(){

String base = ingredient.getDescription();

return base +"\n"+"Decrocated with GreenGrocery !";

}

public double getCost(){

double basePrice = ingredient.getCost();

double greenGroceryPrice = 0.4;

return basePrice + greenGroceryPrice ;

}

}

青菜的包装器。

下面我们就领略装饰器模式的神奇了!我们有一个测试类,其中建立夹羊肉的三明治、全蔬菜的三明治、全荤的三明治。
public class DecoratorTest{

public static void main(String[] args){

Ingredient compound = new Mutton(new Celery(new Bread("Master24's Bread")));

compound.printDescription();

compound = new Celery(new GreenGrocery(new Bread("Bread with milk")));

compound.printDescription();

compound = new Mutton(new Pork(new Bread("Bread with cheese")));

compound.printDescription();

}

}

以上就是一个简单的装饰器类。

 

分享到:
评论

相关推荐

    TypeScript装饰器定义 类装饰器 属性装饰器 装饰器工厂.zip

    下面是一个简单的类装饰器示例: ```typescript function logClass(target: any) { console.log(`Class ${target.name} has been decorated.`); } @logClass class MyClass {} ``` 在这个例子中,`logClass`是一...

    Node.js-Node.js的简单路由器ES7装饰器

    在本教程中,我们将深入探讨如何使用ES7装饰器(Decorator)来创建一个简单的Node.js路由器。装饰器是一种元编程特性,允许我们在不修改源代码的情况下,为对象、类或方法添加额外的行为或属性。 ### ES7装饰器简介...

    一个简单的C#类生成器

    "一个简单的C#类生成器"项目就是这样的尝试,它旨在帮助C#程序员快速生成基础的类结构,从而减少手动编写代码的工作量。这个类生成器是用C#语言编写的,体现了C#的面向对象特性和强大的文本处理能力。 C#是一种广泛...

    python类装饰器装饰方法通用编码模型分析.pdf

    装饰器的基本原理是使用高阶函数(即一个函数接收另一个函数作为参数的函数),并且利用闭包(一个函数返回另一个函数)的特性来实现。当装饰器应用于函数时,它本质上是用新函数替代了原函数,新函数内部调用了原...

    装饰器模式的简单demo

    例如,`CarDecorator.java`可能是一个通用的装饰器类。 4. 具体装饰器(Concrete Decorator):具体装饰器是装饰器的子类,负责增加特定的功能。`ZhenpiCar.java`、`RoundCar.java`和`TangCar.java`可能分别代表装有...

    Decor,android布局装饰器:在布局文件中注入自定义属性,使用装饰器消除带有自定义视图的不必要的类爆炸。.zip

    1. **定义装饰器(Decorator)**:开发者需要创建一个实现了`com.h6ah4i.android.widget.decor.ViewDecorator`接口的类,这个类包含了如何应用自定义属性的逻辑。 2. **注册装饰器(Register Decorator)**:在应用...

    装饰器模式实现简单demo

    下面是一个简单的装饰器模式实现示例,假设我们有一个`AndroidView`接口,代表Android中的视图组件,以及一个`TextView`类作为具体组件: ```java public interface AndroidView { void display(); } public ...

    设计模式-装饰器模式

    博客链接中提到的简单解释可能涵盖了如何创建装饰器类以及如何使用它来包装原始对象的基本步骤。通常,装饰器模式包含以下几个关键组件: 1. 抽象组件(Component):定义了被装饰对象的接口。所有对象(包括原始...

    基于JavaScript装饰器Decorator实现的通信库

    装饰器的这种特性使得它成为现代JavaScript开发中的一个强大工具,尤其是在处理复杂应用程序架构时,如单页应用(SPA)或微服务架构。 总的来说,eventbus-cjs利用JavaScript装饰器提供的元编程能力,为Vue、React和...

    JAVA设计模式学习12——装饰器模式

    例如,我们可以创建一个基础的业务服务类,然后通过装饰器为其添加日志记录、事务处理等附加功能。 至于给出的标签“源码”和“工具”,在学习装饰器模式时,阅读源码可以帮助理解如何在实际项目中应用该模式。同时...

    Python-rediscache一个Redis的缓存装饰器

    装饰器是Python编程中的一个重要概念,它允许我们修改或增强函数、类等对象的行为,而无需改变其源代码。在"Python-rediscache"中,装饰器用于在函数调用前检查是否有缓存结果,如果有则直接返回,无则执行函数并...

    django如何通过类视图使用装饰器

    首先,我们需要创建一个简单的装饰器来检查客户端IP是否存在于黑名单中。如果存在,则返回一个错误消息,阻止进一步处理。 ```python from functools import wraps from django.http import HttpResponse def ban_...

    装饰器模式 完整示例代码

    下面是一个简单的装饰器模式示例: ```python # 具体组件 (Concrete Component) class SimpleEditor: def write(self, text): print(f'编写: {text}') # 装饰器 (Decorator) class EditorDecorator: def __init...

    带你了解python装饰器

    例如,下面是一个简单的类装饰器实现: ```python class MyDecorator: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print("Before the function call") result = self...

    Python高级特性深入解析:装饰器与迭代器的应用

    首先探讨了装饰器的基本概念、作用以及如何创建和使用装饰器,包括简单装饰器、带参数的装饰器、多重装饰器和类装饰器。接着介绍了迭代器的定义及其与可迭代对象的区别,讲解了如何创建自定义迭代器,以及生成器的...

    7. 装饰器模式1

    例如,一个简单的日志装饰器可以记录函数的执行时间,或者统计函数的调用次数。 装饰器模式的本质是通过类的继承和实例化,构建出一个对象的“套娃”结构,每个装饰类都包含一个原对象的引用,这样就可以在保持原...

    Android装饰模式demo

    在"Android装饰模式demo"中,我们可以看到一个简单的实现,帮助开发者理解这一模式。UML(统一建模语言)图通常会被用来表示类之间的关系,以便更直观地展示装饰模式的结构。在提供的博客文章链接...

    python 装饰器(示例)

    在Python中定义一个装饰器非常简单,下面是一个基础的装饰器示例: ```python def simple_decorator(func): def wrapper(): print("Before function call.") func() print("After function call.") return ...

    通过C#实现设计模式-装饰模式(DecoratorPattern).rar

    假设我们有一个简单的Component接口和一个具体的ConcreteComponent类,以及几个装饰器类。 1、首先,我们定义一个Component接口。 2、实现一个具体的组件ConcreteComponent。 3、定义一个抽象的装饰器类Decorator,...

    PHP简单装饰器模式实现与用法示例

    PHP简单装饰器模式实现与用法示例中,主要讲解了如何利用装饰器模式在不修改原有类代码的基础上,为类添加新的功能。装饰器模式是一种结构型设计模式,其主要目的是增强一个类的功能,而不需要改变类本身。这种模式...

Global site tag (gtag.js) - Google Analytics