设计模式——装饰模式

本文详细介绍了装饰模式,包括其概述、结构(抽象构件、具体构件、抽象装饰类、具体装饰类),并给出咖啡计价软件的实例。还阐述了透明装饰模式和半透明装饰模式的特点及使用方式,帮助理解如何动态给对象增加额外职责。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

装饰模式概述

动态的给一个对象增加一些额外的职责

装饰模式结构

1.Component(抽象构件)

它是具体构件和抽象装饰类的共同父类。声明了一种业务,该业务在具体构件里面实现。

2.ConcreteComponent(具体构件)

它是抽象构件的子类,实现了抽象构件中声明的方法,且抽象装饰类可以给他增加额外的职责。

3.Decorator(抽象装饰类)

它也是抽象构件的子类,用于给具体构件增加额外的方法,但只是声明,具体的实现交给具体装饰类。它维护了一个指向抽象构件对象的引用,通过这个引用调用装饰之前的业务,并通过子类实现扩展,达到装饰的目的。

4.ConcreteDecorator(具体装饰类)

它是抽象装饰类的子类, 实现抽象装饰类中的方法,给具体构件添加新的业务。

装饰模式实例(作业)

某咖啡店为了满足顾客的口味,允许顾客可以在普通咖啡Coffee (5.00元)中自由地加入多种配料(糖Sugar 1.50元、奶Milch 1.00元、冰Ice 0.50元等)。给咖啡店设计一个咖啡计价(calcAmount(): BigDecimal)软件,该软件要遵守面向对象设计原则,咖啡的价格随着加入的配料而变化,并满足咖啡店后期可能还会增加新配料(如巧克力Chocolate等)和咖啡品种的需求。注意金额精度问题!

设计类图

在这里插入图片描述

Component(抽象构件)

import java.math.BigDecimal;
public abstract class Component {
    public abstract BigDecimal calcAmount();
}

Coffee(具体结构)

import java.math.BigDecimal;
public class Coffee extends Component{
    @Override
    public BigDecimal calcAmount() {
        return new BigDecimal("5.00");
    }
}

Decorator(抽象装饰类)

import java.math.BigDecimal;
public class Decorator extends Component{
    private Component component;
    public Decorator(Component component) {
        this.component = component;
    }
    @Override
    public BigDecimal calcAmount() {
        return component.calcAmount();
    }
}

Suger、Ice、Milk(具体装饰类)

import java.math.BigDecimal;
public class Suger extends Decorator{
    static private double price=1.50;
    public Suger(Component component) {
        super(component);
    }
    @Override
    public BigDecimal calcAmount() {
        BigDecimal bigDecimal=new BigDecimal(addsuger());
        return super.calcAmount().add(bigDecimal);
    }
    public String addsuger(){
        return "1.50";
    }
}
public class Milk extends Decorator{
    public Milk(Component component) {
        super(component);
    }
    @Override
    public BigDecimal calcAmount() {
        BigDecimal bigDecimal=new BigDecimal(addmike());
        return super.calcAmount().add(bigDecimal);
    }
    public String addmike(){
        return "1.00";
    }
}
public class Ice extends Decorator {
    public Ice(Component component) {
        super(component);
    }
    @Override
    public BigDecimal calcAmount() {
        BigDecimal bigDecimal=new BigDecimal(addice());//把加冰转换为BigDecimal
        return super.calcAmount().add(bigDecimal);
    }//
    public String addice(){
        return "0.50";
    }
}

透明装饰模式与半透明装饰模式

透明装饰模式

无论是创建具体构件对象,还是具体装饰对象。我们统一使用Component(抽象构件)来声明这些对象。这一特点使得,透明装饰模式可以对同一个对象,装饰多次。

client代码

import java.math.BigDecimal;
public class client {
    public static void main(String[] args) {
        Component componentone=new Coffee();//父类使用子类的构造函数,用多态calcAmount()更新自己的方法。
        Component componentone1=new Suger(componentone);
        Component componentone2=new Milk(componentone1);
        Component componentone3=new Milk(componentone2);
        BigDecimal sum=componentone3.calcAmount();//记录顾客最终付费的coffee价格
        System.out.println("顾客一花费:"+sum);//顾客一

        Component componenttwo=new Coffee();//父类使用子类的构造函数,用多态calcAmount()更新自己的方法。
        Component componenttwo1=new Suger(componenttwo);
        Component componenttwo2=new Ice(componenttwo1);
        Component componenttwo3=new Milk(componenttwo2);
        BigDecimal sum2=componenttwo3.calcAmount();//记录顾客最终付费的coffee价格
        System.out.println("顾客二花费:"+sum2);//顾客二
    }
}

坏处是具体装饰类(Ice,Suger,Milk)里面扩展的方法,没法使用,只能用Component里面有的方法。

半透明装饰模式

为了用具体装饰类里面的方法,一部分用Ice,Suger,Milk声明这些对象

client代码

import java.math.BigDecimal;

public class client1 {
    public static void main(String[] args) {
        Component component=new Coffee();
        Ice ice=new Ice(component);
        BigDecimal sum=ice.calcAmount().add(new BigDecimal(ice.addice()));
        System.out.println(sum);
    }
}

这个相当于加了两遍冰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值