您好,登錄后才能下訂單哦!
GOF 在《設計模式》中給橋梁模式的定義為:將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化。這里的抽象部分和實現(xiàn)部分不是我們通常認為的父類與子類、接口與實現(xiàn)類的關系,而是組合關系。也就是說,實現(xiàn)部分是被抽象部分調用,以用來完成(實現(xiàn))抽象部分的功能。
橋梁模式的用意是“將抽象化(Abstraction)和實現(xiàn)化(Implementation)脫耦,使得二者可以獨立地變化?!?/span>
抽象化:
存在于多個實體中的共同的概念性聯(lián)系,就是抽象化。
實現(xiàn)化:
抽象化給出的具體實現(xiàn),就是實現(xiàn)化。
脫耦:
耦合,就是兩個實體的行為的某種強關聯(lián)。脫耦,就是將這種強關聯(lián)去掉。
強關聯(lián),就是在編譯時期就確定了,無法在運行時期動態(tài)改變的關聯(lián)。
弱關聯(lián),就是可以動態(tài)地確定,并可以在運行時期動態(tài)地改變的關聯(lián)。
Java中,繼承關系是強關聯(lián),組合(聚合)關系是軟關聯(lián)。
一、組成:
1) 抽 象 ( Abstraction ) 角色: 它定義了抽象類的接口而且維護著一個指向實現(xiàn)角色的引用。
2) 精確\修正抽象(RefinedAbstraction\SpecializedAbstraction)角色:實現(xiàn)并擴充由抽象角色定義的接口。
3) 實現(xiàn)(Implementor)角色:給出了實現(xiàn)類的接口,這里的接口與抽象角色中的接口可以不一致。實現(xiàn)化角色應當只給出底層操作,而抽象化角色應當只給出基于底層操作的更高一層的操作。
4) 具體實現(xiàn)(ConcreteImplementor)角色:給出了實現(xiàn)角色定義接口的具體實現(xiàn)。
二、UML類圖:
三、類圖的代碼描述(JAVA):
以下代碼來自《Thinking in Patterns with Java》:
//抽象部分的抽象角色
class Abstraction {
//維護著一個指向實現(xiàn)(Implementor)角色的引用
private Implementation implementation;
public Abstraction(Implementation imp) {
implementation = imp;
}
// 下面定義了抽象部分應該有的接口
public void service1() {
//使用了實現(xiàn)部分已有的接口
//組合實現(xiàn)功能
implementation.facility1();
implementation.facility2();
}
public void service2() {
implementation.facility2();
implementation.facility3();
}
public void service3() {
implementation.facility1();
implementation.facility2();
implementation.facility4();
}
// For use by subclasses:
protected Implementation getImplementation() {
return implementation;
}
}
//抽象部分的精確抽象角色
class ClientService1 extends Abstraction {
public ClientService1(Implementation imp) {
super(imp);
}
//使用抽象角色提供的方法組合起來完成某項功能
//這就是為什么叫精確抽象角色(修正抽象角色)
public void serviceA() {
service1();
service2();
}
public void serviceB() {
service3();
}
}
//另一個精確抽象角色,和上面一樣的被我省略了
class ClientService2 extends Abstraction {
//這里是直接通過實現(xiàn)部分的方法來實現(xiàn)一定的功能
public void serviceE() {
getImplementation().facility3();
}
}
//實現(xiàn)部分的實現(xiàn)角色
interface Implementation {
//這個接口只是定義了一定的接口
void facility1();
void facility2();
void facility3();
void facility4();
}
//具體實現(xiàn)角色就是要將實現(xiàn)角色提供的接口實現(xiàn)
//并完成一定的功能
//這里省略了
class Implementation1 implements Implementation {
......
}
class Implementation2 implements Implementation {
......
}
......
在上面的程序中還體現(xiàn)出一點特色:就是不僅實現(xiàn)部分和抽象部分所提供的接口可以完全不一樣;而且實現(xiàn)部分內部、抽象部分內部的接口也完全可以不一樣。但是實現(xiàn)部分要提供類似的功能才行。
四、詳細代碼實現(xiàn):
在這里,我用了一個具體的例子:
現(xiàn)在我要畫畫,要畫矩形(Rectangle)和三角形(Triangle)兩種形狀的形狀(Shape),但是我又要畫實線(SolidLine)和虛線(DotLine)兩種線條(Line)。
這樣,我們就可以把形狀看成抽象化,把線條看成實現(xiàn)化;矩形和三角形就是修正抽象化,實線和虛線就是具體實現(xiàn)化。
JAVA:
Shape.java:
// 抽象化角色
package abstraction;
import implementation.Line;
public class Shape {
protected Line line;
protected int x1;
protected int y1;
protected int x2;
protected int y2;
public Shape(){}
public Shape(Line line,int x1, int y1, int x2, int y2){
this.line = line;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public void show(){
}
public int calculateArea(){
return 0;
}
public int calculatePerimeter(){
return 0;
}
}
Rectangle.java:
// 修正抽象化角色
package abstraction;
import implementation.Line;
public class Rectangle extends Shape {
public Rectangle(Line line,int x1, int y1, int x2, int y2){
super(line, x1, y1, x2, y2);
}
public void show(){
System.out.println("This is an Rectangle!");
line.draw(x1, y1, x2, y2);
}
public int calculateArea(){
return Math.abs((x2 - x1)*(y2 - y1));
}
public int calculatePerimeter(){
return 2*(Math.abs(x2 - x1) + Math.abs(y2 - y1));
}
}
Triangle.java:
// 修正抽象化角色
package abstraction;
import implementation.Line;
public class Triangle extends Shape {
public Triangle(Line line,int x1, int y1, int x2, int y2){
super(line, x1, y1, x2, y2);
}
public void show(){
System.out.println("This is an Triangle!");
line.draw(x1, y1, x2, y2);
}
public int calculateArea(){
return Math.abs((x2 - x1)*(y2 - y1))/2;
}
public int calculatePerimeter(){
int a = Math.abs(x2 - x1);
int b = Math.abs(y2 - y1);
int c = (int)Math.sqrt(a*a + b*b);
return a + b + c;
}
}
Line.java:
// 實現(xiàn)化角色
package implementation;
public class Line {
protected int x1;
protected int y1;
protected int x2;
protected int y2;
public void draw(int x1, int y1, int x2, int y2){
}
}
DotLine.java:
// 具體實現(xiàn)化角色
package implementation;
public class DotLine extends Line {
protected int x1;
protected int y1;
protected int x2;
protected int y2;
public void draw(int x1, int y1, int x2, int y2){
System.out.println("drawSolidLine:"+x1+","+y1+","+x2+","+y2);
}
}
SolidLine.java:
// 具體實現(xiàn)化角色
package implementation;
public class SolidLine extends Line {
protected int x1;
protected int y1;
protected int x2;
protected int y2;
public void draw(int x1, int y1, int x2, int y2){
System.out.println("drawDotLine:"+x1+","+y1+","+x2+","+y2);
}
}
mainDraw.java:
// 實現(xiàn)
import abstraction.*;
import implementation.*;
public class mainDraw {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int x1=0, y1=0, x2=1, y2=1;
Line solidLine = new SolidLine();
Line dotLine = new DotLine();
Shape solidLineRectangle = new Rectangle(solidLine,x1, y1, x2, y2);
Shape dotLineRectangle = new Rectangle(dotLine,x1, y1, x2, y2);
Shape solidLineTriangle = new Triangle(solidLine,x1, y1, x2, y2);
Shape dotLineTriangle = new Triangle(dotLine,x1, y1, x2, y2);
System.out.println("########################");
System.out.println("solidLineRectangle:");
solidLineRectangle.show();
System.out.println("area:"+solidLineRectangle.calculateArea());
System.out.println("perimeter:"+solidLineRectangle.calculatePerimeter());
System.out.println("########################");
System.out.println("dotLineRectangle:");
dotLineRectangle.show();
System.out.println("area:"+dotLineRectangle.calculateArea());
System.out.println("perimeter:"+dotLineRectangle.calculatePerimeter());
System.out.println("########################");
System.out.println("solidLineTriangle:");
solidLineTriangle.show();
System.out.println("area:"+solidLineTriangle.calculateArea());
System.out.println("perimeter:"+solidLineTriangle.calculatePerimeter());
System.out.println("########################");
System.out.println("dotLineTriangle:");
dotLineTriangle.show();
System.out.println("area:"+dotLineTriangle.calculateArea());
System.out.println("perimeter:"+dotLineTriangle.calculatePerimeter());
}
}
輸出結果:
########################
solidLineRectangle:
This is an Rectangle!
drawDotLine:0,0,1,1
area:1
perimeter:4
########################
dotLineRectangle:
This is an Rectangle!
drawSolidLine:0,0,1,1
area:1
perimeter:4
########################
solidLineTriangle:
This is an Triangle!
drawDotLine:0,0,1,1
area:0
perimeter:3
########################
dotLineTriangle:
This is an Triangle!
drawSolidLine:0,0,1,1
area:0
perimeter:3
C++:
shape.h(定義在include包中):
// 抽象化角色
#ifndef SHAPE_H_
#define SHAPE_H_
#include "lines.h"
#include <iostream>
using namespace std;
class Shape{
public:
Shape(){}
Shape(Line &line,int x1, int y1, int x2, int y2){
this->line = &line;
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
}
virtual void show() = 0;
virtual int calculateArea() = 0;
virtual int calculatePerimeter() = 0;
virtual ~Shape(){}
protected:
Line* line;
int x1, y1, x2, y2;
};
class Rectangle : public Shape{
public:
Rectangle(Line &line,int x1, int y1, int x2, int y2);
int calculateArea();
int calculatePerimeter();
void show();
virtual ~Rectangle(){}
protected:
int x1, y1, x2, y2;
};
class Triangle : public Shape {
public:
Triangle(Line &line,int x1, int y1, int x2, int y2);
void show();
int calculateArea();
int calculatePerimeter();
private:
int x1, y1, x2, y2;
};
#endif
line.h(定義在include包中):
// 實現(xiàn)化角色
#ifndef LINES_H_
#define LINES_H_
class Line{
public:
virtual void draw(int x1, int y1, int x2, int y2) = 0;
virtual ~Line(){};
};
class SolidLine:public Line{
public:
void draw(int x1, int y1, int x2, int y2);
virtual ~SolidLine(){};
};
class DotLine:public Line{
public:
void draw(int x1, int y1, int x2, int y2);
virtual ~DotLine(){};
};
#endif /* LINES_H_ */
Rectangle.cpp:
// 修正實現(xiàn)角色
#include "../include/shape.h"
#include <stdlib.h>
Rectangle::Rectangle(Line &line,int x1, int y1, int x2, int y2){
this->line = &line;
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
}
int Rectangle::calculateArea(){
return abs((x2 - x1)*(y2 - y1));
}
int Rectangle::calculatePerimeter(){
return 2*(abs(x2 - x1) + abs(y2 - y1));
}
void Rectangle::show(){
cout << "Rectangle" << endl;
line->draw(x1, y1, x1, y2);
}
Triangle.cpp:
// 修正實現(xiàn)角色
#include "../include/shape.h"
#include <stdlib.h>
#include <math.h>
Triangle::Triangle(Line &line, int x1, int y1, int x2, int y2){
this->line = &line;
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
}
int Triangle::calculateArea(){
return abs((x2 - x1)*(y2 - y1))/2;
}
int Triangle::calculatePerimeter(){
int a = abs(x2 - x1);
int b = abs(y2 - y1);
int c = (int)sqrt(a*a + b*b);
return a + b + c;
}
void Triangle::show(){
cout << "Triangle" << endl;
line->draw(x1, y1, x1, y2);
}
DotLine.cpp:
// 具體實現(xiàn)化角色
#include "../include/lines.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
void DotLine::draw(int x1, int y1, int x2, int y2){
cout << "drawDotLine" << x1 << "," << y1 << "," << x2 << "," << y2 << endl;
}
SolidLine.cpp:
// 具體實現(xiàn)化角色
#include "../include/lines.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
void SolidLine::draw(int x1, int y1, int x2, int y2){
cout << "drawSolidLine" << x1 << "," << y1 << "," << x2 << "," << y2 << endl;
}
Bridge.cpp
// 實現(xiàn)
//============================================================================
// Name : Bridge.cpp
// Author : Yan Chao
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include "../include/shape.h"
#include "../include/lines.h"
int main() {
int x1=0, y1=0, x2=1, y2=1;
Line *solidLine = new SolidLine();
Line *dotLine = new DotLine();
Shape *solidLineRectangle = new Rectangle(*solidLine,x1, y1, x2, y2);
Shape *dotLineRectangle = new Rectangle(*dotLine,x1, y1, x2, y2);
Shape *solidLineTriangle = new Triangle(*solidLine,x1, y1, x2, y2);
Shape *dotLineTriangle = new Triangle(*dotLine,x1, y1, x2, y2);
cout << "solidLineRectangle:" << endl;
solidLineRectangle->show();
cout << "dotLineRectangle:" << endl;
dotLineRectangle->show();
cout << "solidLineTriangle:" << endl;
solidLineTriangle->show();
cout << "dotLineTriangle:" << endl;
dotLineTriangle->show();
return 0;
}
輸出結果:
solidLineRectangle:
Rectangle
drawSolidLine0,0,0,1
dotLineRectangle:
Rectangle
drawDotLine0,0,0,1
solidLineTriangle:
Triangle
drawSolidLine0,0,0,1
dotLineTriangle:
Triangle
drawDotLine0,0,0,1
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。