Java设计模式之装饰器模式

1、什么是装饰器模式?

装饰器模式的核心是要有一个共通接口,然后共通接口又分成两大类实现。一种实现是被修饰者,它实现接口的主体功能。另一种是修饰者,它相当于一个饰品的功能,不改变被修饰者的实现,只是在原有实现上再加上点“修饰”。最后是构建者,它负责将被修饰者与“饰品”就是修饰者组装起来。

装饰器模式涉及到的四个角色:

  1. 共通接口
  2. 被修饰者:它实现共通接口,是主体功能。
  3. 饰品:这也实现共通接口,但只实现“修饰”功能,主体功能调用构建器传入的被修饰者实现
  4. 构建者:它负责组合“被修饰者”与“饰品”

2、装饰器模式要点

在具体实践中,关键问题是分离“主体”与“饰品”。主题是必需有的功能,饰品是可有可无的功功能。一个主体可以不与任何饰品组合,也可以与多个饰品组合。组合的过程是在代码运行过程中实现的,不是在编译阶段,因此说它是“动态”的为已存在的类添加新功能。

修饰器虽然也实现了共通接口,但接口的主要功能是通过传入的被修饰者的实例实现的,它只是“增加”新额外的功能,不是重新实现被修饰者的实现。这样的话,无论是被修饰者,还是组装以后的结果,都可以当成共通接口使用,这个就是“透明”的增加新功能。

3、示例

假如我们实现一个小游戏,里边有很多小动物,这些小动物可以用任意的“饰品”打扮起来。

首先有共通接口Animal,然后分别从Animal实现猫与狗,这个是主体。再然后分别给Animal加上帽子与鞋子,这个是“饰品”。

代码如下:

package com.zhangxf.test;

// 动物的共通接口
interface Animal {
	void say();
}
// 动物“猫”的实现主体
class Cat implements Animal{
	public void say() {
		System.out.println("I am class Cat");
	}
}
// 动物“狗”的实现主体
class Dog implements Animal{
	public void say() {
		System.out.println("I am class Dog");
	}
}
// 用“帽子”修饰动物
class AnimalWithHat implements Animal {
	private Animal ani;
	AnimalWithHat(Animal ani) {
		this.ani = ani;
	}
	public void say() {
		ani.say();
		System.out.println("I hava a hat");
	}
}
//用“鞋子”修饰动物
class AnimalWithShoes implements Animal {
	private Animal ani;
	AnimalWithShoes(Animal ani) {
		this.ani = ani;
	}
	public void say() {
		ani.say();
		System.out.println("I hava shoes");
	}
}
public class Decorator {
	// main方法就是构建者
	public static void main(String[] args) {
		// 一般的猫
		Animal cat = new Cat();
		cat.say();
		System.out.println("==========1==========");
		// 般的狗
		Animal dog = new Dog();
		dog.say();
		System.out.println("===========2=========");
		// 戴帽子的猫
		Animal catWithHat = new AnimalWithHat(cat);
		catWithHat.say();
		System.out.println("=========3===========");
		// 穿鞋的猫
		Animal catWithShoes = new AnimalWithShoes(cat);
		catWithShoes.say();
		System.out.println("==========4==========");
		// 给戴帽子的猫穿上鞋
		Animal catWithHatAndShoes = new AnimalWithShoes(catWithHat);
		catWithHatAndShoes.say();
		System.out.println("===========5=========");
		// 给穿鞋的猫带上帽子
		Animal catWithShoesAndHat = new AnimalWithHat(catWithShoes);
		catWithShoesAndHat.say();
		System.out.println("==========6==========");
		// 戴帽子的狗
		Animal dogWithHat = new AnimalWithHat(dog);
		dogWithHat.say();
		System.out.println("===========7=========");
		// 穿鞋的狗
		Animal dogWithShoes = new AnimalWithShoes(dog);
		dogWithShoes.say();
		System.out.println("==========8==========");
		// 给戴帽子的狗穿上鞋
		Animal dogWithHatAndShoes = new AnimalWithShoes(dogWithHat);
		dogWithHatAndShoes.say();
		System.out.println("===========9=========");
		// 给穿鞋的狗带上帽子
		Animal dogWithShoesAndHat = new AnimalWithHat(dogWithShoes);
		dogWithShoesAndHat.say();
		System.out.println("==========10==========");
	}

}

输出如下:

I am class Cat
==========1==========
I am class Dog
===========2=========
I am class Cat
I hava a hat
=========3===========
I am class Cat
I hava shoes
==========4==========
I am class Cat
I hava a hat
I hava shoes
===========5=========
I am class Cat
I hava shoes
I hava a hat
==========6==========
I am class Dog
I hava a hat
===========7=========
I am class Dog
I hava shoes
==========8==========
I am class Dog
I hava a hat
I hava shoes
===========9=========
I am class Dog
I hava shoes
I hava a hat
==========10==========

可以看到,我们只是实现了两种具体的动物与饰品,却可以生成十个不同的组合。以后扩展的话,可以任意增加动物与饰品的各类。这两个东西起越多,产生的组合也就越多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值