C# 有效地使用Decorator模式
我正在设计一个库,提供对我们公司使用的Bug跟踪器应用程序的访问 目前,我们只需要访问简单的功能:C# 有效地使用Decorator模式,c#,design-patterns,architecture,decorator,C#,Design Patterns,Architecture,Decorator,我正在设计一个库,提供对我们公司使用的Bug跟踪器应用程序的访问 目前,我们只需要访问简单的功能: 开放性缺陷 查询缺陷(按给定条件搜索) 连接/断开与Bug跟踪器的连接 我设计该库是为了提供这些操作的接口,以便在新版本出现时可以透明地替换实现 为了支持未来更多的运营,我们可以: 扩展接口;使所有实现类实现添加的成员 使用Decorator模式在运行时添加操作/功能 问题是——Decorator似乎与底层基类/接口联系太紧密。 我的意思是,它依赖于这样一个事实,即它所修饰的对象提供了足够的访问权
- 故意未修饰的类型,仅具有基本行为
- 允许您提供重写行为的任意修饰类型
namespace Version1
{
public interface IOpenDefectService
{
void Submit(string title, string description, int severity);
void Bump(int issueId);
}
}
namespace Version2
{
public interface IOpenDefectService
{
void Submit(string title, string description, int severity);
// Removed Bump method - it was a bad idea
// Added an optional priority field
void Submit(string title, string description, int severity,
int priority);
// Added support for deleting
void Delete(int id);
}
}
public class OpenDefectService : Version1.IOpenDefectService,
Version2.IOpenDefectService
{
// Still must support it until you no longer have any clients using it.
// Here to support staggered rollouts
[Obsolete("This method is deprecated. Don't use it")]
public void Bump(int issueId) { /* Still has implementation... */ }
public void Submit(string title, string description,
int severity) { /* ... */ }
public void Submit(string title, string description,
int severity, int priority) { /* ... */ }
public void Delete(int id) { /* ... */ }
}
你不需要装饰图案
decorator模式在这个场景中不是很有用。它的目的是允许您在运行时附加行为。您试图在编译时附加行为(或多或少)
见:
此模式允许用户创建以下类型的代码实例:
- 故意未修饰的类型,仅具有基本行为
- 允许您提供重写行为的任意修饰类型
namespace Version1
{
public interface IOpenDefectService
{
void Submit(string title, string description, int severity);
void Bump(int issueId);
}
}
namespace Version2
{
public interface IOpenDefectService
{
void Submit(string title, string description, int severity);
// Removed Bump method - it was a bad idea
// Added an optional priority field
void Submit(string title, string description, int severity,
int priority);
// Added support for deleting
void Delete(int id);
}
}
public class OpenDefectService : Version1.IOpenDefectService,
Version2.IOpenDefectService
{
// Still must support it until you no longer have any clients using it.
// Here to support staggered rollouts
[Obsolete("This method is deprecated. Don't use it")]
public void Bump(int issueId) { /* Still has implementation... */ }
public void Submit(string title, string description,
int severity) { /* ... */ }
public void Submit(string title, string description,
int severity, int priority) { /* ... */ }
public void Delete(int id) { /* ... */ }
}
我还没有部署任何接口。部分问题是第一个接口需要支持多少(我很确定基本的操作集可能就足够了)。为什么我需要引入一个新的接口而不是更新现有的接口?另外,您能否给出一个例子来说明运行时和编译时行为的不同。这个答案是:“为了支持将来更多的操作”。“我还没有部署任何接口”-那么您就不需要引入新的接口或新的装饰器。只需更改您的界面:)我的意思是-我将使用包含2-3个操作的简化界面发布此文件,但在更新此文件以支持未来几个月/年的更多操作时,希望将工作量减至最少。@liortal:最基本的工作(如果您可以立即重新部署整个内容)是编辑您的界面。如果你是你唯一的消费者,你不需要保持向后兼容,你可以一次性更换整个应用程序。我还没有部署任何界面。部分问题是第一个接口需要支持多少(我很确定基本的操作集可能就足够了)。