装饰模式

装饰者模式简述

强颜欢笑 提交于 2020-02-04 11:53:28
装饰者模式 装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。 我们通过下面的实例来演示装饰者模式的用法 注意 要实现装饰者模式,注意以下几点内容: a.装饰者类要实现真实类同样的接口 b.装饰者类内有一个真实对象的引用(可以通过装饰者类的构造器传入) c.装饰者类对象在主类中接受请求,将请求发给真实的对象(相当于已经将引用传递到了装饰类的真实对象) d.装饰者可以在传入真实对象后,增加一些附加功能(因为装饰对象和真实对象都有同样的方法,装饰对象可以添加一定的操作在调用真实对象的方法,或者先调用真实对象的方法,再添加自己的方法) e.不用继承 示例 生产馒头的示例 假设要制造添加糖和玉米面的馒头: 需要一个正常的馒头 添加玉米面和糖 和面,最后生产出馒头 馒头接口 package waking . test . zs ; /** * 馒头的接口 * @author waking * */ public interface IBread { void prepare ( ) ; //准备 void kneadFlour ( ) ; //和面 void steamed ( )

设计模式3——装饰者模式

左心房为你撑大大i 提交于 2020-02-03 08:59:34
定义:动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加弹性的解决方案。 1 引例_咖啡订单系统 1.1 最初设计。 如图1,首先创建一个Bevarage(饮料)的抽象类,店内所有的咖啡都继承这个类。description是成员变量,由子类设置,描述咖啡使用。 getDescription() 就是返回这个描述。 cost() 方法是抽象方法,由子类实现,计算价格使用。 最开始咖啡就有如下4个(对咖啡不太了解,中文名字错了不要在意):DarkRoast(超优深焙咖啡),Espresso(浓缩咖啡),Decaf(低卡咖啡),HouseBlend(混合咖啡) 但客人要求在咖啡里添加调料:Milk(奶),Soy(豆浆),Mocha(摩卡),每种调料都有单独的价钱,所以设计上又添加了这些,如图2。 这里我们可以看出问题,图2中只是列出了三种组合,我们可以想一下,这种组合是由很多种的,现在是4款咖啡,3种调料,在考虑到以后,可定会推出更多的咖啡和各种调料。这样维护起来,类会爆炸的,而且有的人还喜欢double份的Mocha,这样算的话类就会无穷无尽,而且物价是波动的,你还会修改价格,这样维护起来会死人的。 1.2 进一步改进 如图3,这次将调料加入 Bevarage 中的成员变量中,并加入相应的has和set方法, cost() 方法现在提供实现,计算出调料的价格

Java设计模式-装饰者模式

两盒软妹~` 提交于 2020-02-02 09:49:30
一、概述 装饰者模式指的是在不必改变原来类文件和使用继承的情况下, 动态地扩展一个对象 的功能。它是通过创建一个包装对象,也就是装饰者来包裹真实的对象。 二、角色 抽象构件(Component) :是一个接口或者抽象类,就是定义最核心的对象,也就是最原始的对象 具体构件(Concrete Component) :是Component的实现,被装饰者 抽象装饰(Decorator) :一般是一个抽象类,持有一个private的Componet对象 具体装饰(Concrete Decorator) :把最核心的、最原始的、最基本的东西装饰成其他东西 三、装饰者模式 1.抽象构件 /** * 抽象构建角色(对应动物类) */ public interface Animal { void function(); } 2.具体构件 /** * 具体构建角色(对应狗) */ public class Dog implements Animal { @Override public void function() { System.out.println("基本功能:呼吸+睡觉"); } } 3.抽象装饰 /** * 装饰角色 */ public class AnimalDecorator implements Animal { // 持有一个Component类型的对象引用 private

Decorator Pattern (装饰者模式)

℡╲_俬逩灬. 提交于 2020-02-02 09:25:09
装饰者模式( Decorator Pattern ) 意图 : 动态的给一个对象添加一些额外的功能,IO这块内容体现出了装饰模式,Decorator模式相比生成子类更为灵活。 角色 : 1)抽象构件角色(Component)--- 定义成一个接口类型 2)具体构件角色 (ConcreteComponent) --- 该类(被装饰者)实现了 Component 接口, 3)装饰角色 (Decorator) --- 该类实现了 Component 接口,并持有 Component接口的引用 4)具体装饰角色 (ConcreteDecorator) --- 该类继承了装饰类 UML实现: 代码实现: Component.java package com.decorator ; //抽象构件角色 public interface Component { public void operation() ; } ConcreteComponent.java package com.decorator ; //具体构件角色 public class ConcreteComponent implements Component { public void operation() { System.out.println("实现功能A") ; } } Decorator.java package

装饰模式(Decorator Pattern)

走远了吗. 提交于 2020-02-01 19:50:40
动态或者静态地为一个对象附加一个职责或者功能,称为装饰模式。它是属于结构设计模式之一,比较常用。 使用场合和优势: 为子类提供了一个可选项。 在不影响其它对象的前提下,给一个对象添加一个新方法。 很容易动态地添加和删除某个 职责。 比静态继承更具有灵活性。 对于对象来说是透明的。 下列UML类图展示了装饰模式的经典实现模型。 我们将要定义一个 Shape接口和图的实现类。之后,我们创建抽象装饰类ShapeDecorator,它实现了Shape接口。 RedShapeDecorator 是 ShapeDecorator的扩展类, DecoratorPatternDemo则是对这个模式的测试类 . UML类图如下所示。 定义Shape接口. public interface Shape { void draw(); } Shape的子类Circle、Rectangle. public class Rectangle implements Shape { @Override public void draw() { System.out.println("Shape: Rectangle"); } } public class Circle implements Shape { @Override public void draw() { System.out.println(

c#设计模式之装饰器模式(Decorator Pattern)

那年仲夏 提交于 2020-02-01 14:32:27
引子 在面向对象语言中,我们常常会听到这样一句话:组合优于继承.那么该如何去理解这句话呢? 下面我将以游戏装备为模型用简单的代码去展示它 先创建一个装备的抽象类,然后创建刀枪2个具体的业务子类 1 public abstract class AbstractEquipment 2 { 3 public int Id { get; set; } 4 5 public string Name { get; set; } 6 7 public abstract void Attack(); 8 } 9 10 public class Gun : AbstractEquipment 11 { 12 public override void Attack() 13 { 14 Console.WriteLine("用枪攻击"); 15 } 16 } 17 18 class Sword : AbstractEquipment 19 { 20 public override void Attack() 21 { 22 Console.WriteLine("用剑攻击"); 23 } 24 } 面对这样的场景,我们常常会提出这样的疑问:如何面对业务扩展?例如,此时需要添加一个新的功能:在装备攻击后,会提醒善恶值增加 在不修改业务子类的前提下,我们通过继承和组合两种不同的方式来解决,如下: 1 //继承

设计模式学习02

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-31 04:52:23
3.1 结构型模式 3.1.1 适配器模式 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。 实际就是解决接口不兼容的问题,可以通过第三方的类来解决这个问题。具体实现:适配类实现新接口,重写方法,在重写的方法中调用老接口实现类的方法,完成新老接口的适配操作 3.1.2 桥接模式 桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。我们通过下面的实例来演示桥接模式(Bridge Pattern)的用法。其中,可以使用相同的抽象类方法但是不同的桥接实现类,来画出不同颜色的圆。 实际是将抽象和实现进行分离,两者之间是关联关系而不是继承关系,抽象类和实现类独立,做到低耦合。 3.1.3 过滤器模式 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern

Coding-21-装饰器模式

為{幸葍}努か 提交于 2020-01-30 20:17:19
  实现一个同样功能可以有各种方法,功能简单时需要考虑的只有效率和可读性,功能复杂时就需要额外考虑扩展性。在设计程序时,使用合适的设计模式,不仅可以解决扩展性问题,还可以让程序结构更符合人类的思维直觉,富有艺术感。   这里介绍并实现了 装饰器模式 。   装饰器模式的说明是:动态地将责任(或功能)附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。   Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality. Talk is cheap, show me code   以 HTML 的渲染为例,对一段文本 “hello world” 进行渲染,例如加黑、加斜体。 Python 的装饰器 # 加黑装饰器 def renderbold(func): def wrapped(): return "<b>" + func() + "</b>" return wrapped # 加斜体装饰器 def renderitalic(func): def wrapped(): return "<i>"

装饰模式(Decorate Pattern)

不想你离开。 提交于 2020-01-30 12:55:20
装饰模式(Decorate Pattern) 描述:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的代替方案 注意:装饰者和被装饰者必须是一样的类型 缺点:利用装饰着模式,常常造成设计中有大量的小类,可能会造成使用此API程序员的困扰 代码举例: class Beverage { public : virtual std :: string getDescription ( ) ; virtual float cost ( ) ; } class DarkRoast : public Beverage { public : virtual std :: string getDescription ( ) { return "DarkRoast" ; } virtual float cost ( ) { return 1.0 ; } } class CondimentDecorator : public Beverage { public : CondimentDecorator ( Beverage * pBeverage ) ; virtual std :: string getDescription ( ) ; virtual float cost ( ) ; Beverage * m_pBeverage ; } class Milk : public

Python 简单入门指北(二)

六眼飞鱼酱① 提交于 2020-01-30 08:50:22
Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值。总而言之,函数和普通变量并没有什么区别。 函数是一等公民,这是函数式编程的基础,然而 Python 中基本上不会使用 lambda 表达式,因为在 lambda 表达式的中仅能使用单纯的表达式,不能赋值,不能使用 while、try 等语句,因此 lambda 表达式要么难以阅读,要么根本无法写出。这极大的限制了 lambda 表达式的使用场景。 上文说过,函数和普通变量没什么区别,但普通变量并不是函数,因为这些变量无法调用。但如果某个类实现了 __call__ 这个魔术方法,这个类的实例就都可以像函数一样被调用: class Person: def __init__(self): self.name = 'bestswifter' self.age = 22 self.sex = 'm' def __call__(self): print(self) def __str__(self): return 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=self) p = Person() p() # 等价于 print(p)