Chapter 10 mediator
Download
1 / 153

Chapter 10 Mediator - PowerPoint PPT Presentation


  • 66 Views
  • Uploaded on

Chapter 10 Mediator. Summary prepared by Kirk Scott. Athena From Wikipedia, the free encyclopedia.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Chapter 10 Mediator' - isi


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Chapter 10 mediator

Chapter 10Mediator

Summary prepared by Kirk Scott


Athena from wikipedia the free encyclopedia
AthenaFrom Wikipedia, the free encyclopedia

  • :"Athene", "Athina", and "Pallas Athena" all redirect here. For other uses, see Athena (disambiguation), Athene (disambiguation), Athina (disambiguation) and Pallas Athena (disambiguation)


  • In Greek religion and mythology, Athena or Athene (pron.: /əˈθiːnə/ or /əˈθiːniː/; Attic: Ἀθηνᾶ, Athēnā or Ἀθηναία, Athēnaia; Epic: Ἀθηναίη, Athēnaiē; Ionic: Ἀθήνη, Athēnē; Doric: Ἀθάνα, Athānā), also referred to as Pallas Athena/Athene (pron.: /ˈpæləs/; Παλλὰς Ἀθηνᾶ; Παλλὰς Ἀθήνη), is the goddess of wisdom, courage, inspiration, civilization, law and justice, just warfare, mathematics, strength, strategy, the arts, crafts, and skill. Minerva is the Roman goddessidentified with Athena.[4]


  • Athena is also a shrewd companion of heroes and is the goddess of heroic endeavour. She is the virgin patroness of Athens. The Athenians founded the Parthenon on the Acropolis of her namesake city, Athens (Athena Parthenos), in her honour.[4]


Athena in the art of gandhara
Athena in the art of Gandhara.


Design patterns in java chapter 10 mediator

Design Patterns in JavaChapter 10Mediator

Summary prepared by Kirk Scott


Introduction
Introduction

  • A mediator is something that stands between one base class and another

  • In object terms, the mediator object stands between one or more instances of one or more base classes

  • Instances of the base classes interact with the mediator class rather than interacting with each other directly



  • The background for mediators can be expressed in terms of responsibility

  • The general rule is that objects are responsible for themselves

  • In other words, classes should contain some well-defined, limited, and coherent data set, along with the methods needed to work with the data

  • Classes, in general, should not be heavily reliant on objects of other classes to implement needed functionality


  • On the other hand, recall the Builder pattern responsibility

  • It illustrated offloading construction responsibility/functionality into another class

  • Also recall the Proxy pattern

  • In it, the client dealt with the proxy (stand-in) rather than dealing directly with the base class


  • The Mediator pattern can be viewed as offloading/concentrating responsibility/functionality into a separate class

  • The mediator becomes responsible for the relationship between classes or the relationships between instances of those classes


  • Although conceptual in nature, the relationships are real aspects of the design

  • They can be as meaningful as the bases classes themselves

  • They canhave a life of their own

  • It turns out to make good design sense to have a separate class that is devoted to storing and maintaining the relationships


Scenario
Scenario aspects of the design

  • Consider this scenario:

  • In a group of objects, each one “is aware of” or has a reference to every other member of the group

  • First of all, note that this can be complex


  • Also note that the set of relationships itself becomes an abstraction that might be implemented as a separate class

  • Introducing a new class factors the relationship functionality out of the base classes

  • The new class concentrates responsibility for the relationships among objects and reduces their responsibility for themselves


  • The individual objects become dependent on the class that maintains the relationships

  • In the code, the individual objects relate only to the class in the middle, not with each other

  • This new class in the middle is a mediator class

  • The base objects are no longer tightly coupled with each other, but they are tightly coupled with the mediator


Book definition of the pattern
Book Definition of the Pattern maintains the relationships

  • Book definition:

  • The intent of the Mediator pattern is to define an object that encapsulates how a set of objects interact; this promotes loose coupling, keeping the objects from referring to one another explicitly, and lets you vary their interactions independently.


  • Comment mode on: maintains the relationships

  • The pattern makes the base classes more loosely coupled with each other.

  • In a sense, it does this by coupling them to a common class in the middle.

  • They are coupled to the class in the middle by virtue of the fact that the class in the middle concentrates the responsibility for maintaining the relationships


Modeling relationships
Modeling Relationships maintains the relationships

  • Keep in mind that code typically models some reality

  • In that reality, individual objects may be linked with each other

  • In the problem domain, the relationships may be as important as the objects, and exist as a truly separate concept



Concrete examples from the book
Concrete Examples from the Book choice

  • The book pursues two examples to illustrate the use of the Mediator design pattern

  • 1. The pattern can become apparent/be used when developing GUI’s with multiple parts in increasingly complex relationships

  • 2. The pattern can also become apparent when modeling the real world where objects have relationships with each other and the code needs to reflect those relationships



A classic example gui mediators
A Classic Example: GUI Mediators common one

  • The book’s first example applies the mediator pattern to a program with a graphical user interface

  • The book shows a GUI, shows some code, and shows a refactoring using the pattern

  • At the end of the book’s example, it basically comes down to this:

  • “Voila—and now you see how these things don’t interact directly with each other anymore—they interact through this other class in the design.”



  • There will be base classes for tub and machine give a preview of how it will fit together:objects

  • There will also be a base class which keeps track of these objects in the data model

  • In this case, the class which takes care of the objects will be known as a “mock database” (stay tuned)

  • You can recognize that this as equivalent to the model in an MVC design



  • There will be a mediator components

  • This will implement listening

  • This is the functionality for what happens when an action is taken in the GUI

  • You can recognize that this as equivalent to the controller in an MVC design



  • Overall in this example a controller serves as a mediator between the model and the viewrelationship between the data model and the graphical user interface representation of the state of the application has to be maintained

  • The mediator implements listening functionality

  • It stands between the GUI/client/view and the data model

  • It is responsible for maintaining the relationship


The scenario
The Scenario controller serves as a mediator between the model and the view

  • The graphical user interface for the example is shown on the overhead following the next one

  • A factory has machines in it, and the machines at any given time have a set of tubs of materials that belong to them

  • The interaction of interest is the moving of tubs from one machine to another


  • It is important to understand that at this point the book is interested in mediation between the graphical user interface and the data model in the application

  • It is apparent that there is another basic relationship in the application:

  • Which tubs are located at which machines

  • Applying mediation to that relationship will be covered in the next example


  • This is the sequence of events: interested in mediation between the graphical user interface and the data model in the application

  • In the interface, pick a source machine from the first column

  • The tubs belonging to it appear in the second column

  • Destination machines appear in the third column

  • Pick a tub in the second column and a destination machine in the third column


  • Once three things are interested in mediation between the graphical user interface and the data model in the applicationhighlighted in the interface, you can press the “Do it!” button

  • This moves the tub from the source machine to the destination machine

  • Both the GUI representation and the underlying data model in the software should be updated


Extending the development scenario
Extending the Development Scenario interested in mediation between the graphical user interface and the data model in the application

  • The authors paint out the scenario further in this way

  • An interface like this can be developed using a wizard

  • However, the wizard produces cookie-cutter code that doesn’t necessarily fit a nice design pattern


  • Using a wizard might produce a class named interested in mediation between the graphical user interface and the data model in the applicationMoveATub that is basically a monolithic application

  • The UML for this class is given on the next overhead


Refactoring the design
Refactoring the Design interested in mediation between the graphical user interface and the data model in the application

  • The book observes that the methods in the MoveATub class are a mixture of component building, event handling, and “mock database” operations

  • The desire is to refactor this design so that it is better

  • In other words, the desire is to break it into parts where the responsibilities are clearly divided

  • In the long run this will make the code easier to maintain and modify


Gui construction methods in the monolithic class
GUI Construction Methods in the Monolithic Class interested in mediation between the graphical user interface and the data model in the application

  • There are methods in MoveATub that construct GUI components

  • For example, there is a method assignButton(), which is the method which constructs the “Do it!” button

  • Its code is given on the next overhead for reference

  • Notice that it is implemented with lazy initialization


  • private interested in mediation between the graphical user interface and the data model in the applicationJButtonassignButton()

  • {

  • if(assignButton == null)

  • {

  • assignButton = new JButton(“Do it!”);

  • assignButton.setEnabled(false);

  • assignButton.addActionListener(this);

  • }

  • return assignButton;

  • }


Domain object construction in the monolithic class
Domain Object Construction in the Monolithic Class interested in mediation between the graphical user interface and the data model in the application

  • There are also methods in MoveATub that construct domain objects like lists of machines and tubs, and so on

  • In other words, the elements of the problem domain are mixed with GUI elements


Listener implementation in the monolithic class
Listener Implementation in the Monolithic Class interested in mediation between the graphical user interface and the data model in the application

  • MoveATub also implements the ActionListener and ListSelectionListener interfaces

  • In it you find methods that are related to actions, like valueChanged() and updateTubList()

  • The authors give the code for the valueChanged() method for reference

  • It is shown on the following overhead


  • public void interested in mediation between the graphical user interface and the data model in the applicationvalueChanged(ListSelectionEvent e)

  • {

  • // …

  • assignButton().setEnabled(

  • !tubList().isSelectionEmpty()

  • && !machineList().isSelectionEmpty());

  • }



Ways of implementing listening
Ways of Implementing Listening moving the event handling methods into a different class

  • How listening is implemented opens out into a somewhat broader topic

  • Think back to how listening was implemented in CSCE 202

  • The orange book’s plan was this:

  • Implement listening in a separate listener class, but make it an inner class so that it had direct access to the instance variables of the outer class


  • What we’ve just seen in the monolithic moving the event handling methods into a different classMoveATub class is that the class itself can implement the listening interface

  • Among the points this book is making is that the monolithic class has too many different kinds of things in it

  • Classes should be coherent, single-purpose, and self-contained


  • Where to put listening and how to make sure listeners have access to the things they need are important topics in Java GUI programming

  • Essentially, these topics were covered in the MVC units

  • Having a model in one or more classes and separating listening and observing into one or more classes each is the most general solution


Redesigning the application using the pattern
Redesigning the Application Using the Pattern access to the things they need are important topics in Java GUI programming

  • Challenge 10.1

  • Complete the diagram in Figure 10.3 to show a refactoring of MoveATub, introducing a separate mock database class and a mediator class to receive the events of the MoveATub GUI.


  • Comment mode on: access to the things they need are important topics in Java GUI programming

  • As usual, doing this on your own verges on the impossible

  • What, for example, does the book mean by a mock database?

  • As usual, the only practical approach is to just look at the book’s solution and try and figure out what it means


  • Solution 10.1 access to the things they need are important topics in Java GUI programming

  • Figure B.11 shows a solution.


  • What is to be gleaned from the UML diagram of the solution? access to the things they need are important topics in Java GUI programming

  • MoveATub2 now is pretty much limited to the graphical components of the application

  • NameBase is the so-called mock database

  • This is the part of the application that is problem-domain, or model oriented

  • It keeps track of the state of machines and their tubs


  • MoveATubMediator access to the things they need are important topics in Java GUI programming implements the ActionListener and ListSelectionListenerinterfaces, suggesting it’s a controller

  • It contains the actionPerformed(), valueChanged(), and updateTubList() methods

  • As its name indicates, this is the (GUI) mediator

  • When things happen in the GUI, actions are taken indirectly on the NameBase, through the mediator


  • It is also possible for the mediator to take actions on the GUI, like enabling or disabling a button

  • The authors say that the most common example of mediation is this use in GUI development

  • The mediator, in this example, stands between and implements the interaction between the GUI class/object and the NameBase class/object




A sequence diagram for the pattern
A Sequence Diagram for the Pattern relationships and arrows are not completely clear

  • The following challenge tries to illustrate the pattern by means of a sequence diagram rather than a static structure diagram

  • It shows a sequence of calls and returns from the GUI component, to the listener, to the underlying data structure


  • Challenge 10.2 relationships and arrows are not completely clear

  • “Draw a diagram that shows what happens when the user clicks the Do it! Button.

  • Show whichever objects you think are most important, and show the messages that pass between these objects.”


  • Solution 10.2 relationships and arrows are not completely clear

  • Figure B.12 shows one solution.


A last observation on the first example
A Last Observation on the First Example relationships and arrows are not completely clear

  • In general, why is it possible to do this example without observing?

  • In what way is this, at least in part, illustrated by the sequence diagram?

  • Think back to the MVC example:

  • There was a slider for input

  • There were two graphics panels and a label for output


  • The output side observed changes in the slider relationships and arrows are not completely clear

  • In this example, each of the graphical components is essentially something that has a listener

  • You pick items from the lists

  • It’s true that the list of tubs depends on which source machine is chosen, but still, each GUI component listens, because you can then select a tub out of that list



Example 2 mediators of relational integrity
Example 2: Mediators of Relational Integrity full MVC design

  • The most common use of the mediator pattern may be in GUI’s, but there are others

  • In general, in any case where there are numerous or complicated relationships between objects, it may be desirable to abstract the relationships out

  • This reduces the coupling between the base objects, encapsulating the complexity inside the mediator class that implements the relationships


  • It also has this advantage, as noted earlier: full MVC design

  • The relationships really do have an existence in a design and may be no less important than the objects

  • By abstracting the relationships out, the rules for them can be standardized and you assure yourself that all objects that participate in relationships rely on the same implementation logic



  • For the purposes of that example, the machines and tubs, or lists of machines and tubs, were simply relegated to that part of the design having to do with the business model

  • Now it is the relationships between the machines and tubs themselves that are of interest and which will be used to illustrate mediation

  • Consider the table shown on the next overhead


  • The table shows a one-to-many relationship between machines and tubs

  • Each machine can have more than one tub

  • A tub can only belong to one machine at a given time

  • As long as the tub entries in the table are unique, the table represents this reality

  • Multiple entries for the same machine in the second column allow a given machine to have more than one tub at a time



An undesirable solution to the problem
An Undesirable Solution to the Problem integrity

  • On the following overhead a UML diagram is given which shows one-to-many relationships between machine and tub objects

  • It is important to note that nothing in this diagram suggests a mechanism for enforcing the one-to-many relationship



  • This is the design question: Java for concepts like enforcing a one-to-many relationship

  • Do you want to try and write code in the classes of the participating objects so that correct relationships are maintained?

  • Or would you prefer to write a separate class that implements all of the rules necessary in order to enforce correct relationships?




  • Challenge 10.3 relationships with an example

  • “Assume that the objects begin as shown in Figure 10.4. Suppose that the object t represents tub T308 and that the object m represents the machine Fuser-2101. Complete the object diagram in Figure 10.5, showing the effects of the code that updates the tub’s location. What defect does this reveal?”

  • [Figures 10.4 and 10.5 are shown on the next overheads.]


  • Solution 10.3 relationships with an example

  • “Figure B.13 shows an updated object diagram.”


  • Solution 10.3, cont’d. relationships with an example

  • “The problem that the developer’s code introduces is that StarPress2402 still thinks that it has tub T308. In a relational table, changing the machine attribute of a row automatically removes the tub from the prior machine. This automated removal does not occur when the relation is dispersed across a distributed object model. The proper modeling of the tub/machine relation requires special logic that you can remove to a separate mediator object.”


A table based implementation
A Table Based Implementation relationships with an example

  • The book suggests that the simplest way to maintain relational integrity like this is to actually rely on a table

  • The table concept can be implemented in the separate mediator class

  • Then the objects won’t refer to each other directly





Code for a map based solution
Code for a Map Based Solution a machine, assigning a machine to a tub, etc.

  • The book next starts presenting code, partial code, and code based challenges

  • It starts with the Tub class

  • It then explains the TubMediator class

  • I think it makes more sense to look at the mediator class first


  • The a machine, assigning a machine to a tub, etc.TubMediator class has a Map instance variable

  • That variable is an instance of the Java class HashMap

  • On the following overhead is a snippet from the Java API documentation for the HashMap


  • HashMap a machine, assigning a machine to a tub, etc.

  • Hash table based implementation of the Map interface.

  • This implementation provides all of the optional map operations, and permits null values and the null key.

  • (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.)


  • Here is a snippet from the Java API documentation for a machine, assigning a machine to a tub, etc.Hashtable:

  • This class implements a hashtable, which maps keys to values.

  • Any non-null object can be used as a key or as a value.

  • To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method and the equals method.



  • get Java API on the hash table get() and put() methods

  • public Vget(Object key)

  • Returns the value to which the specified key is mapped in this hashtable.

  • Specified by: get in interface Map<K,V>

  • Specified by: get in class Dictionary<K,V>

  • Parameters: key - a key in the hashtable.

  • Returns: the value to which the key is mapped in this hashtable; null if the key is not mapped to any value in this hashtable.

  • Throws:NullPointerException - if the key is null.

  • See Also: put(Object, Object)


  • put Java API on the hash table get() and put() methods

  • public Vput(K key, V value)

  • Maps the specified key to the specified value in this hashtable. Neither the key nor the value can be null. The value can be retrieved by calling the get method with a key that is equal to the original key.

  • Specified by: put in interface Map<K,V>

  • Specified by: put in class Dictionary<K,V>

  • Parameters: key - the hashtablekey.value - the value.

  • Returns: the previous value of the specified key in this hashtable, or null if it did not have one.

  • Throws:NullPointerException - if the key or value is null.

  • See Also: Object.equals(Object), get(Object)


  • The way to envision the use of the hash table with tubs and machines is this:

  • The hash table is like a two column table

  • The left column consists of look-up values, known as keys—the tubs

  • The right column consists of values, namely those values that match with the keys—the machines where the tubs are located



  • I have gotten rid of Challenge machines is this:10.4

  • Complete code for the TubMediator class is given on the overhead following the next one

  • There is a method to assign a tub to a machine

  • There is a method to find the machine a tub is assigned to

  • And there is a method which allows you to get the set of all tubs located at a machine


  • Note that the implementations of the machines is this:getTubs() and set() methods are quite simple

  • They rely entirely on the get() and put() methods of the HashMapclass

  • This is the secret of the use of the Java collection in the implementation of the mediator design pattern

  • Essentially, the mediator just wraps the collection and passes through to its methods


  • public class machines is this:TubMediator

  • {

  • protected Map tubToMachine = new HashMap();

  • public Set getTubs(Machine m)

  • {

  • Set set = new HashSet();

  • Iteratori = tubToMachine.entrySet().iterator();

  • while(i.hasNext())

  • {

  • Map.Entry e = (May.Entry) i.next();

  • if(e.getValue().equals(m))

  • set.add(e.getKey());

  • }

  • return set;

  • }


  • public Machine machines is this:getMachine(Tub t)

  • {

  • return (Machine) tubToMachine.get(t);

  • }

  • public void set(Tub t, Machine m)

  • {

  • tubToMachine.put(t, m);

  • }

  • }


The tub class
The Tub Class machines is this:

  • A tub has an id and a reference to the mediator

  • It has set and get methods for location, where location refers to the machine it’s associated with

  • Just as the mediator wrapped a hashmap collection, the set and get methods for the tubwrap calls to the mediator object

  • It’s the mediator that’s responsible for maintaining relationships


  • public class Tub machines is this:

  • {

  • private String id;

  • private TubMediator mediator = null;

  • public Tub(String id, Tubmediator mediator)

  • {

  • this.id = id;

  • this.mediator = mediator;

  • }


  • public Machine machines is this:getLocation()

  • {

  • return mediator.getMachine(this);

  • }

  • public void setLocation(Machine value)

  • {

  • mediator.set(this, value);

  • }

  • public String toString()

  • {

  • return id;

  • }


  • This is not the end of the book’s code, just a brief interruption

  • It turns out that the Tub class also needs a hashCode() and an equals() method in order to serve as the key of a hashmap

  • Code for these methods will be given next

  • They will be discussed at length after the code


  • public interruptioninthashCode()

  • {

  • return id.hashCode();

  • }

  • public boolean equals(Object obj)

  • {

  • if(obj == this) return true;

  • if(obj.getClass() != Tub.class)

  • return false;

  • Tub that = (Tub) obj;

  • return id.equals(that.id);

  • }


  • The Tub class needs interruptionhashCode() and equals() methods for the following reason:

  • In order for instances of a class to serve as the keys of a hash table (HashMap), they have to implement these methods

  • This information was given in the API documentation for the HashMapclass that was shown earlier


  • Functionally, the interruptionsetLocation() and getLocation() methods of the Tub class wrap calls of this kind on the mediator:

  • mediator.set(this, value);

  • mediator.getMachine(this);


  • Functionally, the set() and interruptiongetMachine() methods of the TubMediator class wrap calls of this kind on the hash table, where the parameter t is the tub (this) of the wrapping call:

  • tubToMachine.put(t, m);

  • return (Machine) tubToMachine.get(t);


  • In short, the tubs are being passed in as the key values for the hash table

  • From the requirement that the key class have a hashCode() method and an equals() method, you can deduce the following:

  • Internal to the hash table get() and put() methods, there must be calls to hashCode() and equals() on the tub parameters


  • This makes perfect sense the hash table

  • The keys of a hash table have to be unique

  • The hashCode() and equals() methods are used internally to verify that tubs are unique before they can be used as keys


  • The only lingering question is why the authors chose to implement hashCode() and equals() on the basis of a tub’s id rather that on the basis of the tub object itself

  • As far as I can see in the text, the authors don’t explain this decision

  • I can see no syntactical reason for not basing hashCode() and equals() on the Tub object rather than its id


  • The one concrete consequence of the decision that I can see is that it will ultimately force the user to make sure that tub id’s are unique

  • On the other hand, if the programmer has introduced user level tub id’s into the application, then it’s up to the user to make sure that they are unique anyway


Back to the general discussion
Back to the General Discussion is that it will ultimately force the user to make sure that tub id’s are unique

  • The book returns to the general theme of whether or not it’s a good idea to include a mediator in a design

  • You could code the logic for machines and tubs into those classes themselves

  • The thing to remember is that such code is error prone

  • You could also argue that the details of relationships are not intrinsically part of the logic of the classes themselves


  • You might also argue that the relationships possible between classes are intrinsic parts of the definitions of the classes

  • Regardless of your position, there is clearly a convenience in unifying the logic for relationships in one place

  • The relationships are an abstraction of their own, and the logic for maintaining them can be centralized



Another example
Another Example classes

  • Another example, based on cups and seeds, will be given next

  • This example has this similarity with the book’s first example:

  • A listener in a graphical application may be viewed as a mediator

  • It also has this similarity with the book’s second example:

  • How you capture the relationships between base objects in the application is important as well


  • In this example there are 3 cups and 9 seeds classes

  • A cup can contain from 0 to 9 seeds

  • A given seed can only be contained in one cup at a time

  • The graphical user interface allows the user to pick a seed and a cup and cause the seed to be moved to that cup by pressing a button



  • A UML diagram for the application is given on the overhead following the next one.

  • The diagram shows that CupsAndSeedsMediator occupies a position between the input GUI elements, and the underlying DB model, which is displayed on output.

  • The mediator implements the ActionListener interface, but it isn’t an inner class.

  • It’s passed a reference to the frame class that contains it at construction time.


  • Not a lot of care is taken in the implementation of following the next one.CupsAndSeedsDB, so it isn’t a full scale example of a mediator

  • However, in spite of where it appears relative to the Cup and Seed classes in the diagram, it has mediator like qualities

  • The CupsAndSeedsDB class contains the code that captures the relationships, telling which seeds belong to which cups, and making sure that a seed doesn’t belong to two cups at once


Code following the next one.

  • The code for the application is given on the following overheads for reference.

  • It will probably not be covered in class.


  • import java.awt.*; following the next one.

  • import java.awt.event.*;

  • import javax.swing.*;

  • import java.awt.Graphics2D;

  • import java.awt.Rectangle;

  • import java.awt.geom.Ellipse2D;

  • import java.lang.*;

  • import java.util.*;

  • public class MoveOneSeedOneFile

  • {

  • public static void main(String[] args)

  • {

  • MoveOneSeedFramemyframe = new MoveOneSeedFrame();

  • myframe.setVisible(true);

  • }

  • }


  • class following the next one.MoveOneSeedFrame extends JFrame

  • {

  • private CupsAndSeedsDBcupsAndSeeds;

  • private CupsAndSeedsMediator mediator;

  • private JTextFieldseedField;

  • private JTextFieldcupField;

  • private JButtonmoveSeedButton;

  • private MoveOneSeedPanelmyOutputPanel;

  • private JPanelmyInputPanel;

  • private final int FRAMEW = 1000;

  • private final int FRAMEH = 500;

  • public MoveOneSeedFrame()

  • {

  • setTitle("MoveOneSeed Frame");

  • setSize(FRAMEW, FRAMEH);

  • setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  • cupsAndSeeds = new CupsAndSeedsDB();

  • mediator = new CupsAndSeedsMediator(cupsAndSeeds, this);


  • JPanel following the next one.myInputPanel = new JPanel();

  • JLabel label1 = new JLabel("Color of seed to move: white, pink, red, orange, yellow, green, cyan, blue, magenta:");

  • seedField = new JTextField("", 12);

  • JLabel label2 = new JLabel("Number of destination cup: 1, 2, 3:");

  • cupField = new JTextField("", 12);

  • moveSeedButton = new JButton("Move Seed");

  • moveSeedButton.addActionListener(mediator);

  • JPanel subPanel1 = new JPanel();

  • JPanel subPanel2 = new JPanel();

  • JPanel subPanel3 = new JPanel();

  • JPanel subPanel4 = new JPanel();

  • JPanel subPanel5 = new JPanel();

  • subPanel1.add(label1);

  • subPanel2.add(seedField);

  • subPanel3.add(label2);

  • subPanel4.add(cupField);

  • subPanel5.add(moveSeedButton);

  • myInputPanel.setLayout(new GridLayout(3, 2));

  • myInputPanel.add(subPanel1);

  • myInputPanel.add(subPanel2);

  • myInputPanel.add(subPanel3);

  • myInputPanel.add(subPanel4);

  • myInputPanel.add(subPanel5);


  • myOutputPanel following the next one. = new MoveOneSeedPanel(cupsAndSeeds);

  • Container contentPane = getContentPane();

  • contentPane.add(myInputPanel, "North");

  • contentPane.add(myOutputPanel, "Center");

  • }

  • public JButtongetMoveSeedButton()

  • {

  • return moveSeedButton;

  • }

  • public JTextFieldgetSeedField()

  • {

  • return seedField;

  • }

  • public JTextFieldgetCupField()

  • {

  • return cupField;

  • }

  • }


  • class following the next one.MoveOneSeedPanel extends JPanel

  • {

  • CupsAndSeedsDBshownDB;

  • public MoveOneSeedPanel(CupsAndSeedsDBdbIn)

  • {

  • shownDB = dbIn;

  • }

  • public void paintComponent(Graphics g)

  • {

  • inti;

  • intcupX = 180;

  • intcupY = 180;

  • intcupW = 40;

  • intcupH = 40;

  • intseedX;

  • intseedY;

  • Rectangle cupRectangle;

  • Ellipse2D.Double seedDot;

  • intseedDiam = 7;

  • ArrayList<Cup> cupList;

  • ArrayList<Seed> seedList;

  • Graphics2D g2 = (Graphics2D) g;

  • super.paintComponent(g2);

  • cupList = shownDB.getCupList();

  • System.out.println("Before loops");


  • for(Cup following the next one.aCup : cupList)

  • {

  • System.out.println("In cup loop");

  • cupRectangle = new Rectangle(cupX, cupY, cupW, cupH);

  • g2.draw(cupRectangle);

  • Random generator = new Random();

  • seedList = aCup.getSeedList();

  • for(Seed aSeed : seedList)

  • {

  • System.out.println("In seed loop top");

  • seedX = (int) cupX + generator.nextInt((int) cupW - seedDiam);

  • seedY = (int) cupY + generator.nextInt((int) cupH - seedDiam);

  • seedDot = new Ellipse2D.Double(seedX, seedY, seedDiam, seedDiam);

  • System.out.println("Before printing seedIterator.next()");

  • System.out.println(aSeed);

  • System.out.println("Before printing color of seedIterator.next()");

  • System.out.println(aSeed.getSeedColor());

  • g2.setColor(aSeed.getSeedColor());

  • g2.fill(seedDot);

  • g2.setColor(Color.BLACK);

  • System.out.println("At bottom of seed loop");

  • }

  • cupX = cupX + 50;

  • System.out.println("At bottom of cup loop");

  • }

  • System.out.println("After loops");

  • }

  • }


  • /* The idea behind this class is that each seed will be of a different color.

  • The seeds can then be identified by their colors. Nothing in the code as written

  • would cause more than one seed of the same color to exist. On the other hand,

  • there are no particular protections in the code to prevent this. */

  • class CupsAndSeedsDB

  • {

  • private ArrayList<Cup> cupList;


  • public a different color.CupsAndSeedsDB()

  • {

  • cupList = new ArrayList<Cup>();

  • Seed seed1 = new Seed(Color.WHITE, "WHITE");

  • Seed seed2 = new Seed(Color.PINK, "PINK");

  • Seed seed3 = new Seed(Color.RED, "RED");

  • Cup cup1 = new Cup();

  • cup1.addSeed(seed1);

  • cup1.addSeed(seed2);

  • cup1.addSeed(seed3);

  • cupList.add(cup1);

  • Seed seed4 = new Seed(Color.ORANGE, "ORANGE");

  • Seed seed5 = new Seed(Color.YELLOW, "YELLOW");

  • Seed seed6 = new Seed(Color.GREEN, "GREEN");

  • Cup cup2 = new Cup();

  • cup2.addSeed(seed4);

  • cup2.addSeed(seed5);

  • cup2.addSeed(seed6);

  • cupList.add(cup2);

  • Seed seed7 = new Seed(Color.CYAN, "CYAN");

  • Seed seed8 = new Seed(Color.BLUE, "BLUE");

  • Seed seed9 = new Seed(Color.MAGENTA, "MAGENTA");

  • Cup cup3 = new Cup();

  • cup3.addSeed(seed7);

  • cup3.addSeed(seed8);

  • cup3.addSeed(seed9);

  • cupList.add(cup3);

  • }


  • public a different color.ArrayListgetCupList()

  • {

  • return cupList;

  • }

  • public Seed removeSeedOfThisColor(String colorNameIn)

  • {

  • IteratorcupIterator = cupList.iterator();

  • IteratorseedIterator;

  • Seed latestSeed = null;

  • boolean found = false;

  • while(cupIterator.hasNext() && !found)

  • {

  • seedIterator = ((Cup) cupIterator.next()).getSeedList().iterator();

  • while(seedIterator.hasNext() && !found)

  • {

  • latestSeed = (Seed) seedIterator.next();

  • if(latestSeed.getSeedColorName().equals(colorNameIn))

  • {

  • found = true;

  • seedIterator.remove();

  • }

  • }

  • }

  • if(found)

  • return latestSeed;

  • else

  • return null;

  • }


  • public void a different color.addSeedToCup(intcupNumber, Seed seedIn)

  • {

  • Cup cupRef = (Cup) cupList.get(cupNumber);

  • cupRef.addSeed(seedIn);

  • }

  • }

  • class Cup

  • {

  • private ArrayList<Seed> seedList;

  • public Cup()

  • {

  • seedList = new ArrayList<Seed>();

  • }

  • public void addSeed(Seed seedIn)

  • {

  • seedList.add(seedIn);

  • }

  • public ArrayList<Seed> getSeedList()

  • {

  • return seedList;

  • }

  • }


  • class Seed a different color.

  • {

  • private Color seedColor;

  • private String seedColorName;

  • public Seed(Color colorIn, String seedColorNameIn)

  • {

  • seedColor = colorIn;

  • seedColorName = seedColorNameIn;

  • }

  • public Color getSeedColor()

  • {

  • return seedColor;

  • }

  • public String getSeedColorName()

  • {

  • return seedColorName;

  • }

  • }


  • class a different color.CupsAndSeedsMediator implements ActionListener

  • {

  • MoveOneSeedFrameframeRef;

  • CupsAndSeedsDBcupsAndSeedsRef;

  • public CupsAndSeedsMediator(CupsAndSeedsDBdbIn, MoveOneSeedFrameframeIn)

  • {

  • cupsAndSeedsRef = dbIn;

  • frameRef = frameIn;

  • }

  • public void actionPerformed(ActionEventbuttonClick)

  • {

  • String inputSeedString = frameRef.getSeedField().getText();

  • inputSeedString = inputSeedString.toUpperCase();

  • frameRef.getSeedField().setText("");

  • String inputCupString = frameRef.getCupField().getText();

  • intinputCupAsInteger = Integer.parseInt(inputCupString) - 1;

  • frameRef.getCupField().setText("");

  • Seed seedToGet = cupsAndSeedsRef.removeSeedOfThisColor(inputSeedString);

  • if(seedToGet == null)

  • System.out.println("XXXXXXX Didn't find seed of this color in the db.");

  • else

  • cupsAndSeedsRef.addSeedToCup(inputCupAsInteger, seedToGet);

  • frameRef.repaint();

  • }

  • }


A uml diagram for the pattern from lasater
A UML Diagram for the Pattern from a different color.Lasater

  • Lasater’s UML diagram is given on the next overhead.

  • Using that author’s terminology, the relationship between concrete colleagues is captured by a concrete mediator

  • The mediator superclass is shown as having a reference to instances of the colleague superclass

  • The individual concrete colleagues are also shown as having references to the concrete mediator


Considering the uml for the pattern again
Considering the UML for the Pattern Again a different color.

  • Looking at Lasater’s UML diagram raises a question:

  • What is the correct diagram/correct structure for the pattern?

  • In the UML diagram for the textbook’s first example, with the GUI, you see this:

  • The UI and the mediator have references to each other

  • They both also have references to the mediator






  • Depending on how the code is structured, it may be necessary for the base class objects to have references to their mediator

  • This would not be absolutely necessary

  • However, you would certainly expect the mediator to have references to the objects that it maintains the relationships for

  • 4. The following overhead shows my simplistic view of the pattern using “has-a” relationships from the mediator to the base classes


Summary
Summary for the base class objects to have references to their mediator

  • The Mediator pattern supports loose coupling between base class objects

  • Related objects don’t refer to each other directly

  • Instead, they are related through the mediator

  • The Mediator pattern shows up in GUI development where communication among components by means of an observer/observable structure (listeners)



The end
The End between objects in a separate class, the Mediator pattern applies


ad