Decorator Pattern
Definition
The Decorator pattern lets you attach additional responsibilities and modify an instance functionality dynamically. Decorators provide a flexible alternative to subclassing for extending functionality, using composition instead of inheritance.Where to use
•When you want to add responsibilities to individual objects dynamically and transparently, without affecting the original object or other objects.•When you want to add responsibilities to the object that you might want to change in the future.
•When extension by static subclassing is impractical.
Benefits
•More flexibility than static inheritance.•Avoids feature-laden classes high up in the hierarchy.
•Simplifies coding because you write a series of classes each targeted at a specific part of the functionality rather than
•coding all behavior into the object.
•Enhances the object's extensibility because you make changes by coding new classes.
Drawbacks/consequences
One thing to keep in mind when implementing the Decorator pattern is that you need to keep the component interface simple. You want to avoid making the component interface overly complex, because a complex interface will make it that much harder to get each decorator right. Another potential drawback of the Decorator pattern is the performance overhead associated with a long chain of decorators.Decorator Pattern Class Diagram
Decorator Pattern Example
package com.designpattern.decorator; public interface Logger { public void log(String msg); } package com.designpattern.decorator; public class LoggerDecorator implements Logger { Logger logger; public LoggerDecorator(Logger logger) { super(); this.logger = logger; } public void log(String msg) { logger.log(msg); } } package com.designpattern.decorator; public class ConsoleLogger implements Logger { public void log(String msg) { System.out.println("Detta ska skrivas till consolen! "+ msg); } } package com.designpattern.decorator; public class EncryptLogger extends LoggerDecorator { public EncryptLogger(Logger logger) { super(logger); } public void log(String msg) { msg = encrypt(msg); logger.log(msg); } private String encrypt(String msg) { msg = msg.substring(msg.length()-1) + msg.substring(0, msg.length() -1); return msg; } } package com.designpattern.decorator; public class HTMLLogger extends LoggerDecorator { public HTMLLogger(Logger logger) { super(logger); } public void log(String msg) { msg = makeHTML(msg); logger.log(msg); } private String makeHTML(String msg) { msg = "" + "" + msg + "" + ""; return msg; } } package com.designpattern.decorator; public class LoggerFactory { public static final String TYPE_CONSOL_LOGGER = "console"; public static final String TYPE_FILE_LOGGER = "file"; public Logger getLogger(String type) { if(TYPE_CONSOL_LOGGER.equals(type)) { return new ConsoleLogger(); } else { return new FileLogger(); } } } package com.designpattern.decorator; public class DecoratorClient { public static void main(String[] args) { LoggerFactory factory = new LoggerFactory(); Logger logger = factory.getLogger(LoggerFactory.TYPE_FILE_LOGGER); HTMLLogger htmlLogger = new HTMLLogger(logger); htmlLogger.log("A message to log"); EncryptLogger encryptLogger = new EncryptLogger(logger); encryptLogger.log("A message to log"); } }
When DecoratorClient is executed the result is:
c:>Detta ska skrivas till en fil! <html><body><b>A message to
log</b></body></html>
c:>Detta ska skrivas till en fil! gA message to log
0 comments:
Post a Comment