A Brief Analysis of the Proxy Pattern in Design Patterns
Proxy Pattern Establish a proxy object (proxy) between the client and the entity. All operations the client performs on the entity are delegated to the proxy object, hiding the entity's specific implementation details. Proxy can also be separated from the business code and deployed to another server. Tasks are delegated via RPC in the business code. Similarities and Differences Between the Proxy Pattern and Parent Classes and Interfaces Similarities: The role of the proxy pattern is similar to that of parent classes as well as interfaces and composition; all of them are meant to aggregate shared parts and reduce code for common parts Differences: Compared to parent classes, their contexts are different; what a parent class expresses is is
目录4 个章节
Proxy Pattern
-
Establish a proxy object (proxy) between the client and the entity. All operations the client performs on the entity are delegated to the proxy object, hiding the entity's specific implementation details.
-
Proxy can also be separated from the business code and deployed to another server. Tasks are delegated via RPC in the business code.
Similarities and Differences Between the Proxy Pattern and Parent Classes and Interfaces
- Similarities: The role of the proxy pattern is similar to that of parent classes as well as interfaces and composition; all of them are meant to aggregate shared parts and reduce code for common parts
- Differences:
- Compared to parent classes, their contexts are different; what a parent class expresses is is-a, while what a proxy expresses is closer to an interface, which is has-a, and using a proxy also fits the saying "use less inheritance, use more composition"; what it really means is reducing coupling
- Compared to interfaces, the functions they implement are somewhat different; the context is has-a in both cases, but an interface is has-a-function, while a proxy object is has-a-object, and this object is a has-a-function object; moreover, an interface is meant to indicate what capabilities this class has, without a concrete implementation, achieving polymorphism, whereas a proxy object not only possesses this capability, but also possesses the concrete implementation of this capability
- As for composition, it is more flexible than composition; for example, if we set the proxy object as private, then I can choose to provide only part of the proxy functionality, such as one or two methods of Printer, or add some other operations when providing Printer's functionality; all of these are possible
Implementation Code
class Printer { //代理对象,一台打印机
public function printSth() {
echo 'I can print <br>';
}
// some more function below
// ...
}
class TextShop { //这是一个文印处理店,只文印,卖纸,不照相
private $printer;
public function __construct(Printer $printer) {
$this->printer = $printer;
}
public function sellPaper() { //卖纸
echo 'give you some paper <br>';
}
public function __call($method, $args) { //将代理对象有的功能交给代理对象处理
if(method_exists($this->printer, $method)) {
$this->printer->$method($args);
}
}
}
class PhotoShop { //这是一个照相店,只文印,拍照,不卖纸
private $printer;
public function __construct(Printer $printer) {
$this->printer = $printer;
}
public function takePhotos() { //照相
echo 'take photos for you <br>';
}
public function __call($method, $args) { //将代理对象有的功能交给代理对象处理
if(method_exists($this->printer, $method)) {
$this->printer->$method($args);
}
}
}
$printer = new Printer();
$textShop = new TextShop($printer);
$photoShop = new PhotoShop($printer);
$textShop->printSth();
$photoShop->printSth();
Both the print shop and the photo shop have printing functionality, so we can proxy the printing functionality to a printer. Here the printer has only one function; if the printer also had n functions, using the __call() method we could save a lot of duplicated code
If we used inheritance, the context would be unreasonable; a shop clearly should not inherit from a printer
And if we used an interface, because our function implementations are all the same, there is also no need to re-implement the interface's functions
So using a proxy here is the best choice
Java's Proxy Pattern
The implementation of the proxy pattern in Java is actually similar, except that Java does not have a __call() method, so you need to manually declare the printSth() method, then call $printer's printSth() method in the method body
Alternatively you can use the InvocationHandler proxy interface to implement the proxy,
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throw Throwable;
}
//日志代理实现
public class LogHandler implement InvocationHandler{
private Object target;
public LogHandler(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args ) throw Throwable{
//记录函数的初始状况参数等信息
log4j.info(“开始:方法”+ method.getName() + “参数”+Arrays.toString(args) );
Object result = method.invoke(target, args);
//记录函数的执行状况与返回值
log4j.info(“结束:方法”+ method.getName() + “返回值”+ result );
}
}
//主函数
public class Main{
public static void main(String[ ] args){
//例子中生成报告的功能,生成报告需要记录日志。
ReportGenerator reportGeneratorImpl = new SMSReportGenerator ();
//通过系统提供的Proxy.newProxyInstance创建动态代理实例
ReportGenerator reportGenerator = (ReportGenerator ) Proxy.newProxyInstance(
reportGeneratorImpl.getClass().getClassLoader(),
reportGeneratorImpl.getClass().getInterfaces(),
new LogHandler(reportGeneratorImpl)
) ;
...
}
}
However, the structure of dynamic proxies implemented with the Java Reflection API is very complex and not easy to understand.
Friends who have used the Spring framework should be somewhat familiar with Spring's AOP (slice-oriented programming). Spring's use of annotations to implement the proxy pattern is much more intuitive than the Java Reflection API approach. This article will not go into further detail.
_EOF_
A Brief Analysis of the Proxy Pattern in Design Patterns
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
操作系统学习二:进程同步与互斥之生产者-消费者问题--NetCore实现
目的 1. 掌握进程(线程)的同步与互斥。 2. 掌握生产者消费者问题的实现方法。 3. 掌握VC的多线程编程方法。 内容 本实验要求设计并实现一个进程,该进程拥有3个生产者线程和1个消费者线程,它们使用10个不同的缓冲区。需要使用如下信号量: 一个mutex信号量,用以阻止生产者线程和消费者线程同时操作缓冲区队列; 一个full信号量,当生产者线程生产出一个物品时可以用它向消费者线程发出信号;
2022-06-17 · 计科基础 · 约 1 分钟
操作系统学习三:进程调度与死锁-以及银行家算法避免死锁--NetCore实现
前言 这是操作系统学习的第三篇啦,关于进程调度有很多内容,操作系统在调度进程的时候最容易遇到的问题就是死锁了,银行家算法是一个典型的避免死锁算法。 死锁的概念 先来了解一下死锁的基本概念:一组竞争系统资源或相互通信的进程相互的“永久”阻塞。若无外力作用,这组进程将永远不能继续执行。 看下面两幅图片,左边是可能产生死锁的状态,四辆汽车(进程)要竞争同一个资源(通过路口),如果系统调度不当,就会陷入死
2021-12-18 · 计科基础 · 约 1 分钟
奇怪的操作系统相关习题~4-21
操作系统作业 操作系统在计算机系统分层中处于哪个层次?它与上下层是怎样衔接的? 计算机系统的分层: 第1级是微程序机器层,这是一个实在的硬件层,它由机器硬件直接执行微指令。 第2级是传统机器语言,它也是一个实际的机器层,它由微程序解释机器指令系统。 第3级是操作系统层,它由操作系统程序实现。操作系统程序由机器指令和广义指令组成,这些广义指令是为了扩展机器功能而设置的,它是由操作系统定义和解释的软件
2022-06-17 · 计科基础 · 约 1 分钟
操作系统学习一:NetCore-实现模拟多道程序设计的简单处理机调用
前言 道程序设计中,经常是若干个进程同时处于就绪状态,为了使系统中的各进程有条不紊地运行,必须选择某种调度策略,以选择一个进程占用处理机。本次实验设计一个模拟单处理机调度的算法,以加深对处理机调度算法的理解。 要求 按照时间片轮转算法设计模拟调度程序。 输出进程的调度过程。 思路分析 由于本实验是按照处理机调度算法模拟实现处理机的调度,与真正的处理机调度过程并不完全相同,比如没有实现中断(时间片设
2022-06-17 · 计科基础 · 约 1 分钟
讨论
共 0 条加载评论中…