请教:什么是Bridge模式?

tranchi 2006-12-16 07:47:20
设想并概要地描述两种可使用该模式的不同应用要求,最好能再给出相应的设计类图
...全文
1417 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
逸学堂 2007-01-29
  • 打赏
  • 举报
回复
com的应用就是一个典型的bridge模式
FingerStyle 2007-01-29
  • 打赏
  • 举报
回复
<设计模式可复用面向对象软件的基础>...
FingerStyle 2007-01-29
  • 打赏
  • 举报
回复
建议看 Gof的设计模式 , 很经典...
blueoceanli 2007-01-29
  • 打赏
  • 举报
回复
看ENGLISH
jixingzhong 2006-12-23
  • 打赏
  • 举报
回复
下载 DesignPatterns 一书
jixingzhong 2006-12-23
  • 打赏
  • 举报
回复
The following C++ code implements the Window/WindowImp example from the Motivation section. The Window class defines the window abstraction for client applications:

class Window {
public:
Window(View* contents);

// requests handled by window
virtual void DrawContents();

virtual void Open();
virtual void Close();
virtual void Iconify();
virtual void Deiconify();

// requests forwarded to implementation
virtual void SetOrigin(const Point& at);
virtual void SetExtent(const Point& extent);
virtual void Raise();
virtual void Lower();

virtual void DrawLine(const Point&, const Point&);
virtual void DrawRect(const Point&, const Point&);
virtual void DrawPolygon(const Point[], int n);
virtual void DrawText(const char*, const Point&);

protected:
WindowImp* GetWindowImp();
View* GetView();

private:
WindowImp* _imp;
View* _contents; // the window's contents
};

Window maintains a reference to a WindowImp, the abstract class that declares an interface to the underlying windowing system.

class WindowImp {
public:
virtual void ImpTop() = 0;
virtual void ImpBottom() = 0;
virtual void ImpSetExtent(const Point&) = 0;
virtual void ImpSetOrigin(const Point&) = 0;

virtual void DeviceRect(Coord, Coord, Coord, Coord) = 0;
virtual void DeviceText(const char*, Coord, Coord) = 0;
virtual void DeviceBitmap(const char*, Coord, Coord) = 0;
// lots more functions for drawing on windows...
protected:
WindowImp();
};

Subclasses of Window define the different kinds of windows the application might use, such as application windows, icons, transient windows for dialogs, floating palettes of tools, and so on.

For example, ApplicationWindow will implement DrawContents to draw the View instance it stores:

class ApplicationWindow : public Window {
public:
// ...
virtual void DrawContents();
};

void ApplicationWindow::DrawContents () {
GetView()->DrawOn(this);
}

IconWindow stores the name of a bitmap for the icon it displays...

class IconWindow : public Window {
public:
// ...
virtual void DrawContents();
private:
const char* _bitmapName;
};

...and it implements DrawContents to draw the bitmap on the window:

void IconWindow::DrawContents() {
WindowImp* imp = GetWindowImp();
if (imp != 0) {
imp->DeviceBitmap(_bitmapName, 0.0, 0.0);
}
}

Many other variations of Window are possible. A TransientWindow may need to communicate with the window that created it during the dialog; hence it keeps a reference to that window. A PaletteWindow always floats above other windows. An IconDockWindow holds IconWindows and arranges them neatly.

Window operations are defined in terms of the WindowImp interface. For example, DrawRect extracts four coordinates from its two Point parameters before calling the WindowImp operation that draws the rectangle in the window:

void Window::DrawRect (const Point& p1, const Point& p2) {
WindowImp* imp = GetWindowImp();
imp->DeviceRect(p1.X(), p1.Y(), p2.X(), p2.Y());
}

Concrete subclasses of WindowImp support different window systems. The XWindowImp subclass supports the X Window System:

class XWindowImp : public WindowImp {
public:
XWindowImp();

virtual void DeviceRect(Coord, Coord, Coord, Coord);
// remainder of public interface...
private:
// lots of X window system-specific state, including:
Display* _dpy;
Drawable _winid; // window id
GC _gc; // window graphic context
};

For Presentation Manager (PM), we define a PMWindowImp class:

class PMWindowImp : public WindowImp {
public:
PMWindowImp();
virtual void DeviceRect(Coord, Coord, Coord, Coord);

// remainder of public interface...
private:
// lots of PM window system-specific state, including:
HPS _hps;
};

These subclasses implement WindowImp operations in terms of window system primitives. For example, DeviceRect is implemented for X as follows:

void XWindowImp::DeviceRect (
Coord x0, Coord y0, Coord x1, Coord y1
) {
int x = round(min(x0, x1));
int y = round(min(y0, y1));
int w = round(abs(x0 - x1));
int h = round(abs(y0 - y1));
XDrawRectangle(_dpy, _winid, _gc, x, y, w, h);
}

The PM implementation might look like this:

void PMWindowImp::DeviceRect (
Coord x0, Coord y0, Coord x1, Coord y1
) {
Coord left = min(x0, x1);
Coord right = max(x0, x1);
Coord bottom = min(y0, y1);
Coord top = max(y0, y1);

PPOINTL point[4];

point[0].x = left; point[0].y = top;
point[1].x = right; point[1].y = top;
point[2].x = right; point[2].y = bottom;
point[3].x = left; point[3].y = bottom;

if (
(GpiBeginPath(_hps, 1L) == false) ||
(GpiSetCurrentPosition(_hps, &point[3]) == false) ||
(GpiPolyLine(_hps, 4L, point) == GPI_ERROR) ||
(GpiEndPath(_hps) == false)
) {
// report error

} else {
GpiStrokePath(_hps, 1L, 0L);
}
}

How does a window obtain an instance of the right WindowImp subclass? We'll assume Window has that responsibility in this example. Its GetWindowImp operation gets the right instance from an abstract factory (see Abstract Factory (87)) that effectively encapsulates all window system specifics.

WindowImp* Window::GetWindowImp () {
if (_imp == 0) {
_imp = WindowSystemFactory::Instance()->MakeWindowImp();
}
return _imp;
}

WindowSystemFactory::Instance() returns an abstract factory that manufactures all window system-specific objects. For simplicity, we've made it a Singleton (127) and have let the Window class access the factory directly.

jixingzhong 2006-12-23
  • 打赏
  • 举报
回复
结构型模式
  6、ADAPTER—在朋友聚会上碰到了一个美女Sarah,从香港来的,可我不会说粤语,她不会说普通话,只好求助于我的朋友kent了,他作为我和Sarah之间的Adapter,让我和Sarah可以相互交谈了(也不知道他会不会耍我)
  
  适配器(变压器)模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。
  
  7、BRIDGE—早上碰到MM,要说早上好,晚上碰到MM,要说晚上好;碰到MM穿了件新衣服,要说你的衣服好漂亮哦,碰到MM新做的发型,要说你的头发好漂亮哦。不要问我“早上碰到MM新做了个发型怎么说”这种问题,自己用BRIDGE组合一下不就行了
  
  桥梁模式:将抽象化与实现化脱耦,使得二者可以独立的变化,也就是说将他们之间的强关联变成弱关联,也就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以独立的变化。
  
  8、COMPOSITE—Mary今天过生日。“我过生日,你要送我一件礼物。”“嗯,好吧,去商店,你自己挑。”“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。”“喂,买了三件了呀,我只答应送一件礼物的哦。”“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻烦你包起来。”“……”,MM都会用Composite模式了,你会了没有?
  
  合成模式:合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。
  
  9、DECORATOR—Mary过完轮到Sarly过生日,还是不要叫她自己挑了,不然这个月伙食费肯定玩完,拿出我去年在华山顶上照的照片,在背面写上“最好的的礼物,就是爱你的Fita”,再到街上礼品店买了个像框(卖礼品的MM也很漂亮哦),再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来……,我们都是Decorator,最终都在修饰我这个人呀,怎么样,看懂了吗?
  
  装饰模式:装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。动态给一个对象增加功能,这些功能可以再动态的撤消。增加由一些基本功能的排列组合而产生的非常大量的功能。
  
  10、FACADE—我有一个专业的Nikon相机,我就喜欢自己手动调光圈、快门,这样照出来的照片才专业,但MM可不懂这些,教了半天也不会。幸好相机有Facade设计模式,把相机调整到自动档,只要对准目标按快门就行了,一切由相机自动调整,这样MM也可以用这个相机给我拍张照片了。
  
  门面模式:外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。每一个子系统只有一个门面类,而且此门面类只有一个实例,也就是说它是一个单例模式。但整个系统可以有多个门面类。
  
  11、FLYWEIGHT—每天跟MM发短信,手指都累死了,最近买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了,再不用一个字一个字敲了。共享的句子就是Flyweight,MM的名字就是提取出来的外部特征,根据上下文情况使用。
  
  享元模式:FLYWEIGHT在拳击比赛中指最轻量级。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。
  
  12、PROXY—跟MM在网上聊天,一开头总是“hi,你好”,“你从哪儿来呀?”“你多大了?”“身高多少呀?”这些话,真烦人,写个程序做为我的Proxy吧,凡是接收到这些话都设置好了自动的回答,接收到其他的话时再通知我回答,怎么样,酷吧。
  
  代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况下,客户不想或者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,这时候代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色代为创建并传入。
flypiggy 2006-12-23
  • 打赏
  • 举报
回复
建议看看《设计模式精解》里面讲的很清楚,我就是在那看懂的!!!
iamcdyy 2006-12-23
  • 打赏
  • 举报
回复
谢谢,有启发
realrukawa 2006-12-18
  • 打赏
  • 举报
回复
粘贴出了点错误,懒得改了。大概意思就是这样
realrukawa 2006-12-18
  • 打赏
  • 举报
回复
Bridge模式是解决多层继承的根本原因。如果你在实现应用中一个类,需要继承两个以上的类,并且这两者之间又持有某种关系,它们两个都会有多种变化。Bridge模式是把这两个类,分解为一个抽象,一个实现,使它们两个分离,这样两种类可以独立的变化。

任何事物对象都有抽象和行为之分,例如人,人是一种抽象,人分男人和女人等;人有行为,行为也有各种具体表现,所以,“人”与“人的行为”两个概念也反映了抽象和行为之分。

在这里举一个例子:就好象Jackill和You是两个不同的人,喜欢和不喜欢分别是两种不同的行为,倘若依照以前的设计,必须设计四个子类,倘若添加新的动作,则必须继续继承出新的类来。


class PersonImp
{
public:
virtual ~PersonImp(){};
virtual void Love()=0{};
protected:
PersonImp(){};
};

class ImpA:public PersonImp
{
public:
ImpA(){};
~ImpA(){};
virtual void Love(){cout<<"Love"<
};
class ImpB:public PersonImp
{
public:
ImpB(){};
~ImpB(){};
virtual void Love(){cout<<"Don't Love"<
};

class Person
{
public:
virtual ~Person(){};
virtual void Love()=0{};
protected:
Person(){};
};

class Jackill:public Person
{
public:
virtual ~Jackill(){};
void Love() {m_imp->Love();};
Jackill(PersonImp* imp){m_imp=imp;cout<<"jackill"<<" ";};
private:
PersonImp* m_imp;
};

class You:public Person
{
public:
virtual ~You(){};
void Love() {m_imp->Love();};
You(PersonImp* imp){m_imp=imp;cout<<"You"<<" ";};
private:
PersonImp* m_imp;
};

void main()
{
PersonImp* imp=new ImpA();
Person* per=new Jackill(imp);
per->Love(); /*Jackill喜欢*/
PersonImp* imp2=new ImpB();
Person* per2=new You(imp2);
per2->Love(); /*You 不喜欢*/
caocheng8230 2006-12-16
  • 打赏
  • 举报
回复
infoxa.com上面有设计模式手册,上面有所有的设计模式的实现代码,UML图,非常简洁
我啃 2006-12-16
  • 打赏
  • 举报
回复
错了,是GoF
Gang of Four(四人帮)对不起其他几个大大了
我啃 2006-12-16
  • 打赏
  • 举报
回复
Erich Gamma的<Design pattern>里面应该有吧,CSDN不能贴图的
sopro 2006-12-16
  • 打赏
  • 举报
回复
GoF的《Design Pattern》里面有你想要的东西

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧