装饰器模式
设计模式:常用设计模式及其应用
设计模式:常用设计模式及其应用设计模式是在软件设计中常见问题的解决方案的一种反复使用的经验总结。
它们是已经被证明有效的经典解决方案,可以帮助我们在开发过程中避免重复设计。
本文将介绍一些常用的设计模式及其应用。
1.单例模式单例模式是一个创建型的设计模式,它会确保一个类只有一个实例。
这在需要共享资源或控制唯一资源访问的场景下非常实用,例如线程池、日志记录器等。
2.工厂模式工厂模式是一种用于创建对象的创建型设计模式。
它定义了一个接口来创建对象,但将创建实例的过程延迟到子类中。
这样可以避免在代码中直接使用new操作符,增加了代码的灵活性和可维护性。
3.观察者模式观察者模式是一种行为型的设计模式,它定义了一对多的依赖关系。
当一个对象的状态发生变化时,它会自动通知它的依赖对象。
观察者模式常用于事件处理、GUI编程等场景。
4.装饰器模式装饰器模式是一种结构型的设计模式,它允许你通过将对象包装在一个装饰器对象中来动态地添加新的功能。
装饰器模式可以避免使用子类化的复杂性,提供了比继承更加灵活的方式来扩展功能。
5.策略模式策略模式是一种行为型的设计模式,它定义了一系列算法,并将每个算法封装在可以相互替换的策略对象中。
这使得算法可以独立于客户端的使用,提高了代码的灵活性。
6.适配器模式适配器模式是一种结构型的设计模式,它允许不兼容的接口之间进行适配。
适配器模式可以通过创建一个适配器类来实现两个不兼容接口之间的交互。
7. MVC模式MVC(Model-View-Controller)是一种架构模式,它将应用程序分为三个主要部分:模型、视图和控制器。
模型表示应用程序的数据和逻辑,视图负责显示数据,控制器接收用户输入并对模型和视图进行协调。
8.组合模式组合模式是一种结构型的设计模式,它将对象组合成树状结构以表示“整体/部分”层次结构。
组合模式使得用户对单个对象和组合对象的使用具有一致性,可以用来处理树形结构的问题。
9.迭代器模式迭代器模式是一种行为型的设计模式,它提供一种访问容器中各个元素的方法,而不需要暴露容器的内部结构。
面试常见设计模式
面试常见设计模式设计模式是软件开发中常用的一种设计思想,它提供了一种解决问题的方法和模板,帮助开发人员在面对各种复杂问题时能够快速有效地进行设计和开发。
在面试时,设计模式也是面试官经常会问到的一个重要话题。
本文将介绍一些常见的设计模式,并分析其应用场景和优缺点。
1.单例模式单例模式是一种常见的创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。
在多线程环境下,单例模式可以保证线程安全。
单例模式常用于需要共享资源或控制资源访问的场景,比如数据库连接池、线程池等。
2.工厂模式工厂模式是一种创建型设计模式,它定义了一个创建对象的接口,但具体的对象创建由子类决定。
工厂模式可以隐藏对象的创建细节,减少依赖,并且提供了一种可扩展的方式来创建对象。
工厂模式常用于创建复杂对象或对象组合的场景。
3.观察者模式观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,其依赖的对象将自动收到通知并进行相应的处理。
观察者模式可以实现松耦合,增加对象之间的协作和交互。
观察者模式常用于事件驱动、消息通知等场景。
4.策略模式策略模式是一种行为型设计模式,它将一组算法封装成一系列可互换的策略,使得算法的变化独立于使用算法的客户端。
策略模式可以提高代码的可维护性和可扩展性,减少代码的重复和耦合。
策略模式常用于需要根据不同情况选择不同算法的场景。
5.装饰器模式装饰器模式是一种结构型设计模式,它动态地给一个对象添加一些额外的功能,同时又不改变其原有的结构。
装饰器模式可以在不需要子类化的情况下扩展对象的功能,符合开闭原则。
装饰器模式常用于动态地给对象添加新的行为或功能。
6.适配器模式适配器模式是一种结构型设计模式,它将一个类的接口转换成客户端所期望的另一个接口,使得原本不兼容的接口可以一起工作。
适配器模式可以提高代码的复用性和灵活性,减少代码的改动。
适配器模式常用于不同系统之间的接口转换或旧系统的升级迁移。
装饰器模式详解及代码实现
装饰器模式详解及代码实现1. 什么是装饰器模式?装饰器模式是一种结构型设计模式,它允许你在运行时动态地添加行为或修改类功能,而不需要修改原始类的代码。
使用装饰器模式,你可以将对象功能分成单独的部分,然后组合这些部分以创建更加复杂的行为。
装饰器模式是面向对象编程中的一种非常重要的设计模式,也是 Python 语言中广泛使用的一项技术。
2. 装饰器模式的应用场景有哪些?装饰器模式的应用场景很多,下面主要介绍几种典型的情况。
2.1. 在不修改一个对象的前提下,在运行时给对象添加功能。
这个功能可以是动态的,可以在运行时轻松地添加和移除。
例如,你可以动态地向一个已经实例化的对象中添加新的方法和属性。
2.2. 在保持对象的接口和行为不变的前提下,为对象添加功能和行为。
例如,你可以使用装饰器模式为一个基础组件添加缓存、日志记录等功能,而不需要修改组件的代码。
2.3. 作为一种高阶编程技术,利用装饰器模式可以实现函数的函数式编程,使得代码更加简洁、可读性更高。
例如,可以使用装饰器来简洁地实现函数的计时、缓存等功能。
3. 装饰器模式的实现在 Python 中,装饰器主要是通过函数和类来实现的。
下面分别介绍这两种实现方式。
3.1. 使用函数来实现装饰器使用函数来实现装饰器是 Python 中最为常用的实现方式。
下面是一个例子:```pythondef my_decorator(func):def wrapper():print("Before the function is called.")func()print("After the function is called.")return wrapperdef say_hello():print("Hello World!")say_hello = my_decorator(say_hello)# 调用被装饰的函数say_hello()```在这个例子中,首先定义了一个装饰器函数 `my_decorator`,它接受一个函数作为参数。
软件开发中的设计模式及其应用
软件开发中的设计模式及其应用设计模式是由四人带领的软件开发者团队在1994年《设计模式:可复用面向对象软件的基础》一书中提出的。
设计模式是一种被证明有效的解决方案,用于解决面向对象软件设计中的常见问题。
这些模式已被广泛应用于软件开发领域,并被证明可提高软件开发的效率和可重用性。
本文将介绍其中的几种常见设计模式及其应用,以供软件开发者参考。
1.工厂模式工厂模式是一种创建型模式,它提供了一个通用的接口,用于创建对象。
通过使用工厂模式,我们可以隐藏创建对象的实现细节,使得客户端代码无需知道要实例化哪个类。
应用:在开发过程中,我们通常会遇到许多场景需要创建多个对象,而这些对象的创建逻辑可能比较复杂。
在这种情况下,我们可以使用工厂模式来将复杂的对象创建流程进行封装,以简化客户端的代码。
2.单例模式单例模式是一种创建型模式,它确保一个类只有一个实例,并提供全局访问点来访问该实例。
单例模式可以有效地控制全局资源的使用,避免重复创建对象。
应用:单例模式通常适用于多个客户端需要共享相同的资源的情况,例如配置文件、数据库连接对象等全局性的资源。
通过使用单例模式,我们可以避免频繁创建对象,提高资源利用率。
3.装饰器模式装饰器模式是一种结构型模式,它可以在不修改原始对象的情况下,动态地为对象添加新的功能。
装饰器模式通过包装一个对象来扩展其功能,可以灵活地在运行时添加和删除功能。
应用:装饰器模式通常适用于需要动态地扩展对象功能的场景。
例如,我们可以使用装饰器模式为原本只有基本功能的类添加其他功能,例如添加日志记录、性能统计、缓存等。
4.观察者模式观察者模式是一种行为型模式,它定义了一种对象间的一对多依赖关系,使得当其中一个对象发生改变时,所有依赖它的对象都会收到通知,并自动更新。
观察者模式使得对象之间的关系更加松散,增强了对象的可重用性和可扩展性。
应用:在开发过程中,我们经常遇到需要通知其他对象状态变化的场景。
例如,当一份数据更新时,我们需要将此更新通知给其他相关的对象。
软件开发中的设计模式有哪些
软件开发中的设计模式有哪些在软件开发的领域中,设计模式就像是一套经过实践检验的解决方案,帮助开发者更高效、更优雅地解决常见的问题。
它们是软件开发中的宝贵经验总结,为构建可维护、可扩展和灵活的软件系统提供了有力的支持。
接下来,让我们一起探索一下软件开发中常见的设计模式。
一、创建型设计模式1、单例模式(Singleton Pattern)单例模式确保一个类只有一个实例存在,并提供一个全局访问点来获取该实例。
这在某些情况下非常有用,比如一个系统中只需要一个数据库连接池或者一个日志记录器。
想象一下,如果多个线程同时创建多个数据库连接池实例,不仅会浪费资源,还可能导致混乱。
通过单例模式,我们可以保证只有一个实例存在,有效地管理资源。
2、工厂模式(Factory Pattern)当我们需要创建对象,但又不想让客户端直接与具体的类进行交互时,工厂模式就派上用场了。
它定义了一个用于创建对象的接口,让子类决定实例化哪一个类。
比如,在一个汽车生产厂中,有不同类型的汽车(轿车、SUV 等),我们可以通过一个工厂类根据需求来创建相应类型的汽车对象,而客户端只需要向工厂请求即可,无需关心具体的创建细节。
3、抽象工厂模式(Abstract Factory Pattern)抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
例如,一个家具厂可能生产多种风格的家具(现代风格、古典风格),每种风格都有配套的椅子、桌子和沙发。
通过抽象工厂模式,我们可以根据用户选择的风格创建一整套家具,保证了风格的一致性和协调性。
4、建造者模式(Builder Pattern)建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如构建一个电脑配置,我们可以有不同的 CPU、内存、硬盘等组件选择,通过建造者模式,可以清晰地定义构建的步骤和顺序,同时能够灵活地组合不同的组件来创建出各种不同配置的电脑。
中间件体系结构和设计模式
中间件体系结构和设计模式在中间件体系结构中,中间件是一个处于应用程序和操作系统之间的软件层。
它提供了一系列的服务和功能,如消息传递、事务处理、分布式计算、安全性等。
通过将复杂的系统功能和业务逻辑放在中间件中处理,可以使得应用程序具有更好的可扩展性、灵活性和可维护性。
设计模式则是一套被广泛应用于软件开发中的经验总结。
它们是针对软件开发中常见问题的解决方案,可以帮助开发人员更好地组织和设计代码。
设计模式可以提高代码的可读性、可扩展性和可重用性,同时也能够降低代码的复杂度。
在中间件体系结构中,设计模式发挥着重要的作用。
设计模式能够帮助开发人员更好地设计和组织中间件的功能和服务。
下面介绍几个常见的中间件体系结构中使用的设计模式:1.装饰器模式:装饰器模式允许在不修改原有对象的情况下,动态地给对象添加额外的功能。
在中间件体系结构中,装饰器模式可以用于给中间件添加特定的功能,比如日志记录、性能监控等。
2.观察者模式:观察者模式用于建立一种对象之间的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会收到通知。
在中间件体系结构中,观察者模式可以用于实现消息传递机制,当一个消息发送时,所有订阅该消息的组件都可以收到通知。
3.工厂模式:工厂模式用于创建对象的过程,通过将对象的创建从具体的类中分离出来,使得代码更加灵活和可扩展。
在中间件体系结构中,工厂模式可以用于动态地创建中间件对象,根据不同的配置和需求创建不同的中间件实例。
4.责任链模式:责任链模式用于将请求的发送者和接收者解耦,并且允许多个对象都有机会处理该请求。
在中间件体系结构中,责任链模式可以用于处理请求的传递和处理过程,将请求传递给适合处理的中间件组件。
5.适配器模式:适配器模式用于将一个类的接口转换成客户端期望的另一个接口。
在中间件体系结构中,适配器模式可以用于适配不同的中间件协议或接口,使得不同的中间件组件能够协同工作。
总结起来,中间件体系结构和设计模式的结合可以使得系统的各个组件能够高效地协同工作。
软件设计模式中的桥接模式与装饰器模式比较
软件设计模式中的桥接模式与装饰器模式比较桥接模式和装饰器模式是软件设计中常用的两种设计模式,它们都属于结构型模式,但在使用和实现上有一些不同之处。
本文将对这两种模式进行比较。
首先,桥接模式和装饰器模式的目的不同。
桥接模式的目的是将抽象部分与它的具体实现部分分离,使它们可以独立变化,而装饰器模式则是在不改变原对象的基础上,动态地给该对象添加一些额外的职责。
其次,在桥接模式中,抽象部分与实现部分可以独立地变化。
通过桥接模式,我们可以在不修改原有代码的情况下,对抽象部分和实现部分进行扩展。
而在装饰器模式中,装饰器可以动态地对对象进行功能的扩展和修改,但是它们的调用顺序是固定的,且装饰器与被装饰者之间存在一种固定的关系。
此外,在桥接模式中,抽象部分和实现部分是通过一个桥接接口来进行关联的。
这个桥接接口定义了抽象部分和实现部分的关联方法。
而在装饰器模式中,装饰器与被装饰者之间的关联是通过继承和组合来实现的。
在实现上,桥接模式通常使用接口和抽象类来定义抽象部分和实现部分,并通过组合来将两者关联起来。
而装饰器模式则是通过继承来实现对被装饰者的功能扩展。
在使用上,桥接模式适用于系统中存在多个变化维度的场景,通过桥接模式可以在每个变化维度上进行扩展和变化,提高系统的灵活性。
而装饰器模式适用于需要给对象动态地添加或修改功能的场景,通过装饰器可以避免使用继承带来的静态特性,使得系统更加灵活和可扩展。
综上所述,桥接模式和装饰器模式在使用和实现上有一些不同之处。
桥接模式主要用于抽象部分和实现部分的分离,而装饰器模式主要用于对对象功能的扩展和修改。
在实际开发中,我们可以根据具体的需求选择合适的模式来解决问题。
编程中的设计模式:8个常见模式解析
编程中的设计模式:8个常见模式解析设计模式是软件开发中常见的一种解决问题的思想模式,它是一种经过多次实践总结出来的在特定情境下,对特定问题的解决方案。
设计模式通过将经典的经验进行抽象,然后形成模式来指导软件开发工程师进行设计和开发。
下面将介绍8个常见的设计模式。
1.工厂模式(Factory Pattern)工厂模式是一种创建型模式,用于创建对象的过程中隐藏了具体的实现细节,只暴露了一个工厂类的接口。
工厂模式可以根据不同的参数或条件,动态地返回不同的具体对象,达到解耦的效果,提高了代码的灵活性和可维护性。
2.单例模式(Singleton Pattern)单例模式是一种创建型模式,保证一个类只有一个实例,并提供全局访问点,同时对外部隐藏了具体的创建过程。
单例模式可以用于实现全局资源的管理,例如线程池、数据库连接等,避免了资源的创建和销毁过程中的开销问题。
3.观察者模式(Observer Pattern)观察者模式是一种行为型模式,定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,其相关依赖对象都能够得到通知和更新。
观察者模式可以实现松耦合的通信方式,增加了对象之间的交互性,提高了系统的可扩展性和可维护性。
4.策略模式(Strategy Pattern)策略模式是一种行为型模式,定义了一系列算法或行为,将它们封装起来并可以相互替换。
策略模式使得算法的变化不会影响到调用算法的客户端,提高了代码的可复用性和可维护性。
5.装饰器模式(Decorator Pattern)装饰器模式是一种结构型模式,可以动态地给一个对象添加一些额外的职责,而无需对原始对象进行修改。
装饰器模式通过组合的方式,将一系列装饰器对象包裹在被装饰对象的外部,从而在运行时动态地扩展对象的功能。
6.适配器模式(Adapter Pattern)适配器模式是一种结构型模式,用于将一个类的接口转换成客户端所期望的接口。
适配器模式中,适配器类是作为两个不兼容的接口之间的桥梁,将一个类的接口转换成另一个接口,从而可以让它们能够正常地协同工作。
装饰模式和职责链模式的对比
装饰模式和职责链模式的对比在软件开发中,设计模式是一个十分重要的概念,是指在软件设计过程中可以重复使用的解决问题的方案。
其中,装饰模式和职责链模式都是常见的设计模式,本文将对这两种模式进行比较分析。
一、装饰模式装饰模式,是指在不改变现有对象的基础上,动态地添加一些新的功能。
这种模式通过创建一个包装对象,也可以叫做装饰器来实现。
在装饰器模式中,有三个主要角色,分别是抽象构件(Component)、具体构件(ConcreteComponent)和装饰器(Decorator)。
其中,抽象构件角色定义了抽象接口,具体构件角色实现抽象接口,而装饰器角色继承了抽象构件角色,并持有一个具体构件的实例,起到包装的作用。
装饰模式的优点是可以动态地添加或删除功能,而且可以从不同的角度来扩展一个类的功能,避免了继承带来的代码复杂性和类爆炸问题。
但缺点是装饰层数过多会增加程序的复杂度,也可能会导致增加了过多的类。
二、职责链模式职责链模式,是指通过建立一个请求的处理链,并且每个节点都有处理请求的机会,直到请求被处理完成。
这种模式拥有很强的扩展性,可以根据需要动态地改变请求的处理流程。
在职责链模式中,有两个主要角色,分别是处理者(Handler)和请求(Request)。
处理者是职责链上的节点,每个处理者都可以处理请求,如果请求不能被当前处理者处理,则将请求传递给下一级处理者。
请求则封装了请求的内容和需要执行的操作。
职责链模式的优点是将请求发送者和接收者解耦,可以动态地改变请求的处理流程,可以避免请求发送者和处理者之间的紧耦合关系。
但缺点是会导致请求的处理延迟,也需要合理设计职责链的节点顺序,避免请求被一直传递下去。
三、装饰模式和职责链模式的比较1. 功能不同装饰模式是为对象动态地添加功能,而职责链模式则是为了解耦并且动态地改变请求的处理流程。
2. 使用场景不同装饰模式适用于需要动态地添加或删除功能的场景,也适用于不想使用继承或希望从不同角度扩展类功能的场景。
解析设计模式中的装饰器模式
解析设计模式中的装饰器模式设计模式中的装饰器模式是一种常见的结构型设计模式,它可以动态地为对象添加额外的行为或职责,而又不需要对其进行修改。
本文将解析装饰器模式的定义、特点、实现以及应用场景。
一、定义装饰器模式,又称为包装器模式,是指在不改变已有对象的基础上,动态地添加一些功能的一种设计模式。
通过将对象包装在一个装饰类中,可以在运行时动态地为其添加新的行为和职责。
这种模式能够在不改变原有代码的情况下,非常方便地扩展和修改一个对象的功能。
二、特点装饰器模式的主要特点包括:1. 能够动态地为对象添加新的职责。
2. 装饰器模式通过继承或接口实现,可以让客户端按照自己的需求,动态地组合对象。
3. 装饰器模式可以避免在对象上添加过多的特定职责,降低代码复杂度。
三、实现装饰器模式通过对对象嵌套的方式来动态地增加功能,从而不需要修改已有的代码。
在实现装饰器模式时,通常会定义一个基类或接口,用于表示被装饰的对象,然后定义一个装饰器类,用于扩展被包装对象的功能。
具体实现过程中,可以使用下面这个示例代码:interface Component {operation(): string;}class ConcreteComponent implements Component {public operation(): string {return 'Component';}}class Decorator implements Component {protected component: Component;constructor(component: Component) {ponent = component;}public operation(): string {return ponent.operation();}}class ConcreteDecoratorA extends Decorator {public operation(): string {return `ConcreteDecoratorA(${super.operation()})`;}}class ConcreteDecoratorB extends Decorator {public operation(): string {return `ConcreteDecoratorB(${super.operation()})`;}}在上面的代码中,Component是一个接口,ConcreteComponent 是Component的一种实现,Decorator是装饰器的基类,ConcreteDecoratorA和ConcreteDecoratorB是具体的装饰器实现。
软件工程师中的常见设计模式
软件工程师中的常见设计模式设计模式是软件开发中经验丰富的工程师在解决特定问题时总结出的一种模式或思想,它可以提供一套解决方案,帮助开发人员降低系统的复杂性,并增加代码的可读性和可维护性。
在软件工程师的日常开发过程中,熟悉和掌握常见的设计模式是非常重要的。
本文将介绍一些常见的设计模式,以帮助软件工程师更好地应用设计模式。
一、单例模式单例模式是一种创建型的设计模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。
在软件开发中,我们常常需要保证某个类的实例只有一个,比如数据库连接池、线程池等。
使用单例模式可以有效地避免资源的浪费和冲突。
单例模式的实现方式有多种,其中最常见的是饿汉式和懒汉式。
饿汉式是在类加载时就创建实例,而懒汉式是在首次使用时才创建实例。
二、工厂模式工厂模式是一种创建型的设计模式,它的主要目的是将具体对象的创建和客户端的使用相分离。
工厂模式通过一个工厂类来负责创建对象,客户端只需要调用工厂类的方法即可获取所需的对象,而不需要关心具体对象的创建过程。
工厂模式有三种常见的实现方式:简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂模式通过一个工厂类来创建所有的对象,工厂方法模式通过一个工厂接口和多个具体工厂类来创建对象,抽象工厂模式通过多个工厂接口和多个具体工厂类来创建对象。
三、观察者模式观察者模式是一种行为型的设计模式,它的主要目的是定义了对象之间的一对多依赖关系,使得当一个对象状态发生改变时,其他依赖于它的对象都会收到通知并自动更新。
观察者模式由两个核心角色组成:观察者和被观察者。
其中被观察者维护着一个观察者列表,并提供注册和注销观察者的方法,而观察者通过接收被观察者的通知并执行相应的操作。
四、策略模式策略模式是一种行为型的设计模式,它的主要目的是定义了一系列的算法,并将其封装成独立的对象,使得这些算法可以互相替换。
通过使用策略模式,可以使得算法和客户端解耦,客户端无需关心具体的算法实现细节。
装饰的基本原理名词解释
装饰的基本原理装饰(Decoration)是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原始对象添加新的行为。
装饰器模式的关键思想是,通过将对象包装在一个装饰器类的实例中,可以在不改变原始对象的结构的情况下,动态地扩展其功能。
1. 装饰器模式的结构装饰器模式由以下几个角色组成:•组件(Component):定义了一个抽象接口,用于定义被装饰对象的行为。
•具体组件(Concrete Component):实现了组件接口,并定义了需要被装饰的对象。
•装饰器(Decorator):维持一个指向组件对象的引用,并实现与组件接口一致的接口。
•具体装饰器(Concrete Decorator):向组件添加新的行为。
下图展示了装饰器模式的结构:2. 装饰器模式的工作原理装饰器模式的核心思想是通过包装器(装饰器类)来动态地扩展对象的功能。
装饰器类实现了与组件接口一致的接口,并维持一个指向组件对象的引用。
通过在装饰器类中添加新的行为,可以在不改变原始对象的结构的情况下,为对象添加新的功能。
当需要为一个对象添加新的功能时,可以将该对象传递给一个装饰器类的实例。
装饰器类会在调用原始对象的方法之前或之后执行自己的行为。
这样,装饰器可以在不改变原始对象的代码的情况下,动态地为对象添加新的行为。
3. 装饰器模式的优点•灵活性:装饰器模式允许你在不改变原始对象的结构的情况下,动态地添加新的行为。
你可以根据需要添加多个装饰器,以实现不同的功能组合。
•遵循开闭原则:装饰器模式使得在不修改现有代码的情况下,可以扩展对象的功能。
这符合开闭原则,即对扩展开放,对修改关闭。
•简化代码:装饰器模式将功能的实现分散在多个装饰器类中,使得每个装饰器类的代码较为简单,易于理解和维护。
4. 装饰器模式的应用场景装饰器模式适用于以下情况:•需要在不改变原始对象的结构的情况下,动态地为对象添加新的行为。
•需要通过组合而非继承来扩展对象的功能。
装饰器模式和工厂方法之间有什么区别和联系
装饰器模式和工厂方法模式在软件设计中各有其独特的作用和适用场景,它们之间的主要区别和联系如下:
区别:
1.目的和用途:装饰器模式的主要目的是动态地给一个对象添加一些额外的职责,即
增加功能。
这种增加功能的方式比生成子类更加灵活,因为它可以在运行时扩展类的属性,而不仅仅是在编译前期直接构思好继承逻辑。
而工厂方法模式的主要目的是定义一个用于创建对象的接口,让子类决定实例化哪一个类。
它提供了一种创建对象的最佳方式,解耦了具体类的创建过程。
2.关注点:装饰器模式更关注如何动态地改变对象的行为或增加功能,而工厂方法模
式更关注如何创建和管理对象实例的生命周期。
3.实现方式:装饰器模式通常是通过继承一个抽象类或实现一个接口来实现,而工厂
方法模式则是通过定义一个创建对象的接口,让子类实现这个接口来创建对象。
联系:
1.扩展性:虽然装饰器模式和工厂方法模式的目的不同,但它们都具有一定的扩展
性。
装饰器模式通过动态地添加功能来扩展对象的行为,而工厂方法模式通过定义创建对象的接口来扩展对象的创建方式。
2.设计模式组合:在实际应用中,装饰器模式和工厂方法模式可以结合起来使用。
例
如,你可以使用工厂方法模式来创建对象,然后使用装饰器模式来动态地添加功能。
这种组合使用可以使代码更加灵活和可扩展。
总之,装饰器模式和工厂方法模式各有其独特的优点和适用场景。
理解它们的区别和联系可以帮助你更好地选择和设计适合你的软件架构的设计模式。
面试常见设计模式
面试常见设计模式设计模式是软件开发中经过实践证明的、被广泛接受的解决特定问题的最佳实践。
在软件工程领域,设计模式起到了指导和规范的作用,它们帮助开发人员更好地组织和管理代码,提高代码的可读性、可维护性和可扩展性。
在面试中,设计模式经常是面试官关注的重点,本文将介绍一些面试中常见的设计模式,并对其进行详细的解析和应用场景的说明。
一、单例模式单例模式是最常见的设计模式之一,它保证一个类只有一个实例,并提供一个全局访问点。
在面试中,面试官通常会问到如何实现一个线程安全的单例模式。
我们可以通过使用双重检查锁机制来实现线程安全的单例模式,即在获取实例的方法中使用synchronized 关键字来确保只有一个线程可以创建实例。
此外,还可以使用静态内部类实现单例模式,利用类加载机制保证了线程安全。
二、工厂模式工厂模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。
在面试中,面试官通常会问到如何实现工厂模式。
我们可以通过定义一个抽象工厂类,其中包含一个创建对象的抽象方法,然后通过具体的子类来实现这个抽象方法,从而创建具体的对象。
工厂模式可以帮助我们隐藏对象的创建细节,提高代码的灵活性和可扩展性。
三、观察者模式观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
当主题对象的状态发生变化时,所有依赖于它的观察者对象都会得到通知并更新。
在面试中,面试官通常会问到如何实现观察者模式。
我们可以定义一个抽象的主题接口和一个抽象的观察者接口,然后具体的主题和观察者类分别实现这两个接口。
当主题对象的状态发生变化时,它会调用观察者对象的更新方法,从而实现观察者模式。
四、策略模式策略模式是一种行为型设计模式,它定义了一系列的算法,并将每个算法封装起来,使它们可以相互替换。
在面试中,面试官通常会问到如何实现策略模式。
我们可以定义一个抽象的策略接口和多个具体的策略类,每个具体的策略类实现了策略接口中的算法。
适配器模式、装饰器模式、代理模式的区别
适配器模式、装饰器模式、代理模式的区别
适配器模式、装饰器模式、代理模式都属于设计模式中的结构型模式,结构型设计模式是从程序的结构上解决模块之间的耦合问题。
适配器模式意图:将一个类的接口转换成另外一个客户希望的接口。
Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
Adapter模式通过类的继承或者对象的组合侧重于转换已有的接口,类适配器采用多继承的实现方式,带来了不良的高耦合,所以一般不推荐使用。
对象适配器采用对象组合的方式,更符合松耦合精神。
例如:笔记本电源适配器,可以将220v转化为适合笔记本使用的电压。
适用性:
你想使用一个已经存在的类,而它的接口不符合你的需求。
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。
对象适配器可以适配它的父类接口。
代理模式意图:为其他对象提供一种代理以控制对这个对象的访问,解决直接访问某些对象是出现的问题。
例如:律师本身就是我们维权的一个代理!
适用性:在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。
下面是一些可以使用Proxy模式常见情况:
远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。
虚代理(Virtual Proxy)根据需要创建开销很大的对象。
保护代理(ProtecTIon Proxy)控制对原始对象的访问。
保护代理用于对象应该有不同的访问权限的时候。
aop编程的设计模式
aop编程的设计模式AOP编程的设计模式引言:AOP(Aspect-Oriented Programming)是一种编程思想,旨在将横切关注点(Cross-cutting Concerns)与核心业务逻辑分离,以提高代码的可维护性和复用性。
在AOP编程中,设计模式起到了重要的作用。
本文将介绍几种常见的AOP设计模式,包括代理模式、装饰器模式和观察者模式。
一、代理模式代理模式是AOP编程中最常见的设计模式之一。
在代理模式中,代理对象充当了被代理对象的中间人,通过代理对象进行方法的调用和控制。
代理模式常用于实现横切关注点的功能,比如日志记录、事务管理等。
通过代理对象将这些功能从核心业务逻辑中分离出来,提高了代码的可维护性和复用性。
二、装饰器模式装饰器模式也是一种常用的AOP设计模式。
在装饰器模式中,通过在不修改原有对象的情况下,动态地给对象添加新的功能。
装饰器模式可以在运行时动态地给对象添加额外的行为,比如动态地给方法添加缓存、校验等功能。
通过装饰器模式,可以灵活地对核心业务逻辑进行扩展,而不需要修改已有的代码。
三、观察者模式观察者模式也是AOP编程中常用的设计模式之一。
在观察者模式中,对象之间存在一对多的关系,当被观察对象状态发生变化时,观察者对象会自动收到通知并进行相应的处理。
观察者模式可以用于实现事件监听、消息通知等功能。
通过观察者模式,可以将横切关注点的处理过程与核心业务逻辑解耦,提高代码的可维护性和复用性。
总结:AOP编程是一种将横切关注点与核心业务逻辑分离的编程思想。
在AOP编程中,设计模式起到了重要的作用。
代理模式、装饰器模式和观察者模式是AOP编程中常用的设计模式,它们分别通过代理对象、装饰器对象和观察者对象来实现横切关注点的功能。
这些设计模式能够提高代码的可维护性和复用性,使得核心业务逻辑更加清晰和简洁。
通过学习和应用AOP编程的设计模式,我们可以更好地将横切关注点与核心业务逻辑分离,提高代码的可维护性和复用性。
Adapter模式与包装器模式的区别
Adapter模式与包装器模式的区别在软件开发中,适配器模式和包装器模式是两种常用的设计模式。
虽然它们的作用和功能有些相似,但是它们之间还是有一些区别的。
本文就来详细介绍一下这两种设计模式的区别。
一、适配器模式适配器模式(Adapter Pattern)是指将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
适配器模式分为类适配器和对象适配器两种方式。
1. 类适配器类适配器用于将一个类的接口转换成客户希望的接口,通过继承源类和实现目标类的接口实现。
类适配器一般采用多重继承的方式,同时继承源类和目标类。
这种方式的优点是能够重定义源类的行为,同时也能够适配目标类。
但是这种方式也存在一些缺点,比如如果需要适配的目标接口过于复杂,就需要定义很多的适配器类。
2. 对象适配器对象适配器用于将一个对象的接口转换成客户希望的另一个接口。
对象适配器不是通过继承的方式实现,而是通过在适配器类中包含一个源类的对象实例,使得可以调用源类对象的方法来实现目标接口。
这种方式的优点是可以避免由于过多的继承关系导致代码的复杂性和可读性变差。
但是这种方式也存在一些缺点,比如适配器类和源类必须是同一类型的接口,这样才能实现适配。
二、包装器模式包装器模式(Wrapper Pattern)是指将一个已有的类包装起来,以满足某些特定的需求。
包装器模式分为两种方式:装饰器模式和代理模式。
1. 装饰器模式装饰器模式(Decorator Pattern)是指在不改变原有对象的基础上,使用包装器进行包装,以扩展其功能。
装饰器模式的核心思想是可以为一个对象添加新的功能,同时还不必改变原有的代码。
装饰器模式一般通过继承来实现,在装饰器类中包含了一个被装饰的对象,通过调用被装饰对象的方法,可以在其基础上添加新的功能,从而扩展其原有的功能。
2. 代理模式代理模式(Proxy Pattern)是指通过一个代理对象来控制对实际对象的访问。
软件开发者必知的12大设计模式
软件开发者必知的12大设计模式在软件开发中,设计模式是开发者们必须要掌握的重要知识之一。
设计模式是一种在特定情境下解决问题的经验总结,它们是被反复验证的解决方案,从而被广泛接受和应用于软件开发工程中。
在本文中,将介绍12种常用的设计模式,并说明它们各自的特点和适用场景。
1.单例模式单例模式是一种保证只有一个实例对象的设计模式。
这个实例对象是全局唯一的,可以在任何地方访问。
单例模式适用于需要确保系统中只有一个实例的情况,例如配置文件、日志记录工具等。
2.策略模式策略模式是一种根据不同的情况采取不同算法的设计模式。
它将不同的算法封装在一个类中,使得这些算法可以相互替换。
策略模式适用于在运行时动态地选择算法的情况,例如排序算法、数据加密等。
3.工厂模式工厂模式是一种创建对象的设计模式,它将对象的实例化过程封装在一个类中,由该类负责创建对象。
工厂模式适用于需要动态创建对象的情况,例如数据库连接、日志记录器等。
4.观察者模式观察者模式是一种在对象之间定义一对多的依赖关系,当一个对象状态改变时,它的所有依赖对象都会收到通知并自动更新。
观察者模式适用于建立一种对象之间的松耦合关系,例如事件处理、消息发布等。
5.装饰器模式装饰器模式是一种动态地为对象添加行为的设计模式。
它可以在不改变原有对象的情况下,通过一系列包装对象的方式添加新的功能。
装饰器模式适用于需要动态地扩展对象的功能,例如日志记录、权限控制等。
6.适配器模式适配器模式是一种将不兼容的接口转换成兼容的接口的设计模式。
它可以使得原本不兼容的两个接口能够协同工作。
适配器模式适用于需要集成两个不兼容的组件的情况,例如数据库驱动、网络库等。
7.命令模式命令模式是一种将请求和执行分离的设计模式。
它可以将请求封装成对象,并在该对象中存储和传递请求相关的信息和参数。
命令模式适用于需要将请求进行排队、记录和撤销的情况,例如任务队列、文本编辑器等。
8.模板方法模式模板方法模式是一种基于继承的设计模式,它定义了一个算法骨架,将一些步骤延迟到子类中实现。
模式比较方案
模式比较方案简介在软件开发过程中,选择合适的设计模式是一项非常重要的决策。
设计模式提供了一套解决常见软件设计问题的经验性解决方案。
在本文档中,我们将比较常见的设计模式,包括工厂模式、装饰器模式和观察者模式,并分析它们的应用场景、优点和缺点。
工厂模式定义工厂模式是一种创建对象的设计模式。
它定义了一个抽象工厂,负责封装对象的创建过程,而具体的对象创建交给子类实现。
应用场景工厂模式适用于以下场景:1.当一个对象的创建需要复杂的初始化过程时,可以将初始化逻辑抽象到工厂类中,简化客户端的调用。
2.当需要在运行时根据条件决定创建哪个具体对象时,可以使用工厂模式。
优点工厂模式的优点包括:1.封装了对象的创建过程,降低了客户端与具体对象的耦合性。
2.符合开闭原则,当需要创建新的对象时,只需要新增具体工厂类,而不需要修改已有代码。
缺点工厂模式的缺点包括:1.增加了系统的复杂度,引入了额外的类和接口。
2.当需要创建的对象很多时,会导致工厂类的职责过重。
装饰器模式定义装饰器模式是一种结构型设计模式。
它允许在不改变现有对象结构的情况下,动态地向对象添加额外的功能。
应用场景装饰器模式适用于以下场景:1.当需要动态地添加对象的额外功能时,可以使用装饰器模式。
2.当不能使用子类来扩展对象时,可以使用装饰器模式。
优点装饰器模式的优点包括:1.可以灵活地添加和删除功能,而无需修改现有对象的结构。
2.符合开闭原则,当需要添加新的功能时,只需要创建新的装饰器类,而不需要修改已有代码。
缺点装饰器模式的缺点包括:1.增加了系统的复杂度,引入了额外的类和接口。
2.当装饰器类很多时,可能会导致类的数量庞大。
观察者模式定义观察者模式是一种行为型设计模式。
它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,它的所有依赖者都会接收到通知并自动更新。
应用场景观察者模式适用于以下场景:1.当一个对象需要将自己的变化通知其他对象时,可以使用观察者模式。
十种常用的设计模式
十种常用的设计模式设计模式是在软件开发中经过实践总结出来的一套解决特定问题的模板。
它们提供了一种在软件设计中重用的方式,可以提高代码的可维护性、复用性和灵活性。
本文将介绍十种常用的设计模式,分别是单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式、适配器模式、装饰器模式、代理模式、观察者模式和策略模式。
1. 单例模式单例模式确保某个类只有一个实例,并提供一个全局访问点。
它常用于数据库连接、日志记录器等需要唯一实例的场景。
单例模式可以通过私有化构造函数、静态方法和静态变量来实现。
2. 工厂模式工厂模式将对象的创建与使用分离,通过一个工厂类来创建对象。
工厂模式可以隐藏具体对象的实现细节,提供一个统一的接口来创建对象。
它常用于创建复杂对象或者需要根据条件来动态创建对象的场景。
3. 抽象工厂模式抽象工厂模式提供一个接口来创建一系列相关或依赖的对象,而不需要指定具体的类。
抽象工厂模式可以为客户端提供一组相互关联的产品,而不需要关心具体的实现细节。
它常用于创建一系列产品族的场景。
4. 建造者模式建造者模式将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式可以通过一步一步地构建对象,灵活地组合各个部分来构建复杂的对象。
它常用于创建复杂的对象,尤其是对象的构建过程比较复杂的场景。
5. 原型模式原型模式通过复制现有对象来创建新的对象,而不需要通过调用构造函数来创建。
原型模式可以提高对象的创建效率,避免重复创建相似的对象。
它常用于创建成本较高的对象或者需要创建大量相似对象的场景。
6. 适配器模式适配器模式将一个类的接口转换成客户端所期望的另一个接口,使得原本不兼容的类可以一起工作。
适配器模式可以用来解决接口不兼容或者需要复用现有类的情况。
它常用于系统间接口的转换和现有类的复用。
7. 装饰器模式装饰器模式动态地给一个对象添加额外的职责,同时又不改变其接口。
装饰器模式可以在不修改原有对象的情况下,通过对对象进行包装来扩展其功能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
OO原则
• • • • •
封装变化 多用组合,少用继承 针对接口编程,不针对实现编程 为交互对象之间的松耦合设计而努力 对扩展开放,对修改关闭
Any Question ????
Thank you
测试你的新Java I/O装饰者
要点
• 继承属于扩展形式之一,但不见得是达到弹性设计 的最佳方式 • 在我们的设计中,应该允许行为可以被扩展,而无 须修改现有的代码 • 组合和委托可用于在运行时动态地加上新的行为 • 除了继承,装饰者模式也可以让我们扩展行为 • 装饰者模式意味着一群装饰者类, 这些类用来包 装具体组件 • 装饰者类反映出被装饰的组件类型(事实上,他们 具有相同的类型,都经过接口或继承实现)
②
现在,该是为顾客算钱的时候了。通过调用最外 圈装饰者(Whip)的cost()就可以办得到。Whip 的cost()会先委托它装饰的对象(也就是Mocha) 计算出价钱,然后再加上奶泡的价钱。
这是目前所知道的一切…… 这是目前所知道的一切
• • • 装饰者和被装饰对象有相同的超类型 你可以用一个或多个装饰者包装一个对象 既然装饰者和被装饰对象有相同的超类型,所 以在任何需要原始对象(被包装的)的场合, 可以用装饰过的对象代替它 装饰者可以在所委托被装饰者的行为之前与/或
认识装饰者模式
• 我们已经了解利用继承无法完全解决问题,在星 巴兹遇到的问题有:类数量爆炸、设计死板,以 及基类加入的新功能并不适用于所有的子类 • 所以,在这里要采用不一样的做法:我们要以饮 料为主体,然后在运行时以调料来“装饰” (decorate)饮料
• 比方说,如果顾客想要摩卡和奶泡深焙咖啡,那 么,要做的是:
} }
} }
public class DarkRoast extends Beverage { public DarkRoast() { description = “Most Excellent Dark Roast”; } public double cost() { return 1.99 + super.cost(); } }
习题解答
真实世界的装饰者: 真实世界的装饰者:Java I/O
装饰java.io类 类 装饰
编写自己的Java I/0装饰者
• 编写一个装饰者,把输入流内的所有大写字符转 成小写 • 举例:当读取“I know the Decorator Pattern therefore I RULE!”,装饰者会将它转成“i know the decorator pattern therefore i rule!”
写下星巴兹的代码
•
先从Beverage类下手,这不需要改变星巴兹原 始的设计。如下所示: 代码清单
•
让我们也来实现Condiment(调料)抽象类, 也就是装饰者类: 代码清单
写饮料的代码
• • •
现在,已经有了基类,让我们开始开始实现 一些饮料 先从浓缩咖啡(Espresso)开始 我们还需要为具体的饮料设置描述,而且还 必须实现cost()方法
• 尽管继承威力强大,但是体会到它并不总是 能够实现最有弹性和最好维护的设计 • 不通过继承又能如何达到复用呢?
– 利用组合(composition)和委托(delegation) 可以在运行时具有继承行为的效果 – 利用继承设计子类的行为,是在编译时静态决定 的,而且所有的子类都会继承到相同的行为。然 而,如果能够利用组合的做法扩展对象的行为, 就可以在运行时动态地进行扩展
– – – – 拿一个深焙咖啡(DarkRoast)对象 以摩卡(Mocha)对象装饰它 以奶泡(Whip)对象装饰它 调用cost()方法,并依赖委托(delegate)将调料的价 钱加上去
• 但是如何“装饰”一个对象,而“委托”又要如 何与此搭配使用呢? • 给一个暗示:把装饰者对象当成“包装者”。让 我们看看这是如何工作的……
• 购买咖啡时,也可以要求在其中加入各种调料,例 如:蒸奶(Steamed Milk)、豆浆(Soy)、摩卡 (Mocha,也就是巧克力风味)或覆盖奶泡 • 星巴兹会根据所加入的调料收取不同的费用 • 所以订单系统必须考虑到这些调料部分 • 这是他们的第一个尝试……
• 为什么设计这么多类呀? • 利用实例变量和继承,就可以追踪这些调料 • 先从Beverage基类下手,加上实例变量代表是否加 上调料(牛奶、豆浆、摩卡、奶泡……) ……
请为下面类的cost()方法书写代码(用伪 方法书写代码( 请为下面类的 方法书写代码 Java代码即可) 代码即可) 代码即可
public class Beverage { public double cost() {
public class DarkRoast extends Beverage { public DarkRoast() { description = “Most Excellent Dark Roast”; } public double cost() {
以装饰者构造饮料订单
① 以DarkRoast对象开始
② 顾客想要摩卡(Mocha),所以建立一个Mocha 对象,并用它将DarkRoast对象包(wrap)起来
②
顾客也想要奶泡(Whip),所以需要建立一个Whip装 饰者,并用它将Mocha对象包起来。别忘了, DarkRoast继承自Beverage,且有一个cost()方法,用 来计算饮料价钱。
结构型——装饰器模式(Decorator)
欢迎来到星巴兹咖啡
• 星巴兹(Starbuzz)是以扩张速度最快而闻名的 咖啡连锁店 • 如果你在街角看到它的店,在对面街上肯定还会 看到另一家 • 因为扩张速度实在太快了,他们准备更新订单系 统,以合乎他们的饮料供应要求 • 他们原先的类设计是这样的……
• •
之后,加上自己的行为,以达到特定的目的
对象可以在任何时候被装饰,所以可以在运行 时动态地、不限量地用你喜欢的装饰者来装饰 对象
定义装饰者模式
• •
装饰者模式动态地将责任附加到对象上 若要扩展功能,装饰者提供了比继承更有弹性 的替代方案
装饰我们的饮料
在继承和组合之间,观念有一些混淆
• 有一点混淆……我原以为在这个模式中不会使用继承, 而是要利用组合取代继承 • 看看类图。CondimentDecorator扩展自Beverage类, 这用到了继承 • 的确是如此,但这么做的重点在于,装饰者和被装饰 者必须是一样的类型,也就是有共同的超类,这是相 当关键的地方。在这里,我们利用继承达到“类型匹 配”,而不是利用继承获得“行为” • 为何装饰者需要和被装饰者(亦即被包装的组件)有 相同的“接口”,因为装饰者必须能取代被装饰者 • 但是行为又是从哪里来的? • 当我们将装饰者与组件组合时,就是在加入新的行为。 所得到的新行为,并不是继承自超类,而是由组合对 象得来的
• 将装饰者与组件组合时,就是在加入新的行为。所 得到的新行为,并不是继承自超类,而是由组合对 象得来的 • 继承Beverage抽象类,是为了有正确的类型,而不 是继承它的行为。行为来自装饰者和基础组件,或 与其他装饰者之间的组合关系 • 因为使用对象组合,可以把所有饮料和调料更有弹 性地加以混和与匹配,非常方便。 • 如果依赖继承,那么类的行为只能在编译时静态决 定。换句话说,行如果不是来自超类,就是子类覆 盖后的版本。反之,利用组合,可以把装饰者混合 着用……而且是在“运行时” • 可以在任何时候,实现新的装饰者增加新的行为。 如果依赖继承,每当需要新行为时,还得修改现有 的代码
– 可以利用此技巧把多个新职责,甚至是设计超类 时还没有想到的职责加在对象上。而且,可以不 用修改原来的代码 – 利用组合维护代码。通过动态地组合对象,可以 写新的代码添加新功能,而无须修改现有代码 – 既然没有改变现有代码,那么引进bug或产生意 外副作用的机会将大幅度减少
开放-关闭原则
• 类应该对扩展开放,对修改关闭 • 我们的目标是允许类容易扩展,在不修改现有代 码的情况下,就可搭配新的行为 • 如能实现这样的目标,有什么好处呢? • 这样的设计具有弹性可以应对改变,可以接受新 的功能来应对改变的需求 • 想想观察者模式……通过加入新的观察者,我们 可以在任何时候扩展Subject(主题),而且不 需向主题中添加代码
要点
• 装饰者可以在被装饰者的行为前面与/或后面加上 自己的行为, 甚至将被装饰者的行为整个取代掉, 而达到特定的目的 • 你可以用无数个装饰者包装一个组件 • 装饰者一般对组件的客户是透明的,除非客户程序 依赖于组件的具体类型 • 装饰者会导致设计中出现许多小对象,如果过度使 用,会让程序变得很复杂
代码清单
写调料代码
• 如果回头去看看装饰者模式的类图,将发现 我们已经完成了抽象组件(Beverage),有 了具体组件(HouseBlend),也有了抽象装 饰者(CondimentDecorator) 现在,我们就来实现具体装饰者。先从摩卡 巴兹的朋友决定开始在菜单上加上咖啡 的容量大小,供顾客可以选择小杯(tall)、中杯 (grande)、大杯(venti) • 星巴兹认为这是任何咖啡都必须具备的,所以在 Beverage类中加上了getSize()与setSize() • 他们也希望调料根据咖啡容量收费,例如:小中 大杯的咖啡加上豆浆,分别加收0.10、0.15、 0.20美金 • 如何改变装饰者类应对这样的需求?
潜在的问题 • 当哪些需求或因素改变时会影响这个设计?
– 调料价钱的改变会使我们更改现有代码 – 一旦出现新的调料,我们就需要加上新的方法, 并改变超类中的cost()方法 – 以后可能会开发出新饮料。对这些饮料而言(例 如:冰茶),某些调料可能并不适合,但是在这 个设计方式中,Tea(茶)子类仍将继承那些不 适合的方法,例如:hasWhip()(加奶泡) – 万一顾客想要双倍摩卡咖啡,怎么办?