Using multiple decorators to add functionality to an object?

前端 未结 1 2016
礼貌的吻别
礼貌的吻别 2021-01-01 00:19

I am trying to understand the decorator pattern and from the examples I understand how decorator objects can be used to extend existing functionality at runtime by overridin

1条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-01 00:51

    This is a common misconception of the decorator pattern. What you can do with the decorator pattern is to extend the functionality, not the API.

    What does this mean?
    It means, you can add new functionality, to the methods provided by the API, in your case IBusinessObject. Lets say your interface has a method XmlDocument Export() which is implemented in BusinessObject and returns the data in the BusinessObject instance in an XmlDocument instance.
    Now, you could create a LoggingDecorator, which implements the Export method like so:

    public XmlDocument Export()
    {
        _logger.Log("Exporting...");
        var result = _decoratedObject.Export();
        _logger.Log("Done exporting...");
        return result;
    }
    

    Or you can create a BusinessObjectSigningExportDecorator which signs the returned XmlDocument using the xml-dsig algorithm:

    public XmlDocument Export()
    {
        var result = _decoratedObject.Export();
        return SignXmlDocument(result);
    }
    

    You could then use them together like so:

    IBusinessObject businessObject = new LoggingDecorator(
        new BusinessObjectSigningExportDecorator(
            new BusinessObject()
        )
    );
    
    var xmlDocument = businessObject.Export();
    

    The call to Export will now write the log messages and sign the xml export. But you still can use BusinessObject without a decorator or with only one of the decorators.

    The reason for using the decorator pattern is to be able to transparently add functionality. As you can see, the user of the businessObject variable of type IBusinessObject doesn't know and doesn't need to know the actual type that is used. It will work in the case with or without decorators.

    Thinking further: When you have a factory that returns IBusinessObjects you can extend the functionality, without changing the code that uses them and without changing the implementation of the class the implement IBusinessObject. You just need to create another decorator and "attach" it inside the factory and therefore, you are making a change, that occurs only in a limited area of the code. So if this change breaks anything, you know exactly what code is responsible for the breakage.

    Additionally, this enforces separation of concerns, because your normal business object implementation doesn't know and care about which signing algorithm should be used or that one needs to be used altogether.

    0 讨论(0)
提交回复
热议问题