问题
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.
- Create an interface
ICustomDisposeAction(an example name) Implement this interface with all those possible classes which on you would want to perform
DisposeActionon.FileObjectWithDispose : FileObject, IDisposable, ICustomDisposeAction
Create another class Decorator which also implements
ICustomDisposeAction. Pass the original base class through the constructor of the decorator and then call the decorator'sDisposeActionon it.
public class Decorator : ICustomDisposeAction { public FileObject wrappedFile { get; set; } public Decorator(FileObject unWrappedFile,...) { wrappedFile = unWrappedFile; //Do your custom dispose here } }
- 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