⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pat5e.htm

📁 四人帮《设计模式》一书英文版本
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<HTML><HEAD>	<TITLE>Mediator</TITLE>
<SCRIPT>
function setFocus() {	
	if ((navigator.appName != "Netscape") && (parseFloat(navigator.appVersion) == 2)) {
	return;
	} else {
	self.focus();
	}
}
</SCRIPT>
</HEAD>

<BODY   BGCOLOR         = #FFFFFF
onLoad="setFocus()";>

<A NAME="top"></A>
<A NAME="Mediator"></A>
<A NAME="intent"></A>
<H2><A HREF="#motivation"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 ALT="next: 
Motivation"></A> Intent</H2> 

<A NAME="auto1000"></A>
<P>Define an object that encapsulates how a set of objects interact.
Mediator promotes loose coupling by keeping objects from referring to
each other explicitly, and it lets you vary their interaction
independently.</P>

<A NAME="motivation"></A>
<H2><A HREF="#applicability"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 
ALT="next: Applicability"></A> Motivation</H2> 

<A NAME="auto1001"></A>
<P>Object-oriented design encourages the distribution of behavior
among objects.  Such distribution can result in an object structure
with many connections between objects; in the worst case, every object
ends up knowing about every other.</P>

<A NAME="auto1002"></A>
<P>Though partitioning a system into many objects generally enhances
reusability, proliferating interconnections tend to reduce it again.
Lots of interconnections make it less likely that an object can work
without the support of others&#151;the system acts as though it were
monolithic. Moreover, it can be difficult to change the system's
behavior in any significant way, since behavior is distributed among
many objects. As a result, you may be forced to define many subclasses
to customize the system's behavior.</P>

<A NAME="auto1003"></A>
<P>As an example, consider the implementation of dialog boxes in a
graphical user interface. A dialog box uses a window to present a
collection of widgets such as buttons, menus, and entry fields, as
shown here:</P>

<P ALIGN=CENTER><IMG SRC="fontc047.gif" tppabs="http://ultra/development/DesignPatterns/hires/Pictures/fontc047.gif"></P>

<A NAME="listbox"></A>
<P>Often there are dependencies between the widgets in the dialog. For
example, a button gets disabled when a certain entry field is empty.
Selecting an entry in a list of choices called a <STRONG>list box</STRONG>
might change the contents of an entry field. Conversely, typing text
into the entry field might automatically select one or more
corresponding entries in the list box. Once text appears in the entry
field, other buttons may become enabled that let the user do something
with the text, such as changing or deleting the thing to which it refers.</P>

<A NAME="auto1004"></A>
<P>Different dialog boxes will have different dependencies between
widgets.  So even though dialogs display the same kinds of widgets,
they can't simply reuse stock widget classes; they have to be
customized to reflect dialog-specific dependencies. Customizing them
individually by subclassing will be tedious, since many classes are
involved.</P>

<A NAME="def-media"></A>
<P>You can avoid these problems by encapsulating collective behavior in a
separate <STRONG>mediator</STRONG> object.  A mediator is responsible for
controlling and coordinating the interactions of a group of objects.
The mediator serves as an intermediary that keeps objects in the group
from referring to each other explicitly.  The objects only know the
mediator, thereby reducing the number of interconnections.</P>

<A NAME="fontdlogdirector"></A>
<P>For example, <STRONG>FontDialogDirector</STRONG> can be the mediator
between the widgets in a dialog box. A FontDialogDirector object knows
the widgets in a dialog and coordinates their interaction. It acts as
a hub of communication for widgets:</P>

<A NAME="mediator-eg-obj"></A>
<P ALIGN=CENTER><IMG SRC="media033.gif" tppabs="http://ultra/development/DesignPatterns/hires/Pictures/media033.gif"></P>

<A NAME="auto1005"></A>
<P>The following interaction diagram illustrates how the objects cooperate to
handle a change in a list box's selection:</P>

<A NAME="mediator-id"></A>
<P ALIGN=CENTER><IMG SRC="media031.gif" tppabs="http://ultra/development/DesignPatterns/hires/Pictures/media031.gif"></P>

<A NAME="auto1006"></A>
<P>Here's the succession of events by which a list box's selection passes
to an entry field:</P>

<OL>

<A NAME="auto1007"></A>
<LI>The list box tells its director that it's changed.</LI>
<A NAME="auto1008"></A>
<P></P>
<A NAME="auto1009"></A>
<LI>The director gets the selection from the list box.</LI>
<A NAME="auto1010"></A>
<P></P>
<A NAME="auto1011"></A>
<LI>The director passes the selection to the entry field.</LI>
<A NAME="auto1012"></A>
<P></P>
<A NAME="auto1013"></A>
<LI>Now that the entry field contains some text, the director
enables button(s) for initiating an action (e.g., "demibold," "oblique").</LI>

</OL>

<A NAME="auto1014"></A>
<P>Note how the director mediates between the list box and the entry field.
Widgets communicate with each other only indirectly, through the
director. They don't have to know about each other; all they know is the
director. Furthermore, because the behavior is localized in one class,
it can be changed or replaced by extending or replacing that class.</P>

<A NAME="auto1015"></A>
<P>Here's how the FontDialogDirector abstraction can be integrated into a
class library:</P>

<A NAME="275c"></A>
<P ALIGN=CENTER><IMG SRC="media034.gif" tppabs="http://ultra/development/DesignPatterns/hires/Pictures/media034.gif"></P>

<A NAME="auto1016"></A>
<P>DialogDirector is an abstract class that defines the overall behavior of
a dialog. Clients call the ShowDialog operation to display the dialog on
the screen. CreateWidgets is an abstract operation for creating the
widgets of a dialog. WidgetChanged is another abstract operation;
widgets call it to inform their director that they have changed.
DialogDirector subclasses override CreateWidgets to create the proper
widgets, and they override WidgetChanged to handle the changes.</P>

<A NAME="applicability"></A>
<H2><A HREF="#structure"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 ALT="next: 
Structure"></A> Applicability</H2> 

<A NAME="auto1017"></A>
<P>Use the Mediator pattern when</P>

<UL>

<A NAME="auto1018"></A>
<LI>a set of objects communicate in well-defined but complex ways.  The
resulting interdependencies are unstructured and difficult to
understand.</LI>
<A NAME="auto1019"></A>
<P></P>
<A NAME="auto1020"></A>
<LI>reusing an object is difficult because it refers to and communicates
with many other objects.</LI>
<A NAME="auto1021"></A>
<P></P>
<A NAME="auto1022"></A>
<LI>a behavior that's distributed between several classes should be
customizable without a lot of subclassing.</LI>

</UL>

<A NAME="structure"></A>
<H2><A HREF="#participants"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 ALT="next: 
Participants"></A> Structure</H2> 

<P ALIGN=CENTER><IMG SRC="mediator.gif" tppabs="http://ultra/development/DesignPatterns/hires/Pictures/mediator.gif"></P>

<A NAME="auto1023"></A>
<P>A typical object structure might look like this:</P>

<P ALIGN=CENTER><IMG SRC="media030.gif" tppabs="http://ultra/development/DesignPatterns/hires/Pictures/media030.gif"></P>

<A NAME="participants"></A>
<H2><A HREF="#collaborations"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 
ALT="next: Collaborations"></A> Participants</H2>

<UL>

<A NAME="auto1024"></A>
<LI><B>Mediator</B> (DialogDirector)</LI>

<A NAME="auto1025"></A>
<P></P>

    <UL>

    <A NAME="auto1026"></A>
<LI>defines an interface for communicating with Colleague objects.</LI>

    </UL>

<A NAME="auto1027"></A>
<P></P>

<A NAME="auto1028"></A>
<LI><B>ConcreteMediator</B> (FontDialogDirector)

<A NAME="auto1029"></A>
<P></P>

    <UL>

    <A NAME="auto1030"></A>
<LI>implements cooperative behavior by coordinating Colleague objects.</LI>

    <A NAME="auto1031"></A>
<P><!-- extra space --></P>

    <A NAME="auto1032"></A>
<LI>knows and maintains its colleagues.</LI>

    </UL>

<A NAME="auto1033"></A>
<P></P>

<A NAME="auto1034"></A>
<LI><B>Colleague classes</B> (ListBox, EntryField)

<A NAME="auto1035"></A>
<P></P>

    <UL>

    <A NAME="auto1036"></A>
<LI>each Colleague class knows its Mediator object.</LI>

    <A NAME="auto1037"></A>
<P><!-- extra space --></P>

    <A NAME="auto1038"></A>
<LI>each colleague communicates with its mediator whenever it would have
    otherwise communicated with another colleague.</LI>

    </UL>

</UL>

<A NAME="collaborations"></A>
<H2><A HREF="#consequences"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 
ALT="next: Consequences"></A> Collaborations</H2>

<UL>

<A NAME="auto1039"></A>
<LI>Colleagues send and receive requests from a Mediator object. The
mediator implements the cooperative behavior by routing requests
between the appropriate colleague(s).</LI>

</UL>

<A NAME="consequences"></A>
<H2><A HREF="#implementation"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 
ALT="next: Implementation"></A> Consequences</H2> 

<A NAME="auto1040"></A>
<P>The Mediator pattern has the following benefits and drawbacks:</P>

<OL>

<A NAME="auto1041"></A>
<LI><EM>It limits subclassing.</EM>
A mediator localizes behavior that otherwise would be distributed among
several objects. Changing this behavior requires subclassing Mediator
only; Colleague classes can be reused as is.</LI>
<A NAME="auto1042"></A>
<P></P>
<A NAME="auto1043"></A>
<LI><EM>It decouples colleagues.</EM>
A mediator promotes loose coupling between colleagues.  You can vary
and reuse Colleague and Mediator classes independently.</LI>
<A NAME="auto1044"></A>
<P></P>
<A NAME="auto1045"></A>
<LI><EM>It simplifies object protocols.</EM>
A mediator replaces many-to-many interactions with one-to-many
interactions between the mediator and its colleagues.  One-to-many
relationships are easier to understand, maintain, and extend.</LI>
<A NAME="auto1046"></A>
<P></P>
<A NAME="auto1047"></A>
<LI><EM>It abstracts how objects cooperate.</EM>
Making mediation an independent concept and encapsulating it in an
object lets you focus on how objects interact apart from their
individual behavior. That can help clarify how objects interact in a
system.</LI>
<A NAME="auto1048"></A>
<P></P>
<A NAME="auto1049"></A>
<LI><EM>It centralizes control.</EM>
The Mediator pattern trades complexity of interaction for complexity in
the mediator. Because a mediator encapsulates protocols, it can become
more complex than any individual colleague. This can make the mediator
itself a monolith that's hard to maintain.</LI>

</OL>

<A NAME="implementation"></A>
<H2><A HREF="#samplecode"><IMG SRC="down3.gif" tppabs="http://ultra/development/DesignPatterns/hires/gifsb/down3.gif" BORDER=0 ALT="next: 
Sample Code"></A> Implementation</H2> 

<A NAME="auto1050"></A>
<P>The following implementation issues are relevant to the Mediator
pattern:</P>

<OL>

<A NAME="media-omit-abs"></A>
<LI><EM>Omitting the abstract Mediator class.</EM>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -