Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Applied Java™ Patterns - Stephen Stelting, Olav Maassen.pdf
Скачиваний:
204
Добавлен:
24.05.2014
Размер:
2.84 Mб
Скачать

The Mediator is often application specific and difficult to redeploy. This is hardly surprising, since the Mediator is created to encapsulate application-specific behavior so the other classes in the system remain generic. Centralizing application-specific behavior in the Mediator improves maintainability. You can reuse all other classes for other applications; you only need to rewrite the Mediator class for the new application.

Testing and debugging complex Mediator implementations can be challenging, since you must accurately test a component that consists of the Mediator and its associated objects.

The Mediator’s code can become hard to manage as the number and complexity of participants increases. A possible solution is to make the mediator a composite structure, based on a number of highly focused individual mediators. (For more information about the composite pattern, see “ Composite ” on page 157.) In this case, the Mediator consists of a central managing object associated with a number of individual service classes, each providing a specific piece of functionality.

Pattern Variants

The Mediator pattern has a number of behavioral variations:

Unidirectional communication – Some implementations allow send-only and receive-only clients for the system.

Threading – Like many behavioral patterns, the Mediator is a candidate for multithreading. If multithreaded, the Mediator object can maintain a message queue, and perform tasks like managing communications with message priority.

Configurable roles – In this variant, clients define a role (which could possibly be changed as the system runs) that would define messaging requirements. Although complex to implement, defining participants in terms of roles can lead to a more generic Mediator, and one that can be redeployed to other systems.

Client pull – A Mediator can store detailed messages and send only a general notification to clients. Clients can then request detailed information about an event if required.

Related Patterns

Related patterns include the following:

Observer (page 94) – This pattern is often used to manage communication between the Client and Mediator when the communication is local. There is frequently only one Mediator per system, so they are sometimes coded as Singletons or as class-level resources by making their methods static.

HOPP (page 189) – Mediator patterns that run across a network can use the Half-Object Plus Protocol (HOPP) pattern to provide communication support.

Example

Note:

For a full working example of this code example, with additional supporting classes and/or a RunPattern class, see “ Mediator ” on page 395 of the “ Full Code Examples ” appendix.

In this example, a Mediator manages communication among the panels of a graphical user interface. The basic design of this GUI uses one panel to select a Contact from a list, another panel to allow editing, and a third panel to show the current state of the Contact. The Mediator interacts with each panel, calling the appropriate methods to keep each part of the GUI up to date.

The class MediatorGui creates the main window and the three panels for the application. It also creates a mediator and matches it with the three child panels.

Example 2.25 MediatorGui.java

1.import java.awt.Container;

2.import java.awt.event.WindowEvent;

3.import java.awt.event.WindowAdapter;

4.import javax.swing.BoxLayout;

59

5.import javax.swing.JButton;

6.import javax.swing.JFrame;

7.import javax.swing.JPanel;

8.public class MediatorGui {

9.private ContactMediator mediator;

11. public void setContactMediator(ContactMediator newMediator){ mediator = newMediator; }

12.

13.public void createGui(){

14.JFrame mainFrame = new JFrame("Mediator example");

15.Container content = mainFrame.getContentPane();

16.content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

17.ContactSelectorPanel select = new ContactSelectorPanel(mediator);

18.ContactDisplayPanel display = new ContactDisplayPanel(mediator);

19.ContactEditorPanel edit = new ContactEditorPanel(mediator);

20.content.add(select);

21.content.add(display);

22.content.add(edit);

23.mediator.setContactSelectorPanel(select);

24.mediator.setContactDisplayPanel(display);

25.mediator.setContactEditorPanel(edit);

26.mainFrame.addWindowListener(new WindowCloseManager());

27.mainFrame.pack();

28.mainFrame.setVisible(true);

29.}

30.private class WindowCloseManager extends WindowAdapter{

31.public void windowClosing(WindowEvent evt){

32. System.exit(0);

33.}

34.}

35.}

36.

37.

The simplest of the GUI panels is the ContactDisplayPanel. It has a method called contactChanged that updates its display region with the values of the Contact argument.

Example 2.26 ContactDisplayPanel.java

1.import java.awt.BorderLayout;

2.import javax.swing.JPanel;

3.import javax.swing.JScrollPane;

4.import javax.swing.JTextArea;

5.public class ContactDisplayPanel extends JPanel{

6.private ContactMediator mediator;

7.private JTextArea displayRegion;

8.

9.public ContactDisplayPanel(){

10.createGui();

11.}

12.public ContactDisplayPanel(ContactMediator newMediator){

13.setContactMediator(newMediator);

14.createGui();

15.}

16.public void createGui(){

17.setLayout(new BorderLayout());

18.displayRegion = new JTextArea(10, 40);

19.displayRegion.setEditable(false);

20.add(new JScrollPane(displayRegion));

21.}

22.public void contactChanged(Contact contact){

23.displayRegion.setText(

24. "Contact\n\tName: " + contact.getFirstName() +

25. " " + contact.getLastName() + "\n\tTitle: " +

26. contact.getTitle() + "\n\tOrganization: " +

27. contact.getOrganization());

28.}

29.public void setContactMediator(ContactMediator newMediator){

30.mediator = newMediator;

31.}

32.}

ContactSelectorPanel allows the user to choose a Contact for display and edit in the MediatorGui.

Example 2.27 ContactSelectorPanel.java

1. import java.awt.event.ActionEvent;

60

2.import java.awt.event.ActionListener;

3.import javax.swing.JComboBox;

4.import javax.swing.JPanel;

5.

6.public class ContactSelectorPanel extends JPanel implements ActionListener{

7.private ContactMediator mediator;

8.private JComboBox selector;

9.

10.public ContactSelectorPanel(){

11.createGui();

12.}

13.public ContactSelectorPanel(ContactMediator newMediator){

14.setContactMediator(newMediator);

15.createGui();

16.}

17.

18.public void createGui(){

19.selector = new JComboBox(mediator.getAllContacts());

20.selector.addActionListener(this);

21.add(selector);

22.}

23.

24.public void actionPerformed(ActionEvent evt){

25.mediator.selectContact((Contact)selector.getSelectedItem());

26.}

27.public void addContact(Contact contact){

28.selector.addItem(contact);

29.selector.setSelectedItem(contact);

30.}

31.public void setContactMediator(ContactMediator newMediator){

32.mediator = newMediator;

33.}

34.}

The ContactEditorPanel provides an editing interface for the currently selected Contact. It has buttons that allow a user to add or update a Contact.

Example 2.28 ContactEditorPanel.java

 

Y

1.

import java.awt.BorderLayout;

 

 

2.

import java.awt.GridLayout;

 

 

L

3.

import java.awt.event.ActionEvent;

F

4.

import java.awt.event.ActionListener;

M

5.

import javax.swing.JButton;

 

 

 

A

6.

import javax.swing.JLabel;

 

E

 

7.

import javax.swing.JPanel;

 

8.

import javax.swing.JTextField;T

 

 

9.

public class ContactEditorPanel extends JPanel implements ActionListener{

10.

private ContactMediator mediator;

 

11.

private JTextField firstName, lastName, title, organization;

12.

private JButton create, update;

 

13.

 

 

 

 

14.public ContactEditorPanel(){

15.createGui();

16.}

17.public ContactEditorPanel(ContactMediator newMediator){

18.setContactMediator(newMediator);

19.createGui();

20.}

21.public void createGui(){

22.setLayout(new BorderLayout());

23.

24.JPanel editor = new JPanel();

25.editor.setLayout(new GridLayout(4, 2));

26.editor.add(new JLabel("First Name:"));

27.firstName = new JTextField(20);

28.editor.add(firstName);

29.editor.add(new JLabel("Last Name:"));

30.lastName = new JTextField(20);

31.editor.add(lastName);

32.editor.add(new JLabel("Title:"));

33.title = new JTextField(20);

34.editor.add(title);

35.editor.add(new

36.organization = new

37.editor.add(organization);TEAM FLY PRESENTS

38.add(editor, BorderLayout.CENTER);

61

39.

40.JPanel control = new JPanel();

41.create = new JButton("Create Contact");

42.update = new JButton("Update Contact");

43.create.addActionListener(this);

44.update.addActionListener(this);

45.control.add(create);

46.control.add(update);

47.add(control, BorderLayout.SOUTH);

48.}

49.public void actionPerformed(ActionEvent evt){

50.Object source = evt.getSource();

51.if (source == create){

52. createContact();

53.}

54.else if (source == update){

55. updateContact();

56.}

57.}

59.public void createContact(){

60.mediator.createContact(firstName.getText(), lastName.getText(),

61. title.getText(), organization.getText());

62.}

63.public void updateContact(){

64.mediator.updateContact(firstName.getText(), lastName.getText(),

65. title.getText(), organization.getText());

66. }

67.

68.public void setContactFields(Contact contact){

69.firstName.setText(contact.getFirstName());

70.lastName.setText(contact.getLastName());

71.title.setText(contact.getTitle());

72.organization.setText(contact.getOrganization());

73.}

74.public void setContactMediator(ContactMediator newMediator){

75.mediator = newMediator;

76.}

77.}

The ContactMediator interface defines set methods for each of the GUI components, and for the business

methods createContact, updateContact, selectContact and getAllContacts.

Example 2.29 ContactMediator.java

1.public interface ContactMediator{

2.public void setContactDisplayPanel(ContactDisplayPanel displayPanel);

3.public void setContactEditorPanel(ContactEditorPanel editorPanel);

4.public void setContactSelectorPanel(ContactSelectorPanel selectorPanel);

5.public void createContact(String firstName, String lastName, String title, String

organization);

6.public void updateContact(String firstName, String lastName, String title, String

organization);

7.public Contact [] getAllContacts();

8.public void selectContact(Contact contact);

9.}

ContactMediatorImpl is the implementer of ContactMediator. It maintains a collection of Contacts, and methods that notify the panels of changes within the GUI.

Example 2.30 ContactMediatorImpl.java

1.import java.util.ArrayList;

2.public class ContactMediatorImpl implements ContactMediator{

3.private ContactDisplayPanel display;

4.private ContactEditorPanel editor;

5.private ContactSelectorPanel selector;

6.private ArrayList contacts = new ArrayList();

7.private int contactIndex;

8.

9.public void setContactDisplayPanel(ContactDisplayPanel displayPanel){

10.display = displayPanel;

11.}

12.public void setContactEditorPanel(ContactEditorPanel editorPanel){

13.editor = editorPanel;

14.}

15.public void setContactSelectorPanel(ContactSelectorPanel selectorPanel){

62