Design patterns 代理、装饰器、适配器和网桥模式有何区别?
我在看代理模式,在我看来,它非常像装饰器、适配器和桥接器模式。我是不是误解了什么?有什么区别?为什么我要使用代理模式而不是其他模式?您过去在实际项目中是如何使用它们的?我在使用web服务时经常使用它。代理模式可能应该改名为更实用的模式,如“包装模式”。我还有一个库,它是MS Excel的代理。它使Excel自动化变得非常容易,而不必担心后台细节,例如安装了什么版本(如果有的话).它们非常相似,它们之间的线条非常灰色。我建议您阅读c2 wiki中的和条目 这里的条目和讨论非常广泛,它们还链接到其他相关文章。顺便说一句,c2 wiki非常适合了解不同模式之间的细微差别Design patterns 代理、装饰器、适配器和网桥模式有何区别?,design-patterns,decorator,bridge,proxy-pattern,Design Patterns,Decorator,Bridge,Proxy Pattern,我在看代理模式,在我看来,它非常像装饰器、适配器和桥接器模式。我是不是误解了什么?有什么区别?为什么我要使用代理模式而不是其他模式?您过去在实际项目中是如何使用它们的?我在使用web服务时经常使用它。代理模式可能应该改名为更实用的模式,如“包装模式”。我还有一个库,它是MS Excel的代理。它使Excel自动化变得非常容易,而不必担心后台细节,例如安装了什么版本(如果有的话).它们非常相似,它们之间的线条非常灰色。我建议您阅读c2 wiki中的和条目 这里的条目和讨论非常广泛,它们还链接到其他
总结c2条目,我想说装饰器添加/更改行为,但代理与访问控制(延迟实例化、远程访问、安全性等)有更多关系但正如我所说,它们之间的线条是灰色的,我看到对代理的引用很容易被视为装饰器,反之亦然。代理、装饰器、适配器和桥接器都是“包装”类的变体。但它们的用途不同
- 代理可用于延迟实例化对象,或隐藏调用远程服务的事实,或控制对对象的访问
- Decorator也称为“智能代理”。当您希望向对象添加功能时,可使用此选项,但不能扩展该对象的类型。这允许您在运行时执行此操作
- 适配器用于具有抽象接口,并且希望将该接口映射到另一个具有类似功能角色但不同接口的对象
- 桥接器与适配器非常相似,但当您定义抽象接口和底层实现时,我们称之为桥接器。也就是说,您不适应某些遗留或第三方代码,您是所有代码的设计者,但您需要能够交换不同的实现
- Facade是一个更高级别(阅读:更简单)接口到一个或多个类的子系统。假设您有一个复杂的概念,需要多个对象来表示。对该对象集进行更改是令人困惑的,因为您并不总是知道哪个对象具有需要调用的方法。这是编写Facade的时候,该Facade为所有复杂的操作提供高级方法您可以对对象集合执行的操作。例如:学校分区的域模型,其方法包括
,countStudents()
,reportAttention()
,等等assignsubstituteTech()
- Proxy和Decorator都具有与其包装类型相同的接口,但是代理在引擎盖下创建一个实例,而Decorator在构造函数中获取一个实例
- 适配器和Facade都有一个不同于它们包装的接口。但是适配器派生自现有接口,而Facade创建了一个新接口
- 桥和适配器都指向现有类型。但是桥将指向抽象类型,适配器可能指向具体类型。桥允许您在运行时配对实现,而适配器通常不会
另一件事,代理的作用与目标完全相同,而其他模式为目标添加了更多功能。所有四种模式都涉及将内部对象/类与外部对象/类包装在一起,因此它们在结构上非常相似。我将根据目的概述不同之处:
- 代理将访问从外部封装到内部
- 装饰者用外部修改或扩展内部的行为
- 适配器将接口从内部转换为外部
- 桥接将行为的不变部分(外部)与变量或平台相关部分(内部)分开
- 在代理中,接口是相同的
- 在装饰器中接口是相同的
- 在适配器中接口形式不同,但用途相同
- 在桥中接口在概念上是不同的
- 我对这个问题的看法
这四种模式都有很多共同之处
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 { ... }
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 { ... }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
/* Proxy */
Console.WriteLine(Environment.NewLine);
Console.WriteLine("PROXY");
Console.WriteLine(Environment.NewLine);
//instead of creating here create using a factory method, the facory method will return the proxy
IReal realProxy = new RealProxy();
Console.WriteLine("calling do work with the proxy object ");
realProxy.DoWork();
Console.WriteLine(Environment.NewLine);
Console.WriteLine("ADAPTER");
Console.WriteLine(Environment.NewLine);
/*Adapter*/
IInHand objectIHave = new InHand();
Api myApi = new Api();
//myApi.SomeApi(objectIHave); /*I cant do this, use a adapter then */
IActual myAdaptedObject = new ActualAdapterForInHand(objectIHave);
Console.WriteLine("calling api with my adapted obj");
myApi.SomeApi(myAdaptedObject);
Console.WriteLine(Environment.NewLine);
Console.WriteLine("DECORATOR");
Console.WriteLine(Environment.NewLine);
/*Decorator*/
IReady maleReady = new Male();
Console.WriteLine("now male is going to get ready himself");
maleReady.GetReady();
Console.WriteLine(Environment.NewLine);
IReady femaleReady = new Female();
Console.WriteLine("now female is going to get ready her self");
femaleReady.GetReady();
Console.WriteLine(Environment.NewLine);
IReady maleReadyByBeautician = new Beautician(maleReady);
Console.WriteLine("now male is going to get ready by beautician");
maleReadyByBeautician.GetReady();
Console.WriteLine(Environment.NewLine);
IReady femaleReadyByBeautician = new Beautician(femaleReady);
Console.WriteLine("now female is going to get ready by beautician");
femaleReadyByBeautician.GetReady();
Console.WriteLine(Environment.NewLine);
Console.ReadLine();
}
}
/*Proxy*/
public interface IReal
{
void DoWork();
}
public class Real : IReal
{
public void DoWork()
{
Console.WriteLine("real is doing work ");
}
}
public class RealProxy : IReal
{
IReal real = new Real();
public void DoWork()
{
real.DoWork();
}
}
/*Adapter*/
public interface IActual
{
void DoWork();
}
public class Api
{
public void SomeApi(IActual actual)
{
actual.DoWork();
}
}
public interface IInHand
{
void DoWorkDifferently();
}
public class InHand : IInHand
{
public void DoWorkDifferently()
{
Console.WriteLine("doing work slightly different ");
}
}
public class ActualAdapterForInHand : IActual
{
IInHand hand = null;
public ActualAdapterForInHand()
{
hand = new InHand();
}
public ActualAdapterForInHand(IInHand hnd)
{
hand = hnd;
}
public void DoWork()
{
hand.DoWorkDifferently();
}
}
/*Decorator*/
public interface IReady
{
void GetReady();
}
public class Male : IReady
{
public void GetReady()
{
Console.WriteLine("Taking bath.. ");
Console.WriteLine("Dress up....");
}
}
public class Female : IReady
{
public void GetReady()
{
Console.WriteLine("Taking bath.. ");
Console.WriteLine("Dress up....");
Console.WriteLine("Make up....");
}
}
//this is a decorator
public class Beautician : IReady
{
IReady ready = null;
public Beautician(IReady rdy)
{
ready = rdy;
}
public void GetReady()
{
ready.GetReady();
Console.WriteLine("Style hair ");
if (ready is Female)
{
for (int i = 1; i <= 10; i++)
{
Console.WriteLine("doing ready process " + i);
}
}
}
}
}
FileOutputStream fos1 = new FileOutputStream("data1.txt");
ObjectOutputStream out1 = new ObjectOutputStream(fos1);