`

Java 静态代理模式与装饰者模式的本质区别

 
阅读更多

 

       我们在学习 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与模式

    设计模式分为三类:创建型模式(如单例模式、工厂模式、抽象工厂模式)、结构型模式(如代理模式、适配器模式、装饰器模式)和行为型模式(如观察者模式、策略模式、职责链模式)。这些模式在Java开发中有着广泛的...

    使用C语言实现23种设计模式。.zip

    10. **装饰模式**:装饰者模式允许向一个现有的对象添加新的行为或责任,而不需要改变其本质结构。C语言中,通过结构体嵌套和函数指针可以实现。 11. **外观模式**:提供一个统一的接口,用来访问子系统中的各个...

    java 面试题 总结

    22、JSP中动态INCLUDE与静态INCLUDE的区别? 动态INCLUDE用jsp:include动作实现 它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态INCLUDE用include伪码实现,定不会检查所含文件的变化,...

    二十三种设计模式【PDF版】

    以 Jive 为例,剖析代理模式在用户级别授权机制上的应用 设计模式之 Facade(门面?) 可扩展的使用 JDBC针对不同的数据库编程,Facade提供了一种灵活的实现. 设计模式之 Composite(组合) 就是将类用树形结构组合成...

    HeadFirstDesignPattern 图书配套源码

    - 代理模式为其他对象提供一种代理以控制对这个对象的访问。C++中可以通过虚基类实现,C#和Java可以利用接口或继承实现。 6. **适配器模式**: - 适配器模式使两个不兼容的接口能够协同工作。C++中常使用继承或...

    java面试经典

    本篇文章将深入解析这些面试题背后的本质,帮助你扎实掌握Java编程的基础与高级特性。 1. **基础概念** - **Java的内存管理**:理解Java中的堆和栈内存,以及对象生命周期。讲解如何通过垃圾回收机制(GC)处理...

    超级有影响力霸气的Java面试题大全文档

    25、JSP中动态INCLUDE与静态INCLUDE的区别?  动态INCLUDE用jsp:include动作实现 它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态INCLUDE用include伪码实现,定不会检查所含文件的变化...

    Practise.PatternsExample

    结构型模式如适配器(Adapter)、装饰器(Decorator)和代理(Proxy)关注如何组合或扩展已有类;行为型模式如策略(Strategy)、观察者(Observer)和责任链(Chain of Responsibility)关注对象之间的交互和职责...

    Java-OOP:2019年

    - 设计模式:单例、工厂、观察者、装饰者、代理等经典设计模式的理解和应用。 这些知识点都是Java OOP领域的核心组成部分,理解和掌握它们对于成为一名合格的Java开发者至关重要。在2019年的课程中,学生可能通过...

    DesignModel

    6. **代理模式**:为其他对象提供一种代理以控制对这个对象的访问。在Java中,可以使用动态代理实现。 7. **适配器模式**:将一个类的接口转换成客户希望的另一个接口。适配器使原本由于接口不兼容而不能一起工作的...

Global site tag (gtag.js) - Google Analytics