用于扩展类而不修改它们(或不了解实现细节)的模式(C#) [英] Pattern to extend classes without modifying them (or knowing implementation details) (c#)

查看:82
本文介绍了用于扩展类而不修改它们(或不了解实现细节)的模式(C#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在修改位于两个已建立层之间的代码,并且在弄清楚什么是最佳设计时遇到了麻烦。

I am modifying some code that sits between two established layers, and am having trouble figuring out what the best design is.

当前该代码调用文件访问库,然后将一个对象返回给调用者。我需要扩展返回的对象以添加一些自定义处理功能。我无权访问传递的对象的定义(例如某些文件流)

Currently the code calls a file access library, and returns an object to the caller. I need to extend the returned object to add some custom dispose functionality. I don't have access to the definitions of the passed objects (some are filestreams, for example)

如果我可以创建一个孩子,它将为我节省很多工作实例的行为类似于基本实例,可以从基本实例创建,但是具有一些隐藏的额外功能。

It would save me a lot of work if I could create a child instance that behaves like a base instance, and can be created from a base instance, but that has some hidden extra functionality. Can this be done without knowing the implementation details of the base class?

采用类似于以下代码形式的代码形式:

In code form that looks a lot like this:

private class FileObjectWithDispose : FileObject, IDisposable
{//voidaction is a delegate, this is .net 2.0
    private VoidAction _disposeCallback;

public static FileObjectWithDispose wrapFile(FileObject unWrappedFile, VoidAction DisposeAction)
{//Implementation missing, this is the crux of what I don't know how to do
    FileObjectWithDispose wrappedFile = new FileObjectWithDispose(unWrappedFile);
    wrappedFile._disposeCallback = DisposeAction;
    return wrappedFile;
}

private FileObjectWithDispose()
    : base(null, null)//base class does not have a default constructor
{
    throw new NotImplementedException("FileObjectWithDispose is a wrapper class which is intended only to be cast from a filestream.");
}

private void Dispose()
{
    _disposeCallback();
    base.Dispose();
}

}

调用示例如下:

Connect(file, username, password, domain);
return FileObjectWithDispose.wrapFile(OpenFile(path), () => { Disconnect(file, username); });

我遇到的主要困难是,如果可能的话,如何获取基类实例如果基类未实现允许自己进行修饰的接口,并创建修饰的实例?
任何想法如何完成此任务?

The key difficulty I'm having is, if it's possible, how do I take a base class instance and create a decorated instance if the base class does not implement an interface that allows itself to be decorated? Any ideas how to accomplish this task?

谢谢!

推荐答案

装饰器模式是必经之路。

The decorator pattern is the way to go.


  1. 创建接口 ICustomDisposeAction (示例名称)

  2. 使用所有可能要在其上执行 DisposeAction 的可能的类来实现此接口

  1. Create an interface ICustomDisposeAction (an example name)
  2. Implement this interface with all those possible classes which on you would want to perform DisposeAction on.

FileObjectWithDispose:FileObject,IDisposable,ICustomDisposeAction

FileObjectWithDispose : FileObject, IDisposable, ICustomDisposeAction

创建另一个也可以实现 ICustomDisposeAction 。通过装饰器的构造函数传递原始基类,然后在其上调用装饰器的 DisposeAction

Create another class Decorator which also implements ICustomDisposeAction. Pass the original base class through the constructor of the decorator and then call the decorator's DisposeAction on it.




public class Decorator : ICustomDisposeAction
{
  public FileObject wrappedFile { get; set; } 
  public Decorator(FileObject unWrappedFile,...)
  {
    wrappedFile = unWrappedFile;
    //Do your custom dispose here
  }
} 





  1. 在那些需要自定义方式处置对象的情况下,创建装饰器对象并执行自定义处置!

希望这会有所帮助。

这篇关于用于扩展类而不修改它们(或不了解实现细节)的模式(C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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