我们在学习 Spring 时会先学习代理模式:包括静态代理与动态代理。
在学习静态代理模式时,总感觉与装饰者模式特别像,有时候会特别迷茫,自己写的到底是代理模式还是装饰者模式。那么代理模式与装饰者模式的本质区别是什么呢?
我也看过很多大牛写的关于两者的区别,意思是说到了,但是总感觉写得太多专业,不太好理解。
那么如何更简单的理解两者的区别呢?其实非常简单,从使用者的角度来理解,是最简单的。
如下代码:代理模式
public class Client { public static void main(String[] args) { /** * 使用者只与代理类交互,根本不知道代理类调用IUserService 哪个实现类 * * 这种就是代理模式 * */ IUserService userService = new UserServiceProxy(); userService.addUser(); } }
装饰者模式:
public class Client { public static void main(String[] args) { /** * 使用者自己创建IUserSerivce的实现类,然后将创建的对象,交由装饰器进行装饰,即是进行功能加强 * * 这种就是装饰者模式。 */ IUserService userServiceImpl = new UserServiceImpl(); IUserService userService = new UserServiceDecorator(userServiceImpl); userService.addUser(); /** * 使用者只与代理类交互,根本不知道代理类调用IUserService 哪个实现类 * * 这种就是代理模式 * */ //IUserService userService = new UserServiceProxy(); //userService.addUser(); } }
通过使用者可以看出:
代理模式:使用者根本不用关心实现类是谁。
装饰者模式:使用者需要自己创建实现类对象,然后转给装饰器进行功能加强。
看似是两个小小的区别,在现实生活中,可以很容易找到原型。
(1)我们租房子时,我们只要去房屋中介说我要租房子。根本不用关心房东是谁,如何找到房东,中介会帮我们搞定。所以代理模式的本质就是使用者根本不用关心具体的实现类。
(2)装饰者模式,比如我们买了一套房子,我们要装修,我们去装修公司说,我的这套房子(具体的对象)要装修,那么装修公司就会以你传入的对象(你的房子)作为基础来进行装修。
其实我们再看看代理模式与装饰者模式的代码,主能看出,其实写法差异并不大。
(1)创建一个 IUserService 接口,暂时只有一个方法,添加用户 addUser()
/** * 客户服务接口 * * @author hasee * */ public interface IUserService { public void addUser(); }
(2) 具体的实现类 UserServiceImpl
public class UserServiceImpl implements IUserService { @Override public void addUser() { System.out.println("UserService 添加用户!"); } }
(3) 创建代理类,主要是代理类同样也实现 IUserService 接口,并创建一个具体对象的引用,
并在构造方法中自己创建具体实现类对象。
public class UserServiceProxy implements IUserService { private IUserService userService; public UserServiceProxy() { this.userService = new UserServiceImpl(); } public void addUser() { this.userService.addUser(); log("成功添加一条客户数据!"); } public void log(String content) { System.out.println("添加日志:" + content); } }
(4)创建装饰者类,同样实现IUserService ,只是实现类需要使用者传入。
public class UserServiceDecorator implements IUserService { private IUserService userService; public UserServiceDecorator(IUserService userService) { this.userService = userService; } @Override public void addUser() { this.userService.addUser(); log("成功添加一条客户数据!"); } public void log(String content) { System.out.println("添加日志:" + content); } }
相关推荐
设计模式分为三类:创建型模式(如单例模式、工厂模式、抽象工厂模式)、结构型模式(如代理模式、适配器模式、装饰器模式)和行为型模式(如观察者模式、策略模式、职责链模式)。这些模式在Java开发中有着广泛的...
**3.2 代理模式** - 为其他对象提供一个代理以控制对这个对象的访问。 **3.3 适配器模式** - 将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 ...
如代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式和组合模式等。 - **行为型模式**:关注于类之间的协作和职责分配,以便完成复杂的任务。包括模板方法模式、策略模式、命令模式、职责链模式、状态...
本文件中提到了单件模式、工厂模式、抽象工厂模式、访问者模式、状态模式、命令模式、解释器模式、备忘录模式、观察者模式、桥接模式、建造者模式、中介者模式、策略模式、适配器模式、装饰模式、享元模式、代理模式...
- **代理模式**:在`java.rmi.Remote`接口中,用于实现远程方法调用。 **3. Java中的单例模式有什么注意事项?** - 在多线程环境下,必须确保单例模式的线程安全性。 - 使用枚举(Enum)实现单例模式是一种简单且...
以 Jive 为例,剖析代理模式在用户级别授权机制上的应用 设计模式之 Facade(门面?) 可扩展的使用 JDBC针对不同的数据库编程,Facade提供了一种灵活的实现. 设计模式之 Composite(组合) 就是将类用树形结构组合成...
10. **装饰模式**:装饰者模式允许向一个现有的对象添加新的行为或责任,而不需要改变其本质结构。C语言中,通过结构体嵌套和函数指针可以实现。 11. **外观模式**:提供一个统一的接口,用来访问子系统中的各个...
- 代理模式为其他对象提供一种代理以控制对这个对象的访问。C++中可以通过虚基类实现,C#和Java可以利用接口或继承实现。 6. **适配器模式**: - 适配器模式使两个不兼容的接口能够协同工作。C++中常使用继承或...
- 装饰模式:动态地给一个对象添加一些额外的职责。 - **设计模式的原则**: - 开闭原则:对扩展开放,对修改关闭。 - 单一职责原则:一个类只负责一个功能领域中的相应职责。 - 接口隔离原则:客户端不应该...
本篇文章将深入解析这些面试题背后的本质,帮助你扎实掌握Java编程的基础与高级特性。 1. **基础概念** - **Java的内存管理**:理解Java中的堆和栈内存,以及对象生命周期。讲解如何通过垃圾回收机制(GC)处理...
25、JSP中动态INCLUDE与静态INCLUDE的区别? 动态INCLUDE用jsp:include动作实现 它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态INCLUDE用include伪码实现,定不会检查所含文件的变化...
结构型模式如适配器(Adapter)、装饰器(Decorator)和代理(Proxy)关注如何组合或扩展已有类;行为型模式如策略(Strategy)、观察者(Observer)和责任链(Chain of Responsibility)关注对象之间的交互和职责...
- 设计模式:单例、工厂、观察者、装饰者、代理等经典设计模式的理解和应用。 这些知识点都是Java OOP领域的核心组成部分,理解和掌握它们对于成为一名合格的Java开发者至关重要。在2019年的课程中,学生可能通过...
6. **代理模式**:为其他对象提供一种代理以控制对这个对象的访问。在Java中,可以使用动态代理实现。 7. **适配器模式**:将一个类的接口转换成客户希望的另一个接口。适配器使原本由于接口不兼容而不能一起工作的...