设计模式十:装饰器(Decorator)

现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等,都是装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时为对象动态地添加额外的行为或功能,而无需修改原始类的代码。该模式通过创建一个包装器,即装饰器,来包裹原始对象,并以透明的方式扩展其功能。装饰器和原始对象都实现了相同的接口,这使得它们可以互相替代使用。

装饰器模式适用于以下场景:

装饰器模式适用于需要在运行时动态地扩展对象功能,以及对核心对象进行修改但又不希望直接修改其代码的情况。它提供了一种灵活且无侵入性的方式来添加新功能,并允许根据需要组合多个装饰器以实现不同的行为变化

  1. 当你需要在不修改现有对象代码的情况下,动态地给一个对象添加新的行为或功能时,可以使用装饰器模式。它允许你通过包装对象来扩展其功能。
  2. 当你希望能够在运行时选择要添加的特定行为时,装饰器模式非常有用。你可以根据需要动态地组合多个装饰器,以实现不同的行为组合效果。
  3. 当你有一个核心对象,并且希望能够在不影响其他对象的情况下对其进行修改时,装饰器模式是一种很好的选择。由于装饰器模式使用了继承关系,因此你可以针对不同的需求创建多个具体装饰器类,并通过组合它们以满足所需的行为变化。这样就避免了直接修改核心对象的代码。
  4. 当你想要以层次结构的方式动态地组合对象时,可以使用装饰器模式。你可以通过创建多个具体装饰器类并将它们嵌套在一起,形成一个层次结构,从而实现更复杂的行为组合。
  5. 当你想要在不同的时间点为一个对象添加或删除特定行为时,装饰器模式是一个很好的选择。你可以根据需要随时添加或删除特定的装饰器,而不需要修改对象的代码。

装饰器模式中的核心角色包括:

  1. 抽象构件(Component):定义了原始对象和装饰器的公共接口。
  2. 具体构件(Concrete Component):实现了抽象构件的接口,表示原始对象。
  3. 装饰器(Decorator):持有一个抽象构件的引用,并实现了抽象构件接口,用于添加额外的行为或功能。
  4. 具体装饰器(Concrete Decorator):扩展了装饰器的功能,可以在调用原始对象的方法之前或之后执行额外的操作。

装饰器模式代码实践

用装饰模式来完成Coffee的制作具体实现
要求:Coffee有两种款式,浓Coffee和淡Coffee
利用装饰模式加料:牛奶,巧克力
涉及的所有类:

抽象构件:Coffee

/**
 * coffee制作接口:抽象构件接口,表示咖啡 
 */
ublic interface Coffee {
    String getDescription();//获取对应的描述 
    int getPrice();//获取价格
}

具体构件:LightCoffee、StrongCoffee

public class LightCoffee implements Coffee{
    @Override    
    public String getDescription() {
        return "you will get a cap of LightCoffee"; 
      }

    @Override    
    public int getPrice() {
        return 18;    
        }
}
/**
 * 浓咖啡
  */
public class StrongCoffee implements Coffee {

    @Override    
    public String getDescription() {
        return "you will get a cap of StrongCoffee";
        }

    @Override    
    public int getPrice() {
        return 20;
       }
}

抽象装饰器:CoffeeDecorator

/**
 * 实现一个抽象的Coffee装饰器
 */
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public String getDescription() {
        return coffee.getDescription();
    }

    public int getPrice() {
        return coffee.getPrice();
    }

}

具体装饰器:Chocolate、Milk、Mocha

public class Chocolate extends CoffeeDecorator {
    public Chocolate(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + " with Chocolate";
    }

    @Override
    public int getPrice() {
        return coffee.getPrice() + 12;
    }

}

public class Milk extends CoffeeDecorator {

    public  Milk(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return coffee.getDescription()+" with Milk";
    }

    @Override
    public int getPrice() {
        return coffee.getPrice() + 8;
    }

}

public class Mocha extends CoffeeDecorator{
    public Mocha(Coffee coffee) {
        super(coffee);
    }
    @Override
    public String getDescription() {
        return coffee.getDescription()+" with Mocha";
    }

    @Override
    public int getPrice() {
        return coffee.getPrice() +16;
    }

}

运行结果:

public static void main(String[] args) {
        //创建一杯浓coffee
        Coffee strongCoffee = new StrongCoffee();
        System.out.println(strongCoffee.getDescription() + "~it cost :" + strongCoffee.getPrice());

        //创建一杯带有牛奶的浓coffee
        Coffee strongCoffeeWithMilk = new Milk(strongCoffee);
        System.out.println(strongCoffeeWithMilk.getDescription() + "~it cost :" + strongCoffeeWithMilk.getPrice());

        //创建一杯牛奶和巧克力的淡Coffee
        Coffee lightCoffee = new LightCoffee();
        Coffee lightCoffeeWithMilk = new Milk(lightCoffee);
        Coffee lightCoffeeWithMilkAndChocolate = new Chocolate(lightCoffeeWithMilk);
        System.out.println(lightCoffeeWithMilkAndChocolate.getDescription() + "~it cost :" + lightCoffeeWithMilkAndChocolate.getPrice());

    }

you will get a cap of StrongCoffee~it cost :20
you will get a cap of StrongCoffee with Milk~it cost :28
you will get a cap of LightCoffee with Milk with Chocolate~it cost :38

以上示例演示了如何使用装饰器模式来制作咖啡。通过创建具体的咖啡类和装饰器类,我们可以在运行时动态地添加额外的配料或功能,而不需要修改原始咖啡类的代码。

装饰器模式的优缺点

装饰器模式的优点包括:

  1. 动态扩展功能:装饰器模式允许在运行时动态地为对象添加新的功能,而无需修改现有代码。这使得系统更具灵活性和可扩展性。
  2. 组合多个装饰器:通过使用多个装饰器,你可以在对象上组合不同的功能,以实现各种组合效果。这样可以避免类的继承关系变得过于复杂,提高了代码的可读性和可维护性。
  3. 分离关注点:装饰器模式将功能的添加与核心对象的实现分离开来,使得各个功能模块可以独立开发和测试。这使得代码更加清晰、易于理解和维护。
  4. 遵循开闭原则:装饰器模式符合开闭原则,即对扩展开放,对修改关闭。通过使用装饰器模式,你可以在不修改现有代码的情况下,通过添加新的装饰器来扩展功能。

装饰器模式的缺点包括:

  1. 可能产生过多的小对象:装饰器模式涉及创建多个对象,并将它们嵌套在一起,可能会导致系统中存在大量的小对象。这可能会增加内存使用和运行时开销。
  2. 可能增加复杂度:当装饰器的层次结构变得复杂时,理解和维护代码可能会变得困难。过多的装饰器可能会使代码变得混乱并且难以debug。
  3. 需要注意继承问题:装饰器模式是通过继承来实现的,因此需要特别注意父类与子类之间的关系。如果不正确地设计和使用装饰器模式,可能会导致继承关系变得复杂和脆弱。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值