模式在运行时使用新方法添加行为

本文关键字:新方法 添加行 运行时 模式 | 更新日期: 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如何?