设计模式—装饰者模式

设计模式—装饰者模式

引言

装饰者模式是一种常用的设计模式,它在软件开发中起到了很大的作用。当我们需要在不修改现有代码的情况下,动态地扩展或增强对象的功能时,装饰者模式是一种非常有效的解决方案。 在实际开发中,我们经常遇到需要对现有对象进行功能增强或叠加的情况。例如,我们可能希望给一个文本编辑器添加日志记录、发送通知等功能,但又不希望直接修改原始的文本编辑器类。这时,装饰者模式就可以派上用场。 装饰者模式通过持有对象和递归调用的方式,实现了功能的叠加和组合。它引入了抽象组件类和具体组件类的概念,以及装饰器类的作用。装饰器类继承自抽象组件类,并持有一个抽象组件对象作为成员变量。通过在其增强功能之前或之后,调用持有对象的方法,装饰器类实现了功能的递进增强。 在本文中,我们将深入探讨装饰者模式的原理和实现方式,并通过一个实例来演示如何应用装饰者模式。我们将使用一个简单的订单组件为例,通过添加装饰器类实现日志记录和发送通知的功能扩展。希望通过这个实例,您能更好地理解装饰者模式的运作机制和应用场景。 现在让我们开始探索装饰者模式的奥秘吧!

装饰者模式的基本概念和原理

装饰者模式通过持有对象递归调用的方式,实现功能的叠加和组合。它引入了抽象组件类具体组件类的概念,以及装饰器类的作用。装饰器类继承自抽象组件类,并持有一个抽象组件对象作为成员变量。装饰器类通过在其增强功能之前或之后,调用持有对象的方法,实现功能的递进增强。

代码

1.首先是抽象组件类 Order

javaCopy codepublic interface Order {
public void save();
}
javaCopy codepublic interface Order {

    public void save();

}
javaCopy codepublic interface Order { public void save(); }

这是一个接口,定义了订单组件的基本操作,其中只有一个方法 save() 用于保存订单。

2.然后是具体组件类 SimpleOrder

javaCopy codepublic class SimpleOrder implements Order {
@Override
public void save() {
System.out.println("保存订单");
}
}
javaCopy codepublic class SimpleOrder implements Order {

    @Override



    public void save() {

        System.out.println("保存订单");

    }

}
javaCopy codepublic class SimpleOrder implements Order { @Override public void save() { System.out.println("保存订单"); } }

这个类实现了 Order 接口,其中的 save() 方法实现了保存订单的操作。

3.接下来是装饰器接口 OrderDecorator

javaCopy codepublic interface OrderDecorator extends Order {
@Override
public void save();
}
javaCopy codepublic interface OrderDecorator extends Order {

    @Override



    public void save();

}
javaCopy codepublic interface OrderDecorator extends Order { @Override public void save(); }

这个接口继承了 Order 接口,并重新声明了 save() 方法。它作为装饰器类的基础,用于扩展订单组件的功能。

4.然后是具体装饰器类 LogOrderDecorator

javaCopy codepublic class LogOrderDecorator implements OrderDecorator {
Order order;
public LogOrderDecorator(Order order) {
this.order = order;
}
@Override
public void save() {
System.out.println("记录日志前");
order.save();
System.out.println("记录日志后");
}
}
javaCopy codepublic class LogOrderDecorator implements OrderDecorator {

    Order order;



    



    public LogOrderDecorator(Order order) {

        this.order = order;



    }



    



    @Override



    public void save() {



        System.out.println("记录日志前");

        order.save();

        System.out.println("记录日志后");

    }

}
javaCopy codepublic class LogOrderDecorator implements OrderDecorator { Order order; public LogOrderDecorator(Order order) { this.order = order; } @Override public void save() { System.out.println("记录日志前"); order.save(); System.out.println("记录日志后"); } }

这个类实现了 OrderDecorator 接口,并持有一个订单对象作为成员变量。在 save() 方法中,它在调用订单对象的 save() 方法之前和之后,添加了记录日志的功能。

5.接下来是另一个具体装饰器类 NoticeDecorator

javaCopy codepublic class NoticeDecorator implements OrderDecorator {
Order order;
public NoticeDecorator(Order order) {
this.order = order;
}
@Override
public void save() {
order.save();
System.out.println("发送通知");
}
}
javaCopy codepublic class NoticeDecorator implements OrderDecorator {

    Order order;



    



    public NoticeDecorator(Order order) {

        this.order = order;



    }



    



    @Override



    public void save() {



        order.save();

        System.out.println("发送通知");

    }

}
javaCopy codepublic class NoticeDecorator implements OrderDecorator { Order order; public NoticeDecorator(Order order) { this.order = order; } @Override public void save() { order.save(); System.out.println("发送通知"); } }

这个类同样实现了 OrderDecorator 接口,并持有一个订单对象作为成员变量。在 save() 方法中,它先调用订单对象的 save() 方法,然后添加了发送通知的功能。

6.在主方法中,我们可以使用这些类来创建装饰后的订单对象并调用方法:

javaCopy codepublic class Test {
public static void main(String[] args) {
Order order = new SimpleOrder();
Order logOrder = new LogOrderDecorator(order);
Order noticeOrder = new NoticeDecorator(logOrder);
noticeOrder.save();
}
}
javaCopy codepublic class Test {

    public static void main(String[] args) {

        Order order = new SimpleOrder();

        Order logOrder = new LogOrderDecorator(order);

        Order noticeOrder = new NoticeDecorator(logOrder);

        noticeOrder.save();

    }

}
javaCopy codepublic class Test { public static void main(String[] args) { Order order = new SimpleOrder(); Order logOrder = new LogOrderDecorator(order); Order noticeOrder = new NoticeDecorator(logOrder); noticeOrder.save(); } }

在这段代码中,首先创建了一个原始订单对象 SimpleOrder。然后,通过创建装饰器对象,并将原始订单对象作为构造函数的参数传入,依次进行装饰。最终,创建了一个经过装饰的订单对象 noticeOrder,它具有记录日志和发送通知的功能。通过调用 noticeOrder.save() 方法,实现了保存订单并进行装饰功能的操作。

运行结果

首先,我们创建了 LogOrderDecorator 对象 logOrder,它持有了原始订单对象 order。当调用 logOrder.save() 方法时,首先会输出”记录日志前”,然后调用 order.save() 方法,即调用了原始订单对象的 save() 方法,即输出”保存订单”。最后,输出”记录日志后”。

接下来,我们创建了 NoticeDecorator 对象 noticeOrder,它持有了 logOrder 对象。当调用 noticeOrder.save() 方法时,会先调用 logOrder.save() 方法。由于 logOrder 对象实际上是 order 对象的装饰器,所以在调用 logOrder.save() 方法时,会再次执行上述的步骤,即先输出”记录日志前”,然后调用 order.save() 方法,输出”保存订单”,最后输出”记录日志后”。接着,在 noticeOrder.save() 方法中,输出”发送通知”。

所以,最终的运行结果是:

记录日志前
保存订单
记录日志后
发送通知
记录日志前

保存订单

记录日志后

发送通知
记录日志前 保存订单 记录日志后 发送通知

可以看出,装饰器模式中,装饰器类可以在持有对象的方法调用前后,增加额外的功能。通过递归调用持有对象的方法,装饰器类实现了功能的递进增强。

符合原则

  1. 单一职责原则:装饰者模式使得每个类都专注于单一的功能,实现了代码的高内聚。这样,我们可以将复杂的功能拆分为多个简单的装饰器类,并按需组合它们,从而提高了代码的可读性和可维护性。
  2. 开闭原则:通过添加新的装饰器类,我们可以扩展对象的功能,而无需修改已有的代码。这符合开闭原则,使系统具备良好的可扩展性和可维护性。

适用场景

  1. 动态地为对象添加功能:当需要在运行时动态地为对象添加额外的功能,而且希望这些功能能够灵活组合,装饰者模式是一个理想的选择。
  2. 避免继承的复杂性:通过使用装饰者模式,可以避免使用过多的继承关系,减少类的数量,降低代码的复杂性。
  3. 按需定制对象功能:装饰者模式使得我们可以根据需求选择性地添加功能,而不会影响到其他对象。这样,我们可以根据具体的业务场景,灵活地组合装饰器类,实现定制化的功能组合。

设计模式—装饰者模式

引言

装饰者模式是一种常用的设计模式,它在软件开发中起到了很大的作用。当我们需要在不修改现有代码的情况下,动态地扩展或增强对象的功能时,装饰者模式是一种非常有效的解决方案。 在实际开发中,我们经常遇到需要对现有对象进行功能增强或叠加的情况。例如,我们可能希望给一个文本编辑器添加日志记录、发送通知等功能,但又不希望直接修改原始的文本编辑器类。这时,装饰者模式就可以派上用场。 装饰者模式通过持有对象和递归调用的方式,实现了功能的叠加和组合。它引入了抽象组件类和具体组件类的概念,以及装饰器类的作用。装饰器类继承自抽象组件类,并持有一个抽象组件对象作为成员变量。通过在其增强功能之前或之后,调用持有对象的方法,装饰器类实现了功能的递进增强。 在本文中,我们将深入探讨装饰者模式的原理和实现方式,并通过一个实例来演示如何应用装饰者模式。我们将使用一个简单的订单组件为例,通过添加装饰器类实现日志记录和发送通知的功能扩展。希望通过这个实例,您能更好地理解装饰者模式的运作机制和应用场景。 现在让我们开始探索装饰者模式的奥秘吧!

装饰者模式的基本概念和原理

装饰者模式通过持有对象递归调用的方式,实现功能的叠加和组合。它引入了抽象组件类具体组件类的概念,以及装饰器类的作用。装饰器类继承自抽象组件类,并持有一个抽象组件对象作为成员变量。装饰器类通过在其增强功能之前或之后,调用持有对象的方法,实现功能的递进增强。

代码

1.首先是抽象组件类 Order

javaCopy codepublic interface Order {
public void save();
}
javaCopy codepublic interface Order {

    public void save();

}
javaCopy codepublic interface Order { public void save(); }

这是一个接口,定义了订单组件的基本操作,其中只有一个方法 save() 用于保存订单。

2.然后是具体组件类 SimpleOrder

javaCopy codepublic class SimpleOrder implements Order {
@Override
public void save() {
System.out.println("保存订单");
}
}
javaCopy codepublic class SimpleOrder implements Order {

    @Override



    public void save() {

        System.out.println("保存订单");

    }

}
javaCopy codepublic class SimpleOrder implements Order { @Override public void save() { System.out.println("保存订单"); } }

这个类实现了 Order 接口,其中的 save() 方法实现了保存订单的操作。

3.接下来是装饰器接口 OrderDecorator

javaCopy codepublic interface OrderDecorator extends Order {
@Override
public void save();
}
javaCopy codepublic interface OrderDecorator extends Order {

    @Override



    public void save();

}
javaCopy codepublic interface OrderDecorator extends Order { @Override public void save(); }

这个接口继承了 Order 接口,并重新声明了 save() 方法。它作为装饰器类的基础,用于扩展订单组件的功能。

4.然后是具体装饰器类 LogOrderDecorator

javaCopy codepublic class LogOrderDecorator implements OrderDecorator {
Order order;
public LogOrderDecorator(Order order) {
this.order = order;
}
@Override
public void save() {
System.out.println("记录日志前");
order.save();
System.out.println("记录日志后");
}
}
javaCopy codepublic class LogOrderDecorator implements OrderDecorator {

    Order order;



    



    public LogOrderDecorator(Order order) {

        this.order = order;



    }



    



    @Override



    public void save() {



        System.out.println("记录日志前");

        order.save();

        System.out.println("记录日志后");

    }

}
javaCopy codepublic class LogOrderDecorator implements OrderDecorator { Order order; public LogOrderDecorator(Order order) { this.order = order; } @Override public void save() { System.out.println("记录日志前"); order.save(); System.out.println("记录日志后"); } }

这个类实现了 OrderDecorator 接口,并持有一个订单对象作为成员变量。在 save() 方法中,它在调用订单对象的 save() 方法之前和之后,添加了记录日志的功能。

5.接下来是另一个具体装饰器类 NoticeDecorator

javaCopy codepublic class NoticeDecorator implements OrderDecorator {
Order order;
public NoticeDecorator(Order order) {
this.order = order;
}
@Override
public void save() {
order.save();
System.out.println("发送通知");
}
}
javaCopy codepublic class NoticeDecorator implements OrderDecorator {

    Order order;



    



    public NoticeDecorator(Order order) {

        this.order = order;



    }



    



    @Override



    public void save() {



        order.save();

        System.out.println("发送通知");

    }

}
javaCopy codepublic class NoticeDecorator implements OrderDecorator { Order order; public NoticeDecorator(Order order) { this.order = order; } @Override public void save() { order.save(); System.out.println("发送通知"); } }

这个类同样实现了 OrderDecorator 接口,并持有一个订单对象作为成员变量。在 save() 方法中,它先调用订单对象的 save() 方法,然后添加了发送通知的功能。

6.在主方法中,我们可以使用这些类来创建装饰后的订单对象并调用方法:

javaCopy codepublic class Test {
public static void main(String[] args) {
Order order = new SimpleOrder();
Order logOrder = new LogOrderDecorator(order);
Order noticeOrder = new NoticeDecorator(logOrder);
noticeOrder.save();
}
}
javaCopy codepublic class Test {

    public static void main(String[] args) {

        Order order = new SimpleOrder();

        Order logOrder = new LogOrderDecorator(order);

        Order noticeOrder = new NoticeDecorator(logOrder);

        noticeOrder.save();

    }

}
javaCopy codepublic class Test { public static void main(String[] args) { Order order = new SimpleOrder(); Order logOrder = new LogOrderDecorator(order); Order noticeOrder = new NoticeDecorator(logOrder); noticeOrder.save(); } }

在这段代码中,首先创建了一个原始订单对象 SimpleOrder。然后,通过创建装饰器对象,并将原始订单对象作为构造函数的参数传入,依次进行装饰。最终,创建了一个经过装饰的订单对象 noticeOrder,它具有记录日志和发送通知的功能。通过调用 noticeOrder.save() 方法,实现了保存订单并进行装饰功能的操作。

运行结果

首先,我们创建了 LogOrderDecorator 对象 logOrder,它持有了原始订单对象 order。当调用 logOrder.save() 方法时,首先会输出”记录日志前”,然后调用 order.save() 方法,即调用了原始订单对象的 save() 方法,即输出”保存订单”。最后,输出”记录日志后”。

接下来,我们创建了 NoticeDecorator 对象 noticeOrder,它持有了 logOrder 对象。当调用 noticeOrder.save() 方法时,会先调用 logOrder.save() 方法。由于 logOrder 对象实际上是 order 对象的装饰器,所以在调用 logOrder.save() 方法时,会再次执行上述的步骤,即先输出”记录日志前”,然后调用 order.save() 方法,输出”保存订单”,最后输出”记录日志后”。接着,在 noticeOrder.save() 方法中,输出”发送通知”。

所以,最终的运行结果是:

记录日志前
保存订单
记录日志后
发送通知
记录日志前

保存订单

记录日志后

发送通知
记录日志前 保存订单 记录日志后 发送通知

可以看出,装饰器模式中,装饰器类可以在持有对象的方法调用前后,增加额外的功能。通过递归调用持有对象的方法,装饰器类实现了功能的递进增强。

符合原则

  1. 单一职责原则:装饰者模式使得每个类都专注于单一的功能,实现了代码的高内聚。这样,我们可以将复杂的功能拆分为多个简单的装饰器类,并按需组合它们,从而提高了代码的可读性和可维护性。
  2. 开闭原则:通过添加新的装饰器类,我们可以扩展对象的功能,而无需修改已有的代码。这符合开闭原则,使系统具备良好的可扩展性和可维护性。

适用场景

  1. 动态地为对象添加功能:当需要在运行时动态地为对象添加额外的功能,而且希望这些功能能够灵活组合,装饰者模式是一个理想的选择。
  2. 避免继承的复杂性:通过使用装饰者模式,可以避免使用过多的继承关系,减少类的数量,降低代码的复杂性。
  3. 按需定制对象功能:装饰者模式使得我们可以根据需求选择性地添加功能,而不会影响到其他对象。这样,我们可以根据具体的业务场景,灵活地组合装饰器类,实现定制化的功能组合。

总结

装饰者模式的核心思想是通过装饰器类来增强或扩展一个基础组件对象的功能,而不需改动原始组件的代码。这个模式引入了抽象组件类、具体组件类和装饰器类。

装饰器类继承自抽象组件类,同时持有一个抽象组件对象作为成员变量。装饰器类通过在增强功能之前或之后,递归地调用持有对象的方法,实现功能的叠加和组合。

通过这种方式,我们可以动态地为组件对象添加新的功能,而不需要修改已有代码。我们可以根据需求,灵活地组合不同的装饰器类,以实现不同的功能组合效果。

这种模式的优势在于它提供了一种灵活的扩展方式,允许我们在运行时动态地添加、移除或替换功能。它也符合开闭原则,因为我们可以通过添加新的装饰器类来扩展功能,而无需修改已有代码。

总的来说,装饰者模式通过装饰器类的持有对象和递归调用的机制,实现了功能的叠加和组合。这使得我们能够轻松地扩展和定制对象的功能,而不破坏其原有结构和行为。

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MY8a5GbE' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片