设计模式-装饰模式

定义

  在不改变现有对象结构以及不使用继承的情况下,给对象扩展功能。它是通过创建装饰对象,然后包裹目标对象的方式来完成。

使用继承的缺点

  我们下面给出案例:

	public class EggCake {
	
	    public String getDesc() {
	        return "鸡蛋饼";
	    }
	
	    public double getPrice() {
	        return 3;
	    }
	
	}
	
	
	public class EggCakePlusA extends EggCake {
	
	    @Override
	    public String getDesc() {
	        String desc = super.getDesc();
	        return desc + " + 煎蛋";
	    }
	
	    @Override
	    public double getPrice() {
	        double price = super.getPrice();
	        return price + 2;
	    }
	
	}
	
	
	public class EggCakePlusB extends EggCake {
	
	    @Override
	    public String getDesc() {
	        String desc = super.getDesc();
	        return desc + " + 火腿肠";
	    }
	
	    @Override
	    public double getPrice() {
	        double price = super.getPrice();
	        return price + 3.5;
	    }
	
	}
	
	
	public class Test {
	    public static void main(String[] args) {
	        EggCake eggCake = new EggCake();
	        System.out.println(eggCake.getDesc() + " 销售价格:" + 
	        eggCake.getPrice());
	
	        EggCakePlusA eggCakePlusA = new EggCakePlusA();
	        System.out.println(eggCakePlusA.getDesc() + " 销售价格:" + 
	        eggCakePlusA.getPrice());
	
	        EggCakePlusB eggCakePlusB = new EggCakePlusB();
	        System.out.println(eggCakePlusB.getDesc() + " 销售价格:" + 
	        eggCakePlusB.getPrice());
	    }
	}

  运行结果:

在这里插入图片描述
  如果这时候要既加煎蛋,又加火腿肠,是不是又要写一个类;加2个煎蛋,1根火腿肠,也要写?这样子扩展,类就无止境了,这就是使用继承的缺点。

角色定义

  基类角色:被装饰者角色和装饰者角色共同的父类,通常是一个抽象类
  被装饰者角色:继承基类,通过装饰者增强
  抽象装饰者角色:继承基类,并包含一个被装饰者的实例
  具体装饰者角色:继承抽象装饰者,重写方法,方法内部使用被装饰者实例和额外的代码来实现增强

代码实现

	/**
	 * 基类角色:饼
	 */
	public abstract class Cake {
	
	    public abstract String getDesc();
	
	    public abstract double price();
	
	}
	
	/**
	 * 被装饰者:鸡蛋饼
	 */
	public class EggCake extends Cake {
	
	    @Override
	    public String getDesc() {
	        return "鸡蛋饼";
	    }
	
	    @Override
	    public double price() {
	        return 4.5;
	    }
	
	}
	
	/**
	 * 抽象装饰者:加料
	 */
	public class Condiment extends Cake{
	
	    protected Cake cake;
	
	    public Condiment(Cake cake) {
	        this.cake = cake;
	    }
	
	    @Override
	    public String getDesc() {
	        return this.cake.getDesc();
	    }
	
	    @Override
	    public double price() {
	        return this.cake.price();
	    }
	
	}
	
	/**
	 * 具体装饰者:煎蛋
	 */
	public class FriedEgg extends Condiment{
	
	    public FriedEgg(Cake cake) {
	        super(cake);
	    }
	
	    @Override
	    public String getDesc() {
	        return super.getDesc() + " + 煎蛋";
	    }
	
	    @Override
	    public double price() {
	        return super.price() + 1.5;
	    }
	
	}
	
	/**
	 * 具体装饰者:火腿
	 */
	public class Ham extends Condiment{
	
	    public Ham(Cake cake){
	        super(cake);
	    }
	
	    @Override
	    public String getDesc() {
	        return super.getDesc() + " + 火腿";
	    }
	
	    @Override
	    public double price() {
	        return super.price() + 3.0;
	    }
	
	}
	
	/**
	 * 测试类
	 */
	public class Test {
	
	    public static void main(String[] args) {
	        Cake cake = new EggCake();
	        System.out.println(cake.getDesc() + ":" + cake.price());
	        cake = new FriedEgg(cake);
	        cake = new Ham(cake);
	        cake = new FriedEgg(cake);
	        System.out.println(cake.getDesc() + ":" + cake.price());
	    }
	
	}

  运行结果如下:

在这里插入图片描述

优缺点

  优点:

  • 增强对象的功能比采用继承方式更加灵活
  • 多个不同的具体装饰者,可以搭配出任意的组合
  • 装饰者和被装饰者解耦,可以独立发展

  缺点:

  • 仍然需要编写许多的具体装饰者
  • 过多的装饰,会让程序变得复杂
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值