我正在查看代理模式,对我来说,它看起来非常像装饰器、适配器和桥接模式。我是不是误解了什么?有什么不同?为什么我要使用代理模式而不是其他模式?在过去的实际项目中,您是如何使用它们的?


当前回答

我想为Bill Karwing的回答补充一些例子(顺便说一句,这很好)。 我还补充了一些执行上的关键差异,我觉得这是我所缺失的

引用部分来自[https://stackoverflow.com/a/350471/1984346] (Bill Karwing)的回答

代理、装饰器、适配器和桥接器都是“包装”类的变体。 但它们的用途不同。 当您希望延迟实例化对象时,可以使用代理 隐藏您正在调用远程服务或控制访问的事实 对物体。

ProxyClass和被代理的ObjectClass应该实现相同的接口,因此它们是可交换的

示例- proxy昂贵对象

class ProxyHumanGenome implements GenomeInterface  {
    private $humanGenome = NULL; 

    // humanGenome class is not instantiated at construct time
    function __construct() {
    }

    function getGenomeCount() {
        if (NULL == $this->humanGenome) {
            $this->instantiateGenomeClass(); 
        }
        return $this->humanGenome->getGenomeCount();
    }
} 
class HumanGenome implement GenomeInterface { ... }

Decorator也称为“智能代理”。这是在你需要的时候使用的 向一个对象添加功能,但不是通过扩展该对象的功能 类型。这允许您在运行时这样做。

DecoratorClass应该(可以)实现ObjectClass的扩展接口。所以ObjectClass可以被DecoratorClass替换,反之则不行。

示例-添加附加功能

class DecoratorHumanGenome implements CheckGenomeInterface  {

    // ... same code as previous example

    // added functionality
    public function isComplete() {
        $this->humanGenome->getCount >= 21000
    }
}

interface CheckGenomeInterface extends GenomeInterface {

    public function isComplete();

}

class HumanGenome implement GenomeInterface { ... }

适配器用于当您有一个抽象接口,并且您想要 将该接口映射到具有类似功能的另一个对象 角色,但是不同的接口。

实现差异代理,装饰器,适配器

Adapter为其主题提供了不同的接口。Proxy提供相同的接口。Decorator提供了增强的接口。

Bridge is very similar to Adapter, but we call it Bridge when you define both the abstract interface and the underlying implementation. I.e. you're not adapting to some legacy or third-party code, you're the designer of all the code but you need to be able to swap out different implementations. Facade is a higher-level (read: simpler) interface to a subsystem of one or more classes. Suppose you have a complex concept that requires multiple objects to represent. Making changes to that set of objects is confusing, because you don't always know which object has the method you need to call. That's the time to write a Facade that provides high-level methods for all the complex operations you can do to the collection of objects. Example: a Domain Model for a school section, with methods like countStudents(), reportAttendance(), assignSubstituteTeacher(), and so on.

这个答案中的大部分信息来自https://sourcemaking.com/design_patterns,我推荐它作为设计模式的优秀资源。

其他回答

正如Bill的回答所说,它们的用例是不同的。

它们的结构也是如此。

Proxy and Decorator both have the same interface as their wrapped types, but the proxy creates an instance under the hood, whereas the decorator takes an instance in the constructor. Adapter and Facade both have a different interface than what they wrap. But the adapter derives from an existing interface, whereas the facade creates a new interface. Bridge and Adapter both point at an existing type. But the bridge will point at an abstract type, and the adapter might point to a concrete type. The bridge will allow you to pair the implementation at runtime, whereas the adapter usually won't.

Design pattern is not mathematics, it is combination of art and software engineering. There is nothing like for this requirment you have to use proxy, bridge etc. Design patterns are created to solve the problems. If you anticipate a design problem, then use it. Based on experience, you will come to know for specific problem, which pattern to use. If you are good in solid design principles, you would have implemented design pattern without knowing it is pattern. Common example is statergy and factory patterns

因此,更多地集中在坚实的设计原则,干净的编码原则和ttd

在许多GoF模式中有大量的重叠。它们都建立在多态性的力量之上,有时只是意图不同。(战略vs.国家)

在阅读了头部优先设计模式之后,我对模式的理解增加了100倍。

我强烈推荐!

代理、装饰器、适配器和桥接器都是“包装”类的变体。但它们的用途不同。

Proxy could be used when you want to lazy-instantiate an object, or hide the fact that you're calling a remote service, or control access to the object. Decorator is also called "Smart Proxy." This is used when you want to add functionality to an object, but not by extending that object's type. This allows you to do so at runtime. Adapter is used when you have an abstract interface, and you want to map that interface to another object which has similar functional role, but a different interface. Bridge is very similar to Adapter, but we call it Bridge when you define both the abstract interface and the underlying implementation. I.e. you're not adapting to some legacy or third-party code, you're the designer of all the code but you need to be able to swap out different implementations. Facade is a higher-level (read: simpler) interface to a subsystem of one or more classes. Suppose you have a complex concept that requires multiple objects to represent. Making changes to that set of objects is confusing, because you don't always know which object has the method you need to call. That's the time to write a Facade that provides high-level methods for all the complex operations you can do to the collection of objects. Example: a Domain Model for a school section, with methods like countStudents(), reportAttendance(), assignSubstituteTeacher(), and so on.

它们非常相似,而且它们之间的线条是灰色的。我建议您阅读c2 wiki中的代理模式和装饰器模式条目。

那里的条目和讨论相当广泛,也链接到其他相关文章。顺便说一下,c2 wiki在了解不同模式之间的细微差别时非常有用。

总结c2项,我认为装饰器添加/更改行为,但代理与访问控制(延迟实例化,远程访问,安全等)有更多关系。但正如我所说,它们之间的界线是灰色的,我看到对代理的引用很容易被视为装饰器,反之亦然。