装饰者模式
MM们要过生日了 ,怎么也得表示下吧。最起码先送个蛋糕。蛋糕多种多样了。巧克力,冰淇淋,奶油等等。这都是基本的了 ,再加点额外的装饰,如蛋糕里放点花。放贺卡。放点干果吃着更香等等。看看我是如何设计的。
我想既然是蛋糕,那我就把蛋糕作为一个抽象类,剩下的蛋糕子类型来继承它,每个子类都有吃该蛋糕的感觉 ^_^,看起来真的不错。蛋糕的子类分别是奶酪蛋糕,巧克力蛋糕,冰淇淋蛋糕,插花的冰淇淋蛋糕,放贺卡的冰淇淋蛋糕。某个MM的生日蛋糕喜欢带花的冰淇淋蛋糕。还好我早有准备。但是有几次失策了。。她们要的蛋糕我这都没有。比如带鲜花的巧克力蛋糕。带果仁的牛奶蛋糕。带鲜花带果仁的蛋糕。。。。那我还要继续添加蛋糕的子类。。问题出现了。这样会造成大量的蛋糕子类 。真是噩梦啊。
那么我要好好思考这个问题了。发现了刚才的设计确实有问题。。发现了真正的要关注的主体是蛋糕。。而贺卡,花,果仁等等只不过是装饰 的作用。
思路来了。蛋糕作为主体,其他的东西都加到蛋糕上。MM要啥我就加啥呗。呵呵。
到现在我们要明确的是:
- 蛋糕是主体。
- 花,贺卡,果仁等等是装饰者。
- 可以用装饰者包装蛋糕。
来看看什么是装饰器模式吧:
动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
- Component:抽象出的主体对象。
- ConcreteComponent:是要动态扩展的对象,它继承自Component.
- Decorator:是装饰器的接口。(这里的接口并不是指java的interface)。
- ConcreteDecoratorA:实现Decorator的类,包含了一个Component引用,这样就可以扩展Component的方法了。
说完理论了。可能还一头雾水吧。。。还是接着蛋糕的例子继续说。先看图吧。
基本符合了上面所提到的装饰者模式的框架结构了。再看看代码:
Cake
- package decorator.demo;
-
-
-
-
-
-
-
public abstract class Cake {
-
String remark = "蛋糕";
-
public String getRemark() {
-
return remark;
- }
-
public abstract String getImpression();
- }
package decorator.demo;
/**
* 蛋糕基类
* @author Nicholas
*
*/
public abstract class Cake {
String remark = "蛋糕";
public String getRemark() {
return remark;
}
public abstract String getImpression();//用来描述吃蛋糕的感觉。。。。
}
Cake是个抽象类,它已经实现了getRemark的方法。但没有实现getImpression.这个方法必须被子类实现。
再看看装饰器的抽象类
OtherDecorator
- package decorator.demo;
-
-
-
-
-
-
-
public abstract class OtherDecorator extends Cake{
- Cake cake;
-
-
-
-
-
-
-
public OtherDecorator(Cake cake){
-
this.cake=cake;
- }
-
-
-
-
public abstract String getRemark();
- }
package decorator.demo;
/**
* 其他用来添加蛋糕的东西
* @author Nicholas
*
*/
public abstract class OtherDecorator extends Cake{
Cake cake;
/**
* 引用一个Cake.
* 让被装饰者进入装饰者之中。这里用的是构造方法注入。
* 这样就可以调用Cake实例的方法了。
* @param cake
*/
public OtherDecorator(Cake cake){
this.cake=cake;
}
/**
* 让装饰器的子类都去实现getRemark方法。业务需要每个装饰器都要有描述。
*/
public abstract String getRemark();
}
下面让我们实现一个蛋糕吧。^_^。。
- package decorator.demo;
-
-
-
-
-
-
public class CheeseCake extends Cake{
-
-
-
-
public CheeseCake(){
-
super.remark="乳酪蛋糕";
- }
-
-
-
-
-
-
public String getImpression() {
-
return "香甜感受";
- }
-
- }
package decorator.demo;
/**
* 乳酪蛋糕
* @author Nicholas
*
*/
public class CheeseCake extends Cake{
/**
* 乳酪蛋糕的构造方法
*/
public CheeseCake(){
super.remark="乳酪蛋糕";//修改乳酪蛋糕的描述。
}
/**
* 实现了Cake抽象类的getImpression
* 吃乳酪蛋糕的感觉。。
*/
public String getImpression() {
return "香甜感受";
}
}
其他实现Cake的类就不列出了,道理是一样的。
下面我们要开始实现具体的装饰器了。
- package decorator.demo;
-
-
-
-
-
-
-
public class FlowerDecorator extends OtherDecorator{
-
-
-
-
-
-
-
public FlowerDecorator(Cake cake){
-
super(cake);
-
super.remark="一朵玫瑰花";
- }
-
-
-
-
-
public String getImpression() {
-
-
return cake.getImpression()+","+"看到一朵花真是happy";
- }
-
-
public String getRemark() {
-
return cake.getRemark()+"+"+super.remark;
- }
- }
package decorator.demo;
/**
* 给蛋糕添加的花
* @author Nicholas
*
*/
public class FlowerDecorator extends OtherDecorator{
/**
* 构造函数
* 传入一个cake实例,也就是前面所实现的Cake的子类,如奶酪蛋糕,巧克力蛋糕等等。
* @param cake
*/
public FlowerDecorator(Cake cake){
super(cake);//调用父类的构造方法,可以获取Cake的实例了。就可以调用Cake实例的方法.
super.remark="一朵玫瑰花";
}
/**
* 实现了装饰器抽象类的getImpression方法。
*/
public String getImpression() {
//这是重点。我们通过构造方法传入的cake实例。对cake进行了装饰,增加了新的功能。
return cake.getImpression()+","+"看到一朵花真是happy";
}
public String getRemark() {
return cake.getRemark()+"+"+super.remark;
}
}
到现在终于大功告成了。。这样方便了很多,可以通过装饰器生成很多种类的蛋糕。
- package decorator.demo;
-
-
public class MyGirlB {
-
public static void main(String[] args){
-
-
Cake nutsFlowerChocolateCake = new NutsDecorator(new FlowerDecorator(new ChocolateCake()));
-
System.out.println("remark "+nutsFlowerChocolateCake.getRemark());
-
-
System.out.println("impression "+nutsFlowerChocolateCake.getImpression());
- }
- }
package decorator.demo;
public class MyGirlB {
public static void main(String[] args){
//用果仁,花包装巧克力蛋糕。
Cake nutsFlowerChocolateCake = new NutsDecorator(new FlowerDecorator(new ChocolateCake()));
System.out.println("remark "+nutsFlowerChocolateCake.getRemark());
//吃蛋糕的感受已经发生了改变。
System.out.println("impression "+nutsFlowerChocolateCake.getImpression());
}
}
这个模式的缺点也挺明显的 ,看看如下图片
为了扩展cake的功能,加入了许多的装饰类。。当然用户也可以继承OtherDecorator来继续扩展。但是对API使用者是个困扰。。所以API要说明哪些类是用来包装的。。
分享到:
相关推荐
装饰模式(Decorator Pattern)是一种结构型设计模式,它在不改变原有对象的基础上,通过包裹一个对象并为其添加新的行为或责任,实现对对象功能的扩展。这种模式在软件开发中非常常见,尤其当需要在运行时动态改变...
装饰者模式(Decorator Pattern)是一种结构型设计模式,它的定义是在不改变原有对象结构的基础上,动态地给该对象增加一些职责(即增加其额外功能)。这种模式允许向一个现有的对象添加新的功能,同时又不改变其...
装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式通过创建一个装饰类,该类包装了原始类的实例,并在调用原始类方法之前或之后添加额外的...
装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许我们向对象添加新的行为或职责,而无需修改对象的原始代码。在C++中实现装饰者模式,可以让我们灵活地扩展对象的功能,同时保持代码的可读性和可维护性...
装饰者模式(Decorator)是一种设计模式,用于在运行时动态地给对象添加额外的责任或功能。它是结构型设计模式的一种,能将行为的增加与对象的创建分离,使得我们可以独立地扩展对象的功能。 在Java或其他面向对象...
装饰者模式(Decorator Pattern)是结构型设计模式之一,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码。这个模式的名字来源于装饰艺术,它通过添加额外的装饰来增强一个物体的外观,同样地,...
装饰模式(Decorator Pattern)是一种结构型设计模式,允许在不改变对象接口的情况下,动态地为对象添加额外的职责或功能。装饰模式通常用于需要扩展对象功能而又不希望使用子类化的场景。 装饰模式的组成 组件接口...
装饰器模式(Decorator Pattern)是一种设计模式,它允许在运行时动态地给对象添加新的行为或职责,而无需改变对象本身。在Java开发中,这种模式尤其有用,因为它提供了扩展对象功能的方式,同时保持了代码的灵活性...
装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过添加额外的职责来扩展对象的功能。在C#中,装饰模式尤其适用于那些需要动态地增加或减少对象功能的情况,避免了使用...
装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...
在《Element of Reusable Object-Oriented Software》中,GOF 对装饰器模式的用意进行了概述:Decorator Pattern――Attaches additional responsibilities to an object dynamically. Decorators provide a ...
装饰者模式是软件设计模式中的一种结构型模式,它的主要目的是动态地给对象添加新的功能,而无需修改原有代码。在Java中,装饰者模式通常通过继承和组合来实现,它提供了一种比继承更灵活的方式来扩展对象的功能。...
装饰模式(Decorator)是软件设计领域中一种非常实用的结构型设计模式,它允许我们向一个对象添加新的行为或责任,而无需修改该对象的源代码。在C++编程语言中,装饰模式常用于动态地扩展类的功能,使得类的行为在...
在装饰者模式中,我们通常有两个主要的角色:Component(组件)和Decorator(装饰器)。Component是被装饰的对象接口,定义了所有装饰器和原始对象共同拥有的行为。Concrete Component是Component的具体实现,是实际...
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时给对象添加新的行为或职责,而无需修改对象的源代码。这种模式通过创建一个包装类(也称为装饰者),并将其与原始对象组合在一起,使得装饰者...
装饰者模式(Decorator Pattern)是一种设计模式,它允许在运行时动态地给对象添加新的行为或职责,而不会改变对象的类。这种模式是结构型模式的一种,通过将对象包装在一个装饰器对象中来实现扩展功能,使得原有...
装饰者模式是软件设计中的一种行为模式,它允许在运行时动态地给对象添加新的行为或职责,而无需改变对象的原始类。这种模式在不违反开闭原则的前提下,提供了扩展对象功能的能力,使得系统更加灵活,易于维护。 在...