装饰者模式:
思考问题:如果电脑最基础的功能是能够办公使用(function),但是用户买来之后可以在电脑原有的功能上增加功能,可以增加的功能是 可以进行代码开发(programing)、可以吃鸡(games)、能跑十台虚拟机(Virtual)、能看高清电影(movies),此时就是五种功能的任意组合,要在原有的电脑的基础上扩充新的功能,那么就要继承原来的功能的同时又增加新的功能,此时我们考虑使用继承或者是实现的方式来完成。
package com.sxt;
interface Computer{ //定义一个电脑接口
public void function();//所有功能
}
//定义一个子类
class MoviesComputer implements Computer{
@Override
public void function() {
System.out.println("可以办公!");
this.movies();
}
//子类可以扩充新的功能
public void movies() {
System.out.println("可以看电影!");
}
}
//定义一个子类
class VirtualComputer implements Computer{
@Override
public void function() {
System.out.println("可以办公!");
this.runVirtual();
}
//子类可以扩充新的功能
public void runVirtual() {
System.out.println("可以跑多台虚拟机!");
}
}
//定义一个子类
class GamesComputer implements Computer{
@Override
public void function() {
System.out.println("可以办公!");
this.playGames();
}
//子类可以扩充新的功能
public void playGames() {
System.out.println("可以吃鸡!");
}
}
public class Test{
public static void main(String[] args) {
}
}
此时就出现了大量的子类,子类瞬间暴增,导致了代码臃肿,不方便维护,于是就提出了一种叫做装饰者模式的开发思想,装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式(客户端可以任意组合新扩充的功能)扩展对象的功能,是继承关系的一个替代方案。
package com.sxt;
public class TestDemo06 {
public static void main(String[] args) {
InitalComputer i = new InitalComputer();
i.function();
System.out.println("^^^^^^^^^^^^^^^^^^^^^^");
MovieComputer m = new MovieComputer(i);
m.function();
System.out.println("^^^^^^^^^^^^^^^^^^^^^^");
VirtualComputer v = new VirtualComputer(new GameComputer(m));
v.function();
}
}
// 定义一个电脑接口
interface IComputer {
public void function();
}
// 定义一个具备原始功能的电脑
class InitalComputer implements IComputer {
// 最初的功能只有办公
@Override
public void function() {
System.out.println("可以办公");
}
}
// 定义一个抽象装饰者角色(要实现ICpmputer接口)
class SuperComputer implements IComputer {
private IComputer computer;
public SuperComputer(IComputer computer) {
this.computer = computer;
}
@Override
public void function() {
this.computer.function();
}
}
// 定义具体装饰者角色(可以玩游戏)
class GameComputer extends SuperComputer {
public GameComputer(IComputer computer) {
super(computer);
}
// 可以扩充新功能
public void palyGame() {
System.out.println("可以玩游戏");
}
@Override
public void function() {
super.function();
this.palyGame();
}
}
class MovieComputer extends SuperComputer {
public MovieComputer(IComputer computer) {
super(computer);
}
public void seeMovie() {
System.out.println("可以看电影");
}
@Override
public void function() {
super.function();
this.seeMovie();
}
}
class VirtualComputer extends SuperComputer {
public VirtualComputer(IComputer computer) {
super(computer);
}
public void runVirtual() {
System.out.println("可以跑虚拟机");
}
@Override
public void function() {
super.function();
this.runVirtual();
}
}
装饰模式指的是在不必改变原来文件和使用继承的情况下,动态地扩展一个对象的功能。他是通过创建一个包装对象,也就是装饰来包裹真实的对象
1.装饰对象和真实对象有相同的接口,这样客户端对象就能以和真实对象相同的方式和装饰对象交互
2.装饰对象包含一个真实对象的引用(reference)
优点
1.Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性,解决了使用继承带来的大量的子类。
2.通过使用不同的具体装饰以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合