Pattern to extend classes without modifying them (or knowing implementation details) (c#)

久未见 提交于 2020-01-02 10:28:30

问题


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();
}

}

a sample call would look like this:

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?

Thanks!


回答1:


The decorator pattern is the way to go.

  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

  3. 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. In those situations which demands a custom way of disposing the object, create the decorator object and do the custom dispose!

Hope this helps.




回答2:


Try use Decorator pattern. This link can help.



来源:https://stackoverflow.com/questions/12274960/pattern-to-extend-classes-without-modifying-them-or-knowing-implementation-deta

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!