Design Patterns & Refactoring
Bridge
Oliver Haase
HTWG Konstanz
‘A computer once beat me at chess, but it was no match to me at kick-boxing’ — Emo Philips
Description I
Classification: object based structural pattern
Purpose: decouple abstraction (interfaces) and implementation, such that both can evolve independently
Motivation
Scenario:
Provide more comfortable RemoteOpComminterface without modification of existing type hierarchy.
Motivation
Problem: Implementation classesTCPCommunication and UDPCommunication must be duplicated.
Motivation
Structure using Bridge Pattern
CommImpl sendImpl() receiveImpl() Communication
send(op, params): void receive(): Result
RemoteOpComm invoke(op, params): Result
impl.sendImpl(op,params);
TcpCommunication sendImpl(op, params): void receiveImpl(): Result
UdpCommunication sendImpl(op, params): void receiveImpl(): Result impl
return impl.receiveImpl();
send(op, params);
return receive();
Bridge Client
Implications
Please note that
the abstractions (left hand side) use only the functionality provided by classCommImpl. Additional functionality in the subclasses cannot be taken advantage of;
additional functionality in sub-interfaces must be achieved only through usage of the general functionality as contained in the root interface.
General Structure
Bridge Implementor
operationImpl() Abstraction
operation()
Specialization
impl.operationImpl();
ConcreteImplementorA operationImpl()
ConcreteImplementorB operationImpl() impl
Client
Description II
Members:
Abstraction(Communication):
defines interface of the abstraction
maintains reference toImplementor instance
Specialization(RemoteOpComm): extendsAbstractioninterface through usage of its operations
Implementor (CommImpl): defines interface for implementation classes (can differ from Abstractioninterface)
ConcreteImplementor(TcpCommunication): provides implementation of Implementorinterface
Description III
Interactions:Abstractiondelegates requests to Implementorobject Consequences:
loose coupling of abstraction and implementation Implementor object can be replaced at run-time
Implementation
Who decides when and how, what particular Implementor object to use?
1 Specializationobject, based on the params passed in at construction time.
Example:Collection object that gets initialized with small initial size uses LinearList implementation. LargeCollection object uses BTree implementation. (Note: Implementation can be dynamically replaced as the collection grows.)
2 Others decide→ creational patterns!
Specializationobject gets fed with factory or prototype Dependency injection→Specializationobject gets passed in Implementor object byClient.