Java设计模式之java装饰者模式详解

Java设计模式之装饰者模式详解

什么是装饰者模式?

装饰者模式又叫包装模式,它是一种结构型设计模式。装饰者模式可以在运行时给对象动态添加一些额外的职责,而不影响该对象的行为。其实我们在生活中也经常使用到装饰者模式,比如将一个普通房间粉刷成卧室或客厅,这样就给房间添加了额外的功能,而且不会影响原有房间的结构和功能。

装饰者模式的角色和实现方式

装饰者模式有如下角色:

抽象构件(Component):定义一个抽象接口,用于规范具体构件和装饰对象的行为。

public interface Component {
    void operation();
}

具体构件(ConcreteComponent):实现抽象构件接口的类,也可以称作被装饰器装饰的对象。

public class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("执行ConcreteComponent的操作");
    }
}

装饰者(Decorator):实现抽象构件(Component)接口的类,并持有一个抽象构件(Component)的引用,用于装饰具体构件的功能。

public abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

具体装饰者(ConcreteDecorator):实现装饰者(Decorator)接口,具体实现装饰者需要扩展Component功能的方法,同时还包含被装饰对象ConcreteComponent。

public class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addBehavior();
    }

    private void addBehavior() {
        System.out.println("装饰添加的行为");
    }
}

装饰者模式的示例

示例1:给文本添加加粗和颜色功能

现在我们需要在文本中添加加粗和颜色的功能,我们可以使用装饰者模式,具体步骤如下:

  1. 首先定义抽象构件:文本Component。
public interface TextComponent {
    void draw();
}
  1. 定义具体构件:普通文本ConcreteText。
public class ConcreteText implements TextComponent {
    private String text;

    public ConcreteText(String text) {
        this.text = text;
    }

    @Override
    public void draw() {
        System.out.print(text);
    }
}
  1. 定义装饰者Decorator:所有装饰器的父类,和Component相同的接口。
public abstract class Decorator implements TextComponent {
    private TextComponent component;

    public Decorator(TextComponent component) {
        this.component = component;
    }

    @Override
    public void draw() {
        component.draw();
    }
}
  1. 定义具体装饰者ConcreteDecorator:实现具体装饰效果。
public class BoldDecorator extends Decorator {
    public BoldDecorator(TextComponent component) {
        super(component);
    }

    @Override
    public void draw() {
        System.out.print("<b>");
        super.draw();
        System.out.print("</b>");
    }
}

public class ColorDecorator extends Decorator {
    private String color;

    public ColorDecorator(TextComponent component, String color) {
        super(component);
        this.color = color;
    }

    @Override
    public void draw() {
        System.out.print("<font color=\"" + color + "\">");
        super.draw();
        System.out.print("</font>");
    }
}
  1. 最后使用装饰者来给文本添加加粗和颜色的功能。
TextComponent text = new ConcreteText("Hello World!");
TextComponent boldText = new BoldDecorator(text);
TextComponent boldRedText = new ColorDecorator(boldText, "red");
boldRedText.draw();

上述代码会输出:

<b><font color="red">Hello World!</font></b>

示例2:给订单添加促销折扣功能

假设我们有一个订单,现在需要为订单添加促销折扣的功能,我们仍然可以使用装饰者模式,具体步骤如下:

  1. 定义抽象构件:订单Component。
public interface OrderComponent {
    double calcCost(); //计算订单费用
}
  1. 定义具体构件:普通订单ConcreteOrder。
public class ConcreteOrder implements OrderComponent {
    private double cost;

    public ConcreteOrder(double cost) {
        this.cost = cost;
    }

    @Override
    public double calcCost() {
        return cost;
    }
}
  1. 定义装饰者Decorator:所有装饰器的父类,和Component相同的接口。
public abstract class Decorator implements OrderComponent{
    private OrderComponent order;

    public Decorator(OrderComponent order) {
        this.order = order;
    }

    @Override
    public double calcCost() {
        return order.calcCost();
    }
}
  1. 定义具体装饰者ConcreteDecorator:实现具体装饰效果。
public class DiscountDecorator extends Decorator {
    private double discount;

    public DiscountDecorator(OrderComponent order, double discount) {
        super(order);
        this.discount = discount;
    }

    @Override
    public double calcCost() {
        return super.calcCost() * discount;
    }

    public void setDiscount(double discount) {
        this.discount = discount;
    }
}

public class GiftDecorator extends Decorator {
    private String giftName; 

    public GiftDecorator(OrderComponent order, String giftName) {
        super(order);
        this.giftName = giftName;
    }

    @Override
    public double calcCost() {
        double cost = super.calcCost();
        System.out.println("送一份" + giftName);
        return cost;
    }
}
  1. 最后使用装饰者来给订单添加促销折扣的功能。
OrderComponent order = new ConcreteOrder(100);
OrderComponent discountOrder = new DiscountDecorator(order, 0.8);
OrderComponent giftOrder = new GiftDecorator(discountOrder, "优惠券");
double cost = giftOrder.calcCost();
System.out.println("订单总费用:" + cost);

上述代码会输出:

送一份优惠券
订单总费用:80.0

总结

在需求变化较多或需要动态添加额外功能的情况下,装饰者模式是一种很好的设计模式。但是,由于装饰者模式增加了很多小对象,过度使用也会导致程序变得复杂。在实践中,我们应该根据具体的情况来决定是否使用装饰者模式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之java装饰者模式详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Typescript是必须要学习吗?如何学习TS全栈开发

    Typescript是一种开源的编程语言,由微软开发和维护。它是Javascript的超集,意味着它支持Javascript中的所有功能。尽管Typescript在开发本质上与Javascript相同,但它提供了一些额外的功能,主要是类型系统和面向对象编程的概念,这些功能使得开发更加轻松和规范化。 Typescript的优点: 更快的开发:可以通过类型检查避…

    Java 2023年5月23日
    00
  • 什么是软引用?

    软引用是一个在Java中用于动态管理内存的概念。它是一种弱化的引用,被设计成用于指向那些后备缓存数据的对象。Java垃圾回收器通常会尽可能长的保留软引用指向的对象,但当系统内存不足时,垃圾回收器会自动释放这些软引用指向的对象。 常见的使用场景包括图片缓存、数据库缓存等,使用软引用可以更灵活地管理缓存数据,同时也可以防止OOM(Out of Memory)错误…

    Java 2023年5月10日
    00
  • SpringMVC项目异常处理机制详解

    在 SpringMVC 项目中,异常处理是非常重要的一部分。如果不正确地处理异常,可能会导致应用程序崩溃或者出现安全漏洞。本文将详细讲解 SpringMVC 项目异常处理机制,包括异常处理器的编写、异常处理流程、异常处理方式等。 编写异常处理器 在 SpringMVC 项目中,我们可以通过编写异常处理器来处理异常。异常处理器是一个类,它实现了 Spring …

    Java 2023年5月18日
    00
  • JavaScript 引用类型实例详解【数组、对象、严格模式等】

    JavaScript 引用类型实例详解 在 JavaScript 中,引用类型是一种数据结构类型,它们不同于基本类型,基本类型是按值传递,而引用类型则是按引用传递,即在内存中存放的是该值在堆内存中存放的地址,而不是该值本身。常见的引用类型包括数组、对象、函数等。 数组 数组是一种可以存储一组有序数据的集合,它是一种可以动态扩展的对象。数组的声明方式如下: l…

    Java 2023年5月26日
    00
  • Java中如何正确重写equals方法

    Java中的equals方法通常需要被重写,以便进行对象之间的比较。正确重写equals方法不仅可以提高代码质量,而且可以避免因错误的比较导致的程序错误。下面是Java中如何正确重写equals方法的完整攻略。 1. 理解equals方法 在开始重写equals方法之前,我们需要先理解equals方法的作用以及如何使用它来比较两个对象。在Java中,equa…

    Java 2023年5月26日
    00
  • Java中的collection集合类型总结

    Java中的Collection集合类型总结 Collection是Java中常用的一种数据结构,它可以简化我们对数据的操作,提高数据处理的效率。在Java中,集合类型主要分为三大类:List、Set和Map。本文将对这三大类集合类型进行详细总结和说明。 1. List集合类型 List集合类型是有序的、可重复的集合类型。它的实现类主要有ArrayList、…

    Java 2023年5月26日
    00
  • JAVA/JSP学习系列之六(MySQL翻页例子)

    JAVA/JSP学习系列之六(MySQL翻页例子) 本文将介绍如何使用JAVA和JSP实现MySQL翻页效果,以充分利用数据库的性能,同时提高用户体验。 1. 分页原理 分页语句的基本语法如下: SELECT * FROM table LIMIT start, size 其中,start表示起始位置,size表示获取的数据数量。我们可以通过计算来动态生成LI…

    Java 2023年6月15日
    00
  • springboot中jsp配置tiles全过程

    下面是Spring Boot中配置JSP和Tiles的整个过程及两个示例展示。 1. 引入JSP和Tiles依赖 首先,在pom.xml中添加JSP和Tiles的依赖: <!–JSP依赖–> <dependency> <groupId>org.apache.tomcat.embed</groupId> &l…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部