|
The bridge pattern is a design pattern used in software engineering which is meant to "decouple an abstraction from its implementation so that the two can vary independently" (Gamma et al.). The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes. In software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design. ...
Software engineering (SE) is the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software. ...
In computer science, abstraction is a mechanism and practice to reduce and factor out details so that one can focus on a few concepts at a time. ...
Look up Implementation in Wiktionary, the free dictionary. ...
Encapsulation may refer to: information hiding and separation of concerns, in software engineering, the process of enclosing programming elements inside larger, more abstract entities integrated circuit encapsulation, in electronics the design and manufacture of protective packages micro-encapsulation, means to confine material molecular encapsulation, means to confine molecules encapsulation (pharmacology...
This article does not cite any references or sources. ...
In object-oriented programming of computer science, an inheritance is a way to form new classes (instances of which will be objects) using pre-defined objects or classes where new ones simply take over old ones implementations and characteristics. ...
In object-oriented programming, a class is a programming language construct used to group related fields and methods. ...
When a class varies often, the features of object-oriented programming become very useful because changes to a program's code can be made easily with minimal prior knowledge about the program. The bridge pattern is useful when not only the class itself varies often but also what the class does. The class itself can be thought of as the abstraction and what the class can do as the implementation. Object-oriented programming (OOP) is a programming paradigm that uses objects and their interactions to design applications and computer programs. ...
A computer program is a collection of instructions that describe a task, or set of tasks, to be carried out by a computer. ...
Source code (commonly just source or code) is any series of statements written in some human-readable computer programming language. ...
Variant: The implementation can be decoupled even more by deferring the presence of the implementation to the point where the abstraction is utilized (as illustrated by the Visual Prolog example below). Non-technical examples
Shape abstraction When the abstraction and implementation are separated, they can vary independently. Consider the abstraction of shapes. There are many types of shapes, each with its own properties. And there are things that all shapes do. One thing all shapes can do is draw themselves. However, drawing graphics to a screen can sometimes be dependent on different graphics implementations or operating systems. Shapes have to be able to be drawn on many types of operating systems. Having the shape itself implement them all, or modifying the shape class to work with different architectures is not practical. The bridge helps by allowing the creation of new implementation classes that provide the drawing implementation. The abstraction class, shape, provides methods for getting the size or properties of a shape. The implementation class, drawing, provides an interface for drawing graphics. If a new shape needs to be created or there is a new graphics API to be drawn on, then it is very easy to add a new implementation class that implements the needed features.[1] API and Api redirect here. ...
Car abstraction Imagine two types of cars (the abstraction), a Jaguar and a Mercedes (both are Refinements of the Abstraction). The Abstraction defines that a Car has features such as tires and an engine. Refinements of the Abstraction declare what specific kind of tires and engine it has. Finally, there are two types of road. The road is the Implementor (see image below). A highway and an interstate highway are the Implementation Details. Any car refinement needs to be able to drive on any type of road; this concept is what the Bridge Pattern is all about.
Structure
Image File history File links Bridge_classdia. ...
- Client
- the Object using the bridge pattern
- Abstraction
- defines the abstract interface
- maintains the Implementor reference
- Refined Abstraction
- extends the interface defined by Abstraction
- Implementor
- defines the interface for implementation classes
- ConcreteImplementor
- implements the Implementor interface
Code examples Java The following Java (SE 6) program illustrates the 'shape' example given above and will output: Java language redirects here. ...
API1.circle at 1.000000:2.000000 radius 7.500000 API2.circle at 5.000000:7.000000 radius 27.500000 /** "Implementor" */ interface DrawingAPI { public void drawCircle(double x, double y, double radius); } /** "ConcreteImplementor" 1/2 */ class DrawingAPI1 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API1.circle at %f:%f radius %fn", x, y, radius); } } /** "ConcreteImplementor" 2/2 */ class DrawingAPI2 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API2.circle at %f:%f radius %fn", x, y, radius); } } /** "Abstraction" */ interface Shape { public void draw(); // low-level public void resizeByPercentage(double pct); // high-level } /** "Refined Abstraction" */ class CircleShape implements Shape { private double x, y, radius; private DrawingAPI drawingAPI; public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) { this.x = x; this.y = y; this.radius = radius; this.drawingAPI = drawingAPI; } // low-level i.e. Implementation specific public void draw() { drawingAPI.drawCircle(x, y, radius); } // high-level i.e. Abstraction specific public void resizeByPercentage(double pct) { radius *= pct; } } /** "Client" */ class BridgePattern { public static void main(String[] args) { Shape[] shapes = new Shape[2]; shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1()); shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2()); for (Shape shape : shapes) { shape.resizeByPercentage(2.5); shape.draw(); } } } C# The following C# program illustrates the "shape" example given above and will output: The title given to this article is incorrect due to technical limitations. ...
API1.circle at 1:2 radius 7.5 API2.circle at 5:7 radius 27.5 using System; /** "Implementor" */ interface IDrawingAPI { void DrawCircle(double x, double y, double radius); } /** "ConcreteImplementor" 1/2 */ class DrawingAPI1 : IDrawingAPI { public void DrawCircle(double x, double y, double radius) { System.Console.WriteLine("API1.circle at {0}:{1} radius {2}", x, y, radius); } } /** "ConcreteImplementor" 2/2 */ class DrawingAPI2 : IDrawingAPI { public void DrawCircle(double x, double y, double radius) { System.Console.WriteLine("API2.circle at {0}:{1} radius {2}", x, y, radius); } } /** "Abstraction" */ interface IShape { void Draw(); // low-level (i.e. Implementation-specific) void ResizeByPercentage(double pct); // high-level (i.e. Abstraction-specific) } /** "Refined Abstraction" */ class CircleShape : IShape { private double x, y, radius; private IDrawingAPI drawingAPI; public CircleShape(double x, double y, double radius, IDrawingAPI drawingAPI) { this.x = x; this.y = y; this.radius = radius; this.drawingAPI = drawingAPI; } // low-level (i.e. Implementation-specific) public void Draw() { drawingAPI.DrawCircle(x, y, radius); } // high-level (i.e. Abstraction-specific) public void ResizeByPercentage(double pct) { radius *= pct; } } /** "Client" */ class BridgePattern { public static void Main(string[] args) { IShape[] shapes = new IShape[2]; shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1()); shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2()); foreach (Shape shape in shapes) { shape.ResizeByPercentage(2.5); shape.Draw(); } } } Perl The following Perl program illustrates the 'shape' example given above and will output: API1.circle at 1:2 radius 7.5 API2.circle at 5:7 radius 27.5 ### ConcreteImplementor 1/2 package DrawingAPI1; sub new { my $class = shift; return bless {}, $class; } sub draw_circle { my($self, $x, $y, $radius) = @_; print "API1.circle at $x:$y radius $radiusn"; } 1; ### ConcreteImplementor 2/2 package DrawingAPI2; sub new { my $class = shift; return bless({}, $class); } sub draw_circle { my($self, $x, $y, $radius) = @_; print "API2.circle at $x:$y radius $radiusn"; } 1; ### Refined Abstraction package CircleShape; sub new { my($class, $x, $y, $radius, $drawing_api) = @_; return bless { x => $x, y => $y, radius => $radius, drawing_api => $drawing_api, }, $class; } sub draw { my $self = shift; $self->{drawing_api}->draw_circle(@{$self}{'x', 'y', 'radius'}); } sub resize_by_percentage { my($self, $percent) = @_; $self->{radius} *= $percent; } 1; ### client my @shapes = ( CircleShape->new(1, 2, 3, DrawingAPI1->new), CircleShape->new(5, 7, 11, DrawingAPI2->new), ); foreach my $shape (@shapes) { $shape->resize_by_percentage(2.5); $shape->draw(); } PHP Note that this example uses features available only in PHP 5 and up. It will not work in PHP 4. #!/usr/local/bin/php <?php /** "Implementor" */ interface DrawingAPI { public function drawCircle($x, $y, $radius); } /** "ConcreteImplementor" 1/2 */ class DrawingAPI1 implements DrawingAPI { public function drawCircle($x, $y, $radius) { echo "API1.circle at $x:$y radius $radiusn"; } } /** "ConcreteImplementor" 2/2 */ class DrawingAPI2 implements DrawingAPI { public function drawCircle($x, $y, $radius) { echo "API2.circle at $x:$y radius $radiusn"; } } /** "Abstraction" */ interface Shape { public function draw(); // low-level public function resizeByPercentage($pct); // high-level } /** "Refined Abstraction" */ class CircleShape implements Shape { private $x; private $y; private $radius; private $drawingAPI; public function __construct($x, $y, $radius, DrawingAPI $drawingAPI) { $this->x = $x; $this->y = $y; $this->radius = $radius; $this->drawingAPI = $drawingAPI; } // low-level i.e. Implementation specific public function draw() { $this->drawingAPI->drawCircle($this->x, $this->y, $this->radius); } // high-level i.e. Abstraction specific public function resizeByPercentage($pct) { $this->radius *= $pct; } } /** "Client" */ $shapes = array(); $shapes[] = new CircleShape(1, 2, 3, new DrawingAPI1()); $shapes[] = new CircleShape(5, 7, 11, new DrawingAPI2()); foreach ($shapes as $shape) { $shape->resizeByPercentage(2.5); $shape->draw(); } ?> Python The following Python program illustrates the 'shape' example given above and will output: API1.circle at 1.000000:2.000000 radius 7.500000 API2.circle at 5.000000:7.000000 radius 27.500000 class CircleShape: def __init__(self,x,y,r,da): self.x = x self.y = y self.r = r self.da = da def draw(self): self.da.drawCircle(self.x,self.y,self.r) def resizeByPercentage(self,pct): self.r *= pct class DrawingAPI2: def drawCircle(self,x,y,r): print "API2.circle at %f:%f radius %f" % (x,y,r) class DrawingAPI1: def drawCircle(self,x,y,r): print "API1.circle at %f:%f radius %f" % (x,y,r) if __name__ == '__main__': shapes = [CircleShape(1,2,3,DrawingAPI1()), CircleShape(5,7,11,DrawingAPI2())] for shape in shapes: shape.resizeByPercentage(2.5) shape.draw() This will print: Ruby is a reflective, dynamic, object-oriented programming language. ...
API1.circle at 1.000000:2.000000 radius 7.500000 API2.circle at 5.000000:7.000000 radius 27.500000 class CircleShape def initialize(x, y, r, da) @x, @y, @r, @da = x, y, r, da end def draw @da.draw_circle(@x, @y, @r) end def resize_by_percentage(pct) @r *= pct end end class DrawingAPI1 def draw_circle(x, y, r) printf "API1.circle at %f:%f radius %fn", x, y, r end end class DrawingAPI2 def draw_circle(x, y, r) printf "API2.circle at %f:%f radius %fn", x, y, r end end shapes = [CircleShape.new(1, 2, 3, DrawingAPI1.new), CircleShape.new(5, 7, 11, DrawingAPI2.new)] shapes.each do |shape| shape.resize_by_percentage(2.5) shape.draw end DrawingAPI1 and DrawingAPI2 can be implemented more elegantly as blocks.[citation needed] class CircleShape def initialize(x, y, r, &block) @x, @y, @r, @block = x, y, r, block end def draw @block.call(@x, @y, @r) end def resize_by_percentage(perc) @r *= perc end end shapes = [CircleShape.new(1, 2, 3) { |x, y, r| printf "API1.circle at %f:%f radius %fn", x, y, r }, CircleShape.new(5, 7, 11) { |x, y, r| printf "API2.circle at %f:%f radius %fn", x, y, r }] shapes.each do |shape| shape.resize_by_percentage(2.5) shape.draw end This example illustrates the variant in which the presence of the implementation is deferred to the point where the model is used. Visual Prolog, also formerly known as PDC Prolog and Turbo Prolog, is a strongly typed object-oriented extension of Prolog. ...
Abstract implementor interface drawingApi predicates drawCircle : (real X, real Y, real Radius). drawSquare : (real X, real Y, real Width). end interface drawingApi Concrete implementor 1 (of 2) class openGL : drawingApi end class openGL implement openGL clauses drawCircle(X, Y, Radius) :- stdio::writef("OpenGL circle at (%,%) with radius=%n", X, Y, Radius). clauses drawSquare(X, Y, Width) :- stdio::writef("OpenGL square at (%,%) with width=%n", X, Y, Width). end implement openGL Concrete implementor 2 (of 2) class directX : drawingApi end class directX % directX (trivial) implementation skipped Abstract shape data model interface shape predicates draw : (drawingApi DrawingAPI). end interface shape class circle : shape constructors new : (real X, real Y, real Radius). end class circle implement circle facts x : real. y: real. radius : real. clauses new(X, Y, Radius) :- x := X, y := Y, radius := Radius. clauses draw(DrawingAPI) :- DrawingAPI:drawCircle(x, y, radius). end implement circle class square : shape constructors new : (real X, real Y, real Width). end class square implement square facts x : real. y: real. width : real. clauses new(X, Y, Width) :- x := X, y := Y, width := Width. clauses draw(DrawingAPI) :- DrawingAPI:drawSquare(x, y, width). end implement square Client code goal console::init(), % The concrete model is a list of shapes ConcreteModel = [circle::new(1, 2, 7.5), circle::new(5, 7, 27.5), square::new(2.9, 80, 17)], % draw using OpenGL OpenGL = openGL::new(), foreach S1 = list::getMember_nd(ConcreteModel) do S1:draw(OpenGL) end foreach, % draw the same model using DirectX DirectX = directX::new(), foreach S2 = list::getMember_nd(ConcreteModel) do S2:draw(DirectX) end foreach. The following C++ program illustrates the "shape" example given above and will output: For a WikiBook on programming with C++, see Wikibooks: C++ Programming. ...
API1.circle at 1:2 7.5 API2.circle at 5:7 27.5 #include "stdafx.h" #include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; /************************************************************************/ /* Implementor */ /************************************************************************/ // interface class DrawingAPI { public: virtual void drawCircle(double x, double y, double radius) = 0; }; //concrete implementor1 class DrawingAPI1 : public DrawingAPI { public: void drawCircle(double x, double y, double radius) { cout<<"API1.circle at "<<x<<":"<<y<<" "<< radius<<endl; } }; //concrete implementor2 class DrawingAPI2 : public DrawingAPI { public: void drawCircle(double x, double y, double radius) { cout<<"API2.circle at "<<x<<":"<<y<<" "<< radius<<endl; } }; /************************************************************************/ /* Abstraction */ /************************************************************************/ class Shape { public: virtual void draw() = 0; virtual void resizeByPercentage(double pct) = 0; }; class CircleShape:public Shape { public: CircleShape(double x, double y,double radius,DrawingAPI &drawingAPI): m_x(x),m_y(y),m_radius(radius),m_drawingAPI(drawingAPI) {} void draw() { m_drawingAPI.drawCircle(m_x,m_y,m_radius); } void resizeByPercentage(double pct) { m_radius *= pct; } private: double m_x,m_y,m_radius; DrawingAPI& m_drawingAPI; }; ////////////////////////////////////////////////////////////////////////// //Test typedef std::vector<Shape*>::iterator ShapeIt; int main(int argc, char* argv[]) { std::vector<Shape*> vecShapes; vecShapes.push_back(new CircleShape(1,2,3,*(new DrawingAPI1))); vecShapes.push_back(new CircleShape(5,7,11,*(new DrawingAPI2))); ShapeIt begin,end; begin = vecShapes.begin(); end = vecShapes.end(); for_each(begin,end,std::bind2nd(std::mem_fun(&Shape::resizeByPercentage),2.5)); for_each(begin,end,mem_fun(&Shape::draw)); return 0; } The following Erlang program illustrates the 'shape' example given above and will output: Erlang is a general-purpose concurrent programming language and runtime system. ...
API1.circle at 1.000000:2.000000 radius 7.500000 API2.circle at 5.000000:7.000000 radius 27.500000 -module(bridge). -compile(export_all). -record(circle, {x, y, r, da}). % record containing: x, y, radius, % and drawing api circle_shape(X, Y, R, Da) -> % convenience function to construct #circle{x =X, y =Y, r =R, da =Da}. % a circle record resize_by_percentage(Pct) -> fun (C= #circle{r =R}) -> % pull the radius field from the record C#circle{r= R*Pct} % update & return the record end. % return this fun draw(#circle{x =X, y =Y, r =R, da =DA}) -> % get x, y, radius, and DA(X, Y, R). % the drawing api drawing_api1(X,Y,R) -> io:format("API1.circle at ~.6f:~.6f radius ~.6f~n", [X,Y,R]). drawing_api2(X,Y,R) -> io:format("API2.circle at ~.6f:~.6f radius ~.6f~n", [X,Y,R]). demo() -> CircleShape= fun circle_shape/4, % make things slightly DrawingAPI1= fun drawing_api1/3, % less blatantly DrawingAPI2= fun drawing_api2/3, % functional Shapes= [CircleShape(1.0, 2.0, 3, DrawingAPI1), CircleShape(5.0, 7.0, 11, DrawingAPI2)], Resized= lists:map(resize_by_percentage(2.5), % resize the shapes Shapes), lists:map(fun draw/1, Resized), % display the shapes {Shapes, Resized}. See also Template method: UML class diagram. ...
In computer programming, the strategy pattern is a particular software design pattern, whereby algorithms can be selected on-the-fly at runtime. ...
External links - C# Design Patterns: The Bridge Pattern. Sample Chapter. From: James W. Cooper. C# Design Patterns: A Tutorial. Addison-Wesley. ISBN 0201844532.
- Example of using Bridge pattern in Jt, J2EE Pattern Oriented Framework
Pearson can mean Pearson PLC the media conglomerate. ...
References - ^ Shalloway; Trott. Design Patterns Explained: A New Perspective on Object-Oriented Design.
In software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design. ...
This article is about the book by Gamma et al. ...
A software design pattern, the Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme. ...
The Builder Pattern is a software design pattern. ...
The factory method pattern is an object-oriented design pattern. ...
A prototype pattern is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. ...
In software engineering, the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. ...
In computer programming, the adapter design pattern (often referred to as the wrapper pattern or simply a wrapper) adapts one interface for a class into one that a client expects. ...
This does not cite any references or sources. ...
For decorators in Python, see Python syntax and semantics#Decorators. ...
The façade pattern is an object-oriented design pattern. ...
Flyweight is a software design pattern. ...
// In computer programming, the proxy pattern is a software design pattern. ...
In Object Oriented Design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. ...
In object-oriented programming, the Command pattern is a design pattern in which objects are used to represent actions. ...
In computer programming, the interpreter pattern is a particular design pattern. ...
In object-oriented programming, an iterator is an object allowing one to sequence through all of the elements or parts contained in some other object, typically a container or list. ...
The mediator pattern is a software design pattern that provides a unified interface to a set of interfaces in a subsystem. ...
The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo by rollback). ...
The observer pattern (sometimes known as publish/subscribe) is a design pattern used in computer programming to observe the state of an object in a program. ...
A behavioral software design pattern, state pattern is used in computer programming to represent the state of an object. ...
In computer programming, the strategy pattern is a particular software design pattern, whereby algorithms can be selected on-the-fly at runtime. ...
Template method: UML class diagram. ...
In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure. ...
|