内容简介:翻译自:https://stackoverflow.com/questions/40294622/understanding-decorator-design-pattern-in-c-sharp
我刚开始学习装饰设计模式,不幸的是我不得不通过各种参考来更好地理解装饰器模式,这让我非常困惑.所以,就我的理解而言,我相信这是一个装饰模式
interface IComponent
{
void Operation();
}
class Component : IComponent
{
public void Operation()
{
Console.WriteLine("I am walking ");
}
}
class DecoratorA : IComponent
{
IComponent component;
public DecoratorA(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("in the rain");
}
}
class DecoratorB : IComponent
{
IComponent component;
public DecoratorB(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("with an umbrella");
}
}
class Client
{
static void Main()
{
IComponent component = new Component();
component.Operation();
DecoratorA decoratorA = new DecoratorA(new Component());
component.Operation();
DecoratorB decoratorB = new DecoratorB(new Component());
component.Operation();
Console.Read();
}
}
但是下面的代码也可以是Decorator Pattern吗?
class Photo
{
public void Draw()
{
Console.WriteLine("draw a photo");
}
}
class BorderedPhoto : Photo
{
public void drawBorder()
{
Console.WriteLine("draw a border photo");
}
}
class FramePhoto : BorderedPhoto
{
public void frame()
{
Console.WriteLine("frame the photo");
}
}
class Client
{
static void Main()
{
Photo p = new Photo();
p.Draw();
BorderedPhoto b = new BorderedPhoto();
b.Draw();
b.drawBorder();
FramePhoto f = new FramePhoto();
f.Draw();
f.drawBorder();
f.frame();
}
}
我的理解
从我给出的第二个例子中,我们可以调用所有这三个方法,但从第一个例子开始,我无法通过创建单个对象来访问所有这三个方法.
它应该是一个评论,但我有太多的话.
例如,您有一个对象和接口,如Repository:IRepository.
public interface IRepository
{
void SaveStuff();
}
public class Repository : IRepository
{
public void SaveStuff()
{
// save stuff
}
}
和客户,这可能不是你写的
class RepoClient
{
public void DoSomethig(IRepository repo)
{
//...
repo.SaveStuff();
}
}
一旦你决定,就应该记录对存储库的所有调用.但是你有一个问题 – Repository – 来自外部库的类,你不想改变那些代码.因此,您需要扩展您使用的Repository的行为.你编写RepositoryLogDecorator:IRepository,并在每个方法里面做日志记录,比如
public class RepositoryLogDecorator : IRepository
{
public IRepository _inner;
public RepositoryLogDecorator(IRepository inner)
{
_inner = inner;
}
public void SaveStuff()
{
// log enter to method
try
{
_inner.SaveStuff();
}
catch(Exception ex)
{
// log exception
}
// log exit to method
}
}
所以,在你可以使用客户端之前
var client = new RepoClient(); client.DoSomethig(new Repository());
但现在你可以使用
var client = new RepoClient(); client.DoSomethig(new RepositoryLogDecorator(new Repository()));
注意,这是一个非常简单的例子.在实际项目中,对象使用DI容器创建主要对象,您可以通过更改某些配置来使用装饰器.
那么,使用什么装饰器:在不改变对象或客户端的情况下扩展对象的功能.
装饰器的另一个好处是:装饰器不依赖于Repository实现.仅取决于接口IRepository.为什么这是优势?如果你决定写自己的实现
public class MyAwesomeRepository : IRepository
{
public void SaveStuff()
{
// save stuff, but AWESOME!
}
}
你可以自动使用已经存在的装饰器来装饰它
var client = new RepoClient(); client.DoSomethig(new RepositoryLogDecorator(new MyAwesomeRepository()));
想从真实软件中看到例子吗? (就像样本,代码很难看,我知道)=> go here
凉!爱它! :d
翻译自:https://stackoverflow.com/questions/40294622/understanding-decorator-design-pattern-in-c-sharp
以上所述就是小编给大家介绍的《了解C#中的装饰器设计模式》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 大神之路你必须了解的——Java 设计模式
- 写了这么多年代码,你真的了解设计模式么?
- 设计模式-享元设计模式
- 设计模式(四)Singleton设计模式
- 设计模式之建造者设计模式
- 设计模式之单例设计模式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Agile Web Application Development with Yii 1.1 and PHP5
Jeffrey Winesett / Packt Publishing / 2010-08-27
In order to understand the framework in the context of a real-world application, we need to build something that will more closely resemble the types of applications web developers actually have to bu......一起来看看 《Agile Web Application Development with Yii 1.1 and PHP5》 这本书的介绍吧!