了解C#中的装饰器设计模式 [英] Understanding Decorator Design Pattern in C#

查看:74
本文介绍了了解C#中的装饰器设计模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我才刚刚开始学习装饰器设计模式,不幸的是,我不得不经过各种学习才能更好地理解装饰器模式,这使我感到非常困惑。因此,据我所知,我相信这是一个装饰器模式

I just started to learn Decorator Design Pattern, unfortunately i had to go through various refrences to understand the Decorator pattern in a better manner which led me in great confusion. so, as far as my understanding is concern, i believe this is a decorator pattern

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吗? / p>

But can the below code also be 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();
    }
}

我的理解

从我给出的第二个示例中,我们可以调用所有三个方法,但是从第一个示例中,我将无法通过创建单个方法来访问所有这三个方法

From the second example given by me, we can call all the three methods, but from the first example i wont be able to get access to all the three methods by creating a single object.

推荐答案

应该是一个注释,但是我的单词太多了。

It should be a comment, but I have too many words.

例如,您有一个对象和接口,例如 Repository:IRepository

For example, you have an object and interface, like Repository : IRepository.

public interface IRepository
{
    void SaveStuff();
}

public class Repository : IRepository
{
    public void SaveStuff()
    {
        // save stuff   
    }
}

和客户(可能是别人写的)

and client, which probably was written by someone else

class RepoClient
{
    public void DoSomething(IRepository repo)
    {
        //...
        repo.SaveStuff();
    }
}

一旦您决定,所有对存储库的调用都应被记录。但是您有一个问题:存储库类来自外部库,您不想更改该代码。因此,您需要扩展存储库的行为。您编写 RepositoryLogDecorator:IRepository ,然后在每个方法的内部进行日志记录,例如

And once you decided, that ALL calls to repository should be logged. But you have a problem: the Repository class is from an external library and you don't want to change that code. So you need to extend the Repository's behavior that you use. You write RepositoryLogDecorator : IRepository, and inside on each method do the logging, like

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.DoSomething(new Repository());

但现在您可以使用

var client = new RepoClient();
client.DoSomething(new RepositoryLogDecorator(new Repository()));

请注意,这是一个非常简单的示例。在实际的项目中,使用DI容器创建的对象主要是对象,您可以通过更改一些配置来使用decorator。

Note, that this is a very simple example. In real projects, where object created primary with DI container, you will be able to use decorator by changing some config.

因此,装饰器用于扩展对象的功能,而无需更改对象或客户端。

So, decorator is used to extend functionality of object without changing object or client.

装饰器的另一个好处:您的装饰器不依赖存储库的实现。仅取决于接口 IRepository 。为什么这是优势?如果您决定以某种方式编写自己的 IRepository

Another benefit of decorator: your decorator does not depend on Repository implementation. Only depends from an interface IRepository. Why this is an advantage? If somehow you decide to write you own implementation of IRepository

public class MyAwesomeRepository : IRepository
{
    public void SaveStuff()
    {
        // save stuff, but AWESOME!
    }
}

您将能够使用装饰器自动对其进行装饰,

you will be able to automatically decorate this with decorator, which already exist

var client = new RepoClient();
client.DoSomethig(new RepositoryLogDecorator(new MyAwesomeRepository()));

想从真实软件中查看示例吗? (就像样本一样,我知道代码很丑陋)=> 转到此处

Want to see example from real software? (just as sample, code is ugly, I know) => go here

这篇关于了解C#中的装饰器设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆