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

时间:2014-08-14 08:09:23

标签: c# oop design-patterns decorator strategy-pattern

我希望能够使用模式在运行时向现有类添加行为(通过其他方法/属性)。

这看起来与众所周知的装饰器模式非常相似,但是,我能够找到装饰器模式的示例不允许嵌套添加新方法。最好用一个例子说明这一点:

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”进行识别,但为了简洁/清晰,已将其删除)

这可能吗?在上面的示例中,服务器可能具有多个“服务”,因此不希望必须创建每个可能的排列(随着服务数量的增长,这将变得难以管理)。

1 个答案:

答案 0 :(得分:0)

Console.WriteLine("database service ..")的来电应属于RestartServer(),因为它在逻辑上属于"接口合同"。这是Decorator模式的目标 - 你装饰界面提供的行为(但不多)。创建新方法(扩展接口契约)并不是Decorator的意图。不确定你想要实现什么,但也许你不应该过度抽象它?如何使用不同的界面,例如IWebServerIDatabaseServer(实施IServer)并装饰IWebServerIDatabaseServer而不是IServer