![]() ![]() Solution #4: Beyond the Gang of Four patterns ¶ Without building any special combined classes: That can be wrapped around any logger we want.įiltering can be combined with output at runtime The filtering code has moved outside of any particular logger class. logger = logger def log ( self, message ): if self. class LogFilter : def _init_ ( self, pattern, logger ): self. priority, message ) # The filter calls the same method it offers. priority = priority def log ( self, message ): syslog. encode ( 'ascii' )) class SyslogLogger : def _init_ ( self, priority ): self. sock = sock def log ( self, message ): self. flush () class SocketLogger : def _init_ ( self, sock ): self. file = file def log ( self, message ): self. ![]() class FileLogger : def _init_ ( self, file ): self. priority, message )Ībstraction objects and implementation objects priority = priority def emit ( self, message ): syslog. encode ( 'ascii' )) class SyslogHandler : def _init_ ( self, priority ): self. sock = sock def emit ( self, message ): self. flush () class SocketHandler : def _init_ ( self, sock ): self. file = file def emit ( self, message ): self. class FileHandler : def _init_ ( self, file ): self. log ( message ) # The “implementations” hidden behind the scenes. _init_ ( handler ) def log ( self, message ): if self. emit ( message ) class FilteredLogger ( Logger ): def _init_ ( self, pattern, handler ): self. handler = handler def log ( self, message ): self. class Logger ( object ): def _init_ ( self, handler ): self. # The “abstractions” that callers will see. Instead of also having to support a flush() method So let’s design the inner “implementation” object to accept a raw message,Īnd reduce the interface to only a single method emit() We now get to define the interface of the wrapped class ourselves. That sometimes had to be removed again in the adapter. To match the interface of a Python file object. While output belongs in the “implementation” class.Ī separate echelon of classes now governs writing.īut instead of having to contort our output classes That filtering belongs out in the “abstraction” class ![]() If we make the (perhaps slightly arbitrary) decision We can apply the Bridge Pattern to our logging example The Bridge Pattern splits a class’s behaviorīetween an outer “abstraction” object that the caller seesĪnd an “implementation” object that’s wrapped inside. Without the need to create any further classes: Our adapters only need to implement the two file methodsĪnd so the subclass explosion is avoided!Ĭan be freely mixed and matched at runtime Just as it’s not important that a duck can walk if all you need is a quack, The full slate of more than a dozen methods that a real file offers. They are also under no obligation to re-implement Or from the file type they are imitating. To inherit from either the classes they wrap Our adapters, for example, are exempt from the need So an adapter’s only responsibility is to offer the right methods. priority, message ) def flush ( self ): pass priority = priority def write ( self, message_and_newline ): message = message_and_newline. encode ( 'ascii' )) def flush ( self ): pass class FileLikeSyslog : def _init_ ( self, priority ): self. sock = sock def write ( self, message_and_newline ): self. Import socket class FileLikeSocket : def _init_ ( self, sock ): self. ![]()
0 Comments
Leave a Reply. |