我有一些插件的抽象类:
public abstract class BasePlugin
{
public void SomeMethod(){..defaultBehaviour}.
}
这个基类将继承自几个(可能是数百个)实现。
我确实知道,以后我会以一种小的方式改变"" (但仍在改变)SomeMethod
的行为。
我希望BasePlugin
的现有实现继续使用相同的新实现以及使用新功能的新实现。
是否有一些模式允许我这样做?
注意:我在所有实现方面都处于领先地位,但如果新行为没有问题我无法检查数百个实现
答案 0 :(得分:1)
许多模式都适合,但我认为template method pattern是合理的选择,假设您希望保持默认行为的主要部分不变:
public abstract class BasePlugin
{
public void SomeMethod(){
// default code before/after one or many variations
// to be provided by derived classes
...
Variation(....);
...
}
public virtual Variation(....) {} // nothing by default
}
答案 1 :(得分:1)
你不想这样做。如果您正在编写插件系统,则还有其他选择。这就是向插件公开一些合同。每个合约代表一个应用程序中的一种功能,插件可以扩展。
在您的插件基类中,您将定义一个注册方法:
public abstract class PluginBase
{
public abstract void Register(IFeatureRepository repos);
}
..插件用于注册其扩展名的内容:
public class TextProcessingFilter : PluginBase, ITextProcessor
{
public void Register(IFeatureRepository repos)
{
repos.Get<ITextEditor>().Subscribe(this);
}
void ITextProcessor.Process(TextEditorContext ctx)
{
}
}
新功能的好处不会破坏向后兼容性,如果您要拥有大量插件,这非常重要。只需在新版本的基本插件dll中引入新接口。
答案 2 :(得分:0)
Program to an interface, not an implementation.
对所有抽象骨架实现类使用公共接口(Plugin
)时,可以添加新的抽象类(BasePluginNew
)以实现新的(默认)行为。
新实现继承自这个新的抽象类BasePluginNew
旧的实现继续表现相同。
客户端引用公共Plugin
接口,并且与其实现方式无关。
有关进一步讨论,请参阅http://w3sdesign.com处的GoF设计模式存储器(设计原则/接口设计)。
答案 3 :(得分:0)
我会选择策略模式(由于"Prefer composition over inheritance"等原因 - 特别是对于可能已经从另一个类继承的客户端):
public interface IPluginStrategy
{
void SomeMethod();
}
public class OldPluginStrategy : IPluginStrategy
{
public void SomeMethod()
{
// old plugin code
}
}
public class NewPluginStrategy : IPluginStrategy
{
public void SomeMethod()
{
// new plugin code which might be using OldPuginStrategy
// through inheritance or composition
}
}
和客户:
public class Client
{
public Client(IPluginStrategy pluginStrategy)
{
...
}
// use pluginStrategy's SomeMethod
}
这是在行动:
var oldClient = new Client(new OldPluginStrategy());
...
var newClient = new Client(new NewPluginStrategy());
您可以控制哪些客户端使用哪种策略,以便旧客户端可以继续使用旧的插件代码,而其他(新的?)客户端将获得新的插件。 您确实需要访问客户端&#39;代码或至少一种确保他们选择您希望他们使用的插件的方法。
请注意 - 如果您的不同插件基本上做同样的事情,并且您只想保留不同版本以避免破坏现有客户端的风险,请考虑以下事项:
这是您的插件设计不佳的症状 - 您的客户不应该知道您的插件内部。
从长远来看,这很可能非常难以维护 - 您对该插件进行了30次更改后会发生什么?你会在30个不同的客户端中运行30个不同版本的插件吗?