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

7.expressionA.interpret(c);

8.expressionB.interpret(c);

9.Object exprAResult = c.get(expressionA);

10.Object exprBResult = c.get(expressionB);

11.if ((exprAResult instanceof String) && (exprBResult instanceof String)){

12.

if (((String)exprAResult).indexOf((String)exprBResult) != -1){

13.

c.addVariable(this, Boolean.TRUE);

14.

return;

15.

}

16.}

17.c.addVariable(this, Boolean.FALSE);

18.return;

19.}

20.}

The Context class represents shared memory for expressions during evaluation. Context is a wrapper around a HashMap. In this example, the Expression objects provide the keys for the HashMap, and the results of calling the interpret method are stored as its values.

Example A.60 Context.java

1.import java.util.HashMap;

2.public class Context{

3.private HashMap map = new HashMap();

5.public Object get(Object name){

6.return map.get(name);

7.}

8.

9.public void addVariable(Object name, Object value){

10.map.put(name, value);

11.}

12.}

With this series of expressions, it is possible to perform fairly sophisticated comparisons. ContactList holds a series of contacts in this example. It defines a method called getContactsMatchingExpression, which evaluates the Expression for every Contact and returns an ArrayList.

Example A.61 ContactList.java

1.import java.io.Serializable;

2.import java.util.ArrayList;

3.import java.util.Iterator;

4.public class ContactList implements Serializable{

5.private ArrayList contacts = new ArrayList();

7.public ArrayList getContacts(){ return contacts; }

8.public Contact [] getContactsAsArray(){ return (Contact [])(contacts. toArray(new

Contact [1])); }

9.

10.public ArrayList getContactsMatchingExpression(Expression expr, Context ctx, Object key){

11.ArrayList results = new ArrayList();

12.Iterator elements = contacts.iterator();

13.while (elements.hasNext()){

14.

Object currentElement = elements.next();

15.

ctx.addVariable(key,

currentElement);

16.

expr.interpret(ctx);

 

17.

Object interpretResult = ctx.get(expr);

18.

if ((interpretResult

!= null) && (interpretResult.equals(Boolean.TRUE))){

19.

results.add(currentElement);

20.

}

 

21.}

22.return results;

23.}

24.

25. public void setContacts(ArrayList newContacts){ contacts = newContacts; }

26.

27.public void addContact(Contact element){

28.if (!contacts.contains(element)){

29. contacts.add(element);

30.}

31.}

32.public void removeContact(Contact element){

33.contacts.remove(element);

34.}

35.

250

36.public String toString(){

37.return contacts.toString();

38.}

39.}

With the Expression hierarchy and the ContactList, it is possible to perform database-like queries for the Contacts in a ContactList. For example, you could search for all those Contacts with a title containing the characters “Java” by doing the following:

Create a ConstantExpression with the string “Java”.

Create a VariableExpression with the target object and the string “ getTitle ”.

Create a ContainsExpression with the VariableExpression as the first argument and the

ConstantExpression as the second.

Pass the ContainsExpression into a ContactList object's getContactsMatchingExpression method.

Contact and its implementer ContactImpl represent the business objects to be evaluated in this example.

Example A.62 Contact.java

1.import java.io.Serializable;

2.public interface Contact extends Serializable{

3.public static final String SPACE = " ";

4.public String getFirstName();

5.public String getLastName();

6.public String getTitle();

7.public String getOrganization();

8.

public void setFirstName(String newFirstName);

9.

10.

public void setLastName(String newLastName);

11.

public void setTitle(String newTitle);

 

12.

public void setOrganization(String newOrganization);

13.

}

 

 

 

Y

Example A.63 ContactImpl.java

 

 

 

 

 

 

L

1.

public class ContactImpl implements Contact{

2.

private String firstName;

 

F

 

M

 

3.

private String lastName;

 

 

4.

private String title;

 

A

 

5.

private String organization;E

 

 

6.

public ContactImpl(){}

T

 

 

 

7.

 

 

 

 

8.public ContactImpl(String newFirstName, String newLastName,

9.String newTitle, String newOrganization){

10. firstName = newFirstName;

11. lastName = newLastName;

12. title = newTitle;

13. organization = newOrganization;

14. }

15.

16.public String getFirstName(){ return firstName; }

17.public String getLastName(){ return lastName; }

18.public String getTitle(){ return title; }

19.public String getOrganization(){ return organization; }

21.public void setFirstName(String newFirstName){ firstName = newFirstName; }

22.public void setLastName(String newLastName){ lastName = newLastName; }

23.public void setTitle(String newTitle){ title = newTitle; }

24.public void setOrganization(String newOrganization){ organization = newOrganization; }

26.public String toString(){

27.return firstName + SPACE + lastName;

28.}

29.}

This code shows how the Interpreter could be used to search among a set of Contacts in a structure like an address book. Recognize, however, that the Expressions could be used with any other classes, providing search functionality for any of the PIM business objects

TEAM FLY PRESENTS

251

RunPattern demonstrates the Interpreter functionality by creating a ContactList and running a group of matching expressions on the elements in the list.

Example A.64 RunPattern.java

1.public class RunPattern{

2.public static void main(String [] arguments){

3.System.out.println("Example for the Interpreter pattern");

4.System.out.println("In this demonstration, the syntax defined");

5.System.out.println(" by the Interpreter can be used to search");

6.System.out.println(" among a collection of Contacts, returning");

7.System.out.println(" the subset that match the given search criteria.");

9.ContactList candidates = makeContactList();

10.Context ctx = new Context();

11.

12.System.out.println("Contents of the ContactList:");

13.System.out.println(candidates);

14.System.out.println();

15.

16.Contact testContact = new ContactImpl();

17.VariableExpression varLName = new VariableExpression(testContact, "getLastName");

18.ConstantExpression constLName = new ConstantExpression("u");

19.ContainsExpression eqLName = new ContainsExpression(varLName, constLName);

20.

21.System.out.println("Contents of the search on ContactList:");

22.System.out.println("(search was contains 'u' in Lase Name)");

23.Object result = candidates.getContactsMatchingExpression(eqLName, ctx, testContact);

24.System.out.println(result);

25.

26.VariableExpression varTitle = new VariableExpression(testContact, "getTitle");

27.ConstantExpression constTitle = new ConstantExpression("LT");

28.EqualsExpression eqTitle = new EqualsExpression(varTitle, constTitle);

29.

30.System.out.println("Contents of the search on ContactList:");

31.System.out.println("(search was all LT personnel)");

32.result = candidates.getContactsMatchingExpression(eqTitle, ctx, testContact);

33.System.out.println(result);

34.System.out.println();

35.

36.VariableExpression varLastName = new VariableExpression(testContact, "getLastName");

37.ConstantExpression constLastName = new ConstantExpression("S");

38.ContainsExpression cLName = new ContainsExpression(varLastName, constLastName);

39.

40. AndExpression andExpr = new AndExpression(eqTitle, cLName);

41.

42.System.out.println("Contents of the search on ContactList:");

43.System.out.println("(search was all LT personnel with 'S' in Last Name)");

44.result = candidates.getContactsMatchingExpression(andExpr, ctx, testContact);

45.System.out.println(result);

46.}

47.

48.private static ContactList makeContactList(){

49.ContactList returnList = new ContactList();

50.returnList.addContact(new ContactImpl("James", "Kirk", "Captain", "USS

Enterprise"));

51.returnList.addContact(new ContactImpl("Mr.", "Spock", "Science Officer", "USS

Enterprise"));

52.returnList.addContact(new ContactImpl("LT", "Uhura", "LT", "USS Enterprise"));

53.returnList.addContact(new ContactImpl("LT", "Sulu", "LT", "USS Enterprise"));

54.returnList.addContact(new ContactImpl("Ensign", "Checkov", "Ensign", "USS

Enterprise"));

55.returnList.addContact(new ContactImpl("Dr.", "McCoy", "Ship's Doctor", "USS

Enterprise"));

56.returnList.addContact(new ContactImpl("Montgomery", "Scott", "LT", "USS

Enterprise"));

57.return returnList;

58.}

59.}

252

Iterator

This example uses the Java Collection Framework to provide iterating behavior for a pair of business aggregates. The java.util.Iterator interface defines methods for the basic navigation methods required— hasNext and next. Note that the Iterator interface requires one-time-only traversal, since the only way to return to the beginning is to get another Iterator from the collection.

The Iterating interface defines a single method, getIterator. This interface is used to identify any class in the PIM that is capable of producing an Iterator for collection traversal.

Example A.65 Iterating.java

1.import java.util.Iterator;

2.import java.io.Serializable;

3.public interface Iterating extends Serializable{

4.public Iterator getIterator();

5.}

The ToDoList and ToDoListCollection interfaces, which extend Iterating, define the two collections in the example. ToDoList defines a sequential list of tasks or items, while ToDoListCollection represents a collection of to-do lists stored in the PIM.

Example A.66 ToDoList.java

1.public interface ToDoList extends Iterating{

2.public void add(String item);

3.public void add(String item, int position);

4.public void remove(String item);

5.public int getNumberOfItems();

6.public String getListName();

7.public void setListName(String newListName);

8.}

Example A.67 ToDoListCollection.java

1.public interface ToDoListCollection extends Iterating{

2.public void add(ToDoList list);

3.public void remove(ToDoList list);

4.public int getNumberOfItems();

5.}

The classes ToDoListImpl and ToDoListCollectionImpl implement the previous interfaces. ToDoListImpl

uses an ArrayList to hold its elements, which provides absolute ordering and allows duplicate entries. ToDoListCollectionImpl uses a HashTable, which does not support ordering and stores its entries as key-value pairs. Although the collections behave very differently, both can provide Iterators for their stored elements.

Example A.68 ToDoListCollectionImpl.java

1.import java.util.Iterator;

2.import java.util.HashMap;

3.public class ToDoListCollectionImpl implements ToDoListCollection{

4.private HashMap lists = new HashMap();

5.

6.public void add(ToDoList list){

7.if (!lists.containsKey(list.getListName())){

8. lists.put(list.getListName(), list);

9.}

10.}

11.public void remove(ToDoList list){

12.if (lists.containsKey(list.getListName())){

13. lists.remove(list.getListName());

14.}

15.}

16.public int getNumberOfItems(){ return lists.size(); }

17.public Iterator getIterator(){ return lists.values().iterator(); }

18.public String toString(){ return getClass().toString(); }

19.}

Example A.69 ToDoListImpl.java

1.import java.util.Iterator;

2.import java.util.ArrayList;

3.public class ToDoListImpl implements ToDoList{

4.private String listName;

253