模式在运行时使用新方法添加行为
本文关键字:新方法 添加行 运行时 模式 | 更新日期: 2023-09-27 18:17:52
我希望能够在运行时使用模式来添加行为(通过额外的方法/属性)到现有的类。
这看起来与众所周知的装饰器模式非常相似,然而,我所能找到的装饰器模式的示例不允许嵌套的添加新方法。下面的例子可以很好地说明这一点:
namespace Decorator {
// classes and types
// - component:
// - concrete component:
// - decorator:
// - concrete decorator:
class Program {
static void Main(string[] args) {
IServer serverA = new Server(); // has database services
IServer serverB = new Server(); // has web services
IServer serverC = new Server(); // has both database services and web services
// add behaviour using the decorator pattern
serverA = new DatabaseServerDecorator(serverA);
serverB = new WebServerDecorator(serverB);
serverC = new DatabaseServerDecorator(serverA);
serverC = new WebServerDecorator(serverA); // note the 2nd level which causes loss of 'awareness' of the DbDecorator
// test restart of servers
serverA.RestartServer();
serverB.RestartServer();
serverC.RestartServer();
// test restart of web services
var webServerB = serverB as WebServerDecorator;
var webServerC = serverB as WebServerDecorator;
webServerB.RestartWebServices();
webServerC.RestartWebServices();
// test restart of database services
var databaseServerA = serverA as DatabaseServerDecorator;
var databaseServerC = serverC as DatabaseServerDecorator; // this will not work (HOW TO FIX??)
databaseServerA.RestartDatabaseServices();
databaseServerC.RestartDatabaseServices();
Console.ReadKey();
}
}
// IComponent
public interface IServer {
void RestartServer();
}
// Component
public class Server : IServer {
public void RestartServer() {
Console.WriteLine("Server restarted.");
}
}
// DecoratorA
public class WebServerDecorator : IServer {
IServer _server;
public WebServerDecorator(IServer server) {
_server = server;
}
public void RestartServer() {
_server.RestartServer();
}
public void RestartWebServices() {
Console.WriteLine("Web services restarted.");
}
}
public class DatabaseServerDecorator : IServer {
IServer _server;
public DatabaseServerDecorator(IServer server) {
_server = server;
}
public void RestartServer() {
_server.RestartServer();
}
public void RestartDatabaseServices() {
Console.WriteLine("Database services restarted.");
}
}
}
(实际代码将使用"if object is Type"进行标识,但为了简洁/清晰,已将其删除)
这可能吗?在上面的示例中,服务器可能有多个"服务",因此不需要创建每个可能的排列(随着服务数量的增长,这将变得难以管理)。
对Console.WriteLine("database service ..")
的调用应该属于RestartServer()
,因为它在逻辑上属于"接口契约"。这就是Decorator模式的目标——修饰接口提供的行为(仅此而已)。创建新方法(扩展接口契约)并不是Decorator要做的。不确定你想要实现什么,但也许你不应该过度抽象它?有不同的接口,如IWebServer
, IDatabaseServer
(实现IServer
)和装饰IWebServer
, IDatabaseServer
代替IServer
如何?