1. Trang chủ
  2. » Công Nghệ Thông Tin

Applied Java Patterns Stephen phần 7 docx

36 253 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Applied Java Patterns Stephen phần 7
Trường học University of Technology and Education
Chuyên ngành Computer Science
Thể loại Thesis
Năm xuất bản 2023
Thành phố Hanoi
Định dạng
Số trang 36
Dung lượng 2,79 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

public abstract class Address{ 2.. Builder This code example shows how to use the Builder pattern to create an appointment for the PIM.. The following list summarizes each class’s purpos

Trang 1

Appendix A Full Code Examples

System Requirements

This appendix includes full, runnable code examples for each pattern Most of the patterns in the main part of this book included only the code that is crucial for your understanding of the pattern This appendix includes all required class files, and a RunPattern class, which shows you how the code runs, and includes print statements specifying what occurs in the code

The following patterns use Remote Method Invocation ( RMI ) in their code examples: Callback, HOPP, Router, Session, Successive Update, Transaction, and Worker Thread

To run these examples, your computer must be network-enabled Specifically, your system must be able to use TCP/IP sockets for networking and recognize " localhost " as a valid loopback IP address

The rmiregistry is started from the RunPattern file in each of these examples Because rmiregistry is a server process, these examples will appear to block when they are finished You must manually terminate the Java process to exit the rmiregistry

Trang 2

Creational Pattern Code Examples

Abstract Factory

The following code samples show how international addresses and phone numbers can be supported in the Personal Information Manager with the Abstract Factory pattern The AddressFactory interface represents the factory itself:

Example A.1 AddressFactory.java

1 public interface AddressFactory{

2 public Address createAddress();

3 public PhoneNumber createPhoneNumber();

4 }

Note that the AddressFactory defines two factory methods, createAddress and createPhoneNumber The methods produce the abstract products Address and PhoneNumber, which define methods that these products support

Example A.2 Address.java

1 public abstract class Address{

2 private String street;

3 private String city;

4 private String region;

5 private String postalCode;

11 public String getStreet(){ return street; }

12 public String getCity(){ return city; }

13 public String getPostalCode(){ return postalCode; }

14 public String getRegion(){ return region; }

15 public abstract String getCountry();

16

17 public String getFullAddress(){

18 return street + EOL_STRING +

19 city + SPACE + postalCode + EOL_STRING;

20 }

21

22 public void setStreet(String newStreet){ street = newStreet; }

23 public void setCity(String newCity){ city = newCity; }

24 public void setRegion(String newRegion){ region = newRegion; }

25 public void setPostalCode(String newPostalCode){ postalCode = newPostalCode; }

26 }

Example A.3 PhoneNumber.java

1 public abstract class PhoneNumber{

2 private String phoneNumber;

3 public abstract String getCountryCode();

Trang 3

1 public class USAddressFactory implements AddressFactory{

2 public Address createAddress(){

3 return new USAddress();

4 }

5

6 public PhoneNumber createPhoneNumber(){

7 return new USPhoneNumber();

8 }

9 }

Example A.5 USAddress.java

1 public class USAddress extends Address{

2 private static final String COUNTRY = "UNITED STATES";

3 private static final String COMMA = ",";

4

5 public String getCountry(){ return COUNTRY; }

6

7 public String getFullAddress(){

8 return getStreet() + EOL_STRING +

9 getCity() + COMMA + SPACE + getRegion() +

10 SPACE + getPostalCode() + EOL_STRING +

11 COUNTRY + EOL_STRING;

12 }

13 }

Example A.6 USPhoneNumber.java

1 public class USPhoneNumber extends PhoneNumber{

2 private static final String COUNTRY_CODE = "01";

3 private static final int NUMBER_LENGTH = 10;

Example A.7 FrenchAddressFactory.java

1 public class FrenchAddressFactory implements AddressFactory{

2 public Address createAddress(){

3 return new FrenchAddress();

4 }

5

6 public PhoneNumber createPhoneNumber(){

7 return new FrenchPhoneNumber();

8 }

9 }

Example A.8 FrenchAddress.java

1 public class FrenchAddress extends Address{

2 private static final String COUNTRY = "FRANCE";

3

4 public String getCountry(){ return COUNTRY; }

5

6 public String getFullAddress(){

7 return getStreet() + EOL_STRING +

8 getPostalCode() + SPACE + getCity() +

9 EOL_STRING + COUNTRY + EOL_STRING;

10 }

11 }

Example A.9 FrenchPhoneNumber.java

1 public class FrenchPhoneNumber extends PhoneNumber{

2 private static final String COUNTRY_CODE = "33";

3 private static final int NUMBER_LENGTH = 9;

4

5 public String getCountryCode(){ return COUNTRY_CODE; }

Trang 4

PhoneNumber interfaces There are no method calls which depend on the distinction between a USAddress and a

FrenchAddress

Example A.10 RunPattern.java

1 public class RunPattern{

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

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

4 System.out.println();

5 System.out.println(" (take a look in the RunPattern code Notice that you can");

6 System.out.println(" use the Address and PhoneNumber classes when writing");

7 System.out.println(" almost all of the code This allows you to write a very");

8 System.out.println(" generic framework, and plug in Concrete Factories");

9 System.out.println(" and Products to specialize the behavior of your code)");

10 System.out.println();

11

12 System.out.println("Creating U.S Address and Phone Number:");

13 AddressFactory usAddressFactory = new USAddressFactory();

14 Address usAddress = usAddressFactory.createAddress();

15 PhoneNumber usPhone = usAddressFactory.createPhoneNumber();

30 System.out.println("Creating French Address and Phone Number:");

31 AddressFactory frenchAddressFactory = new FrenchAddressFactory();

32 Address frenchAddress = frenchAddressFactory.createAddress();

33 PhoneNumber frenchPhone = frenchAddressFactory.createPhoneNumber();

Trang 5

Builder

This code example shows how to use the Builder pattern to create an appointment for the PIM The following list summarizes each class’s purpose:

AppointmentBuilder, MeetingBuilder – Builder classes

Scheduler – Director class

Appointment – Product

Address, Contact – Support classes, used to hold information relevant to the Appointment

InformationRequiredException – An Exception class produced when more data is required

For the base pattern, the AppointmentBuilder manages the creation of a complex product, which is an

Appointment in this example The AppointmentBuilder uses a series of build methods— buildAppointment,

buildLocation, buildDates, and buildAttendees — to create an Appointment and populate it

Example A.11 AppointmentBuilder.java

6 public static final int START_DATE_REQUIRED = 1;

7 public static final int END_DATE_REQUIRED = 2;

8 public static final int DESCRIPTION_REQUIRED = 4;

9 public static final int ATTENDEE_REQUIRED = 8;

10 public static final int LOCATION_REQUIRED = 16;

16 public void buildAppointment(){

17 appointment = new Appointment();

18 }

19

20 public void buildDates(Date startDate, Date endDate){

21 Date currentDate = new Date();

22 if ((startDate != null) && (startDate.after(currentDate))){

34 public void buildAttendees(ArrayList attendees){

35 if ((attendees != null) && (!attendees.isEmpty())){

Trang 6

3 public class Appointment{

4 private Date startDate;

5 private Date endDate;

6 private String description;

7 private ArrayList attendees = new ArrayList();

8 private Location location;

9 public static final String EOL_STRING =

10 System.getProperty("line.separator");

11

12 public Date getStartDate(){ return startDate; }

13 public Date getEndDate(){ return endDate; }

14 public String getDescription(){ return description; }

15 public ArrayList getAttendees(){ return attendees; }

16 public Location getLocation(){ return location; }

17

18 public void setDescription(String newDescription){ description = newDescription; }

19 public void setLocation(Location newLocation){ location = newLocation; }

20 public void setStartDate(Date newStartDate){ startDate = newStartDate; }

21 public void setEndDate(Date newEndDate){ endDate = newEndDate; }

22 public void setAttendees(ArrayList newAttendees){

38 public String toString(){

39 return " Description: " + description + EOL_STRING +

40 " Start Date: " + startDate + EOL_STRING +

41 " End Date: " + endDate + EOL_STRING +

42 " Location: " + location + EOL_STRING +

3 public class Scheduler{

4 public Appointment createAppointment(AppointmentBuilder builder,

5 Date startDate, Date endDate, String description,

6 Location location, ArrayList attendees) throws InformationRequiredException {

7 if (builder == null){

Trang 7

The responsibilities of each class are summarized here:

Scheduler – Calls the appropriate build methods on AppointmentBuilder; returns a complete Appointment

object to its caller

AppointmentBuilder – Contains build methods and enforces business rules; creates the actual Appointment

object

Appointment – Holds information about an appointment

The MeetingBuilder class in Example A.14 demonstrates one of the benefits of using the Builder pattern To add additional rules for the Appointment, extend the existing builder In this case, the MeetingBuilder enforces an additional constraint: for an Appointment that is a meeting, both start and end dates must be specified

Example A.14 MeetingBuilder.java

1 import java.util.Date;

2 import java.util.Vector;

3

4 public class MeetingBuilder extends AppointmentBuilder{

5 public Appointment getAppointment() throws InformationRequiredException{

Support classes used for this example include the class InformationRequiredException and the interfaces

Location and Contact The Address and Contact interfaces are marker interfaces used to represent supporting information for the Appointment in this example; their implementation is represented by the LocationImpl and

ContactImpl classes

Example A.15 InformationRequiredException.java

1 public class InformationRequiredException extends Exception{

2 private static final String MESSAGE = "Appointment cannot be created because further

information is required";

3 public static final int START_DATE_REQUIRED = 1;

4 public static final int END_DATE_REQUIRED = 2;

5 public static final int DESCRIPTION_REQUIRED = 4;

6 public static final int ATTENDEE_REQUIRED = 8;

7 public static final int LOCATION_REQUIRED = 16;

8 private int informationRequired;

Trang 8

1 import java.io.Serializable;

2 public interface Location extends Serializable {

3 public String getLocation();

4 public void setLocation(String newLocation);

5 }

Example A.17 LocationImpl.java

1 public class LocationImpl implements Location{

2 private String location;

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

9 public void setFirstName(String newFirstName);

10 public void setLastName(String newLastName);

11 public void setTitle(String newTitle);

12 public void setOrganization(String newOrganization);

13 }

Example A.19 ContactImpl.java

1 public class ContactImpl implements Contact{

2 private String firstName;

3 private String lastName;

4 private String title;

5 private String organization;

6

7 public ContactImpl(String newFirstName, String newLastName,

8 String newTitle, String newOrganization){

15 public String getFirstName(){ return firstName; }

16 public String getLastName(){ return lastName; }

17 public String getTitle(){ return title; }

18 public String getOrganization(){ return organization; }

19

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

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

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

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

24

25 public String toString(){

26 return firstName + SPACE + lastName;

27 }

28 }

The RunPattern file executes this example It demonstrates the use of the Builder pattern by creating three

separate Appointment objects using the AppointmentBuilder and MeetingBuilder

Example A.20 RunPattern.java

1 import java.util.Calendar;

2 import java.util.Date;

3 import java.util.ArrayList;

Trang 9

4 public class RunPattern{

5 private static Calendar dateCreator = Calendar.getInstance();

6

7 public static void main(String [] arguments){

8 Appointment appt = null;

9

10 System.out.println("Example for the Builder pattern");

11 System.out.println();

12 System.out.println("This example demonstrates the use of the Builder");

13 System.out.println("pattern to create Appointment objects for the PIM.");

14 System.out.println();

15

16 System.out.println("Creating a Scheduler for the example.");

17 Scheduler pimScheduler = new Scheduler();

37 System.out.println("Creating a MeetingBuilder for the example.");

38 MeetingBuilder mtgBuilder = new MeetingBuilder();

39 try{

40 System.out.println("Creating a new Appointment with a MeetingBuilder");

41 System.out.println("(notice that the same create arguments will produce");

42 System.out.println(" an exception, since the MeetingBuilder enforces a");

43 System.out.println(" mandatory end date)");

57 System.out.println("Creating a new Appointment with a MeetingBuilder");

58 System.out.println("(This time, the MeetingBuilder will provide an end date)");

77 public static Date createDate(int year, int month, int day, int hour, int minute){

78 dateCreator.set(year, month, day, hour, minute);

79 return dateCreator.getTime();

80 }

81

Trang 10

82 public static ArrayList createAttendees(int numberToCreate){

83 ArrayList group = new ArrayList();

84 for (int i = 0; i < numberToCreate; i++){

85 group.add(new ContactImpl("John", getLastName(i), "Employee (nonexempt)", "Yoyodyne

109 public static void printExceptions(InformationRequiredException exc){

110 int statusCode = exc.getInformationRequired();

111

112 System.out.println("Unable to create Appointment: additional information is

required");

113 if ((statusCode & InformationRequiredException.START_DATE_REQUIRED) > 0){

114 System.out.println(" A start date is required for this appointment to be

complete.");

115 }

116 if ((statusCode & InformationRequiredException.END_DATE_REQUIRED) > 0){

117 System.out.println(" An end date is required for this appointment to be

complete.");

118 }

119 if ((statusCode & InformationRequiredException.DESCRIPTION_REQUIRED) > 0){

120 System.out.println(" A description is required for this appointment to be

complete.");

121 }

122 if ((statusCode & InformationRequiredException.ATTENDEE_REQUIRED) > 0){

123 System.out.println(" At least one attendee is required for this appointment to

be complete.");

124 }

125 if ((statusCode & InformationRequiredException.LOCATION_REQUIRED) > 0){

126 System.out.println(" A location is required for this appointment to be

Trang 11

Factory Method

The following example uses the Factory Method pattern to produce an editor for the PIM The PIM tracks a lot of information, and there are many cases where users need an editor to create or modify data The example uses interfaces to improve the overall flexibility of the system

The Editable interface defines a builder method, getEditor, which returns an ItemEditor interface The benefit is that any item can provide an editor for itself, producing an object that knows what parts of a business object can change and how they can be changed The only thing the user interface needs to do is use the

Editable interface to get an editor

Example A.21 Editable.java

1 public interface Editable {

2 public ItemEditor getEditor();

3 }

The ItemEditor interface provides two methods: getGUI and commitChanges The getGUI method is another Factory Method—it returns a JComponent that provides a Swing GUI to edit the current item This makes a very flexible system; to add a new type of item, the user interface can remain the same, because it only uses the

Editable and the ItemEditor interfaces

The JComponent returned by getGUI can have anything in it required to edit the item in the PIM The user

interface can simply the acquired JComponent in its editor window and use the JComponent functionality to edit the item Since not everything in an application needs to be graphical, it could also be a good idea to include a

getUI method that would return an Object or some other nongraphical interface

The second method, commitChanges, allows the UI to tell the editor that the user wants to finalize the changes he or she has made

Example A.22 ItemEditor.java

1 import javax.swing.JComponent;

2 public interface ItemEditor {

3 public JComponent getGUI();

4 public void commitChanges();

5 }

The following code shows the implementation for one of the PIM items, Contact The Contact class defines two attributes: the name of the person and their relationship with the user These attributes provide a sample of some

of the information, which could be included in an entry in the PIM

Example A.23 Contact.java

8 public class Contact implements Editable, Serializable {

9 private String name;

10 private String relationship;

11

12 public ItemEditor getEditor() {

13 return new ContactEditor();

14 }

15

16 private class ContactEditor implements ItemEditor, Serializable {

17 private transient JPanel panel;

18 private transient JTextField nameField;

19 private transient JTextField relationField;

20

21 public JComponent getGUI() {

22 if (panel == null) {

23 panel = new JPanel();

24 nameField = new JTextField(name);

25 relationField = new JTextField(relationship);

26 panel.setLayout(new GridLayout(2,2));

27 panel.add(new JLabel("Name:"));

Trang 12

Contact implements the Editable interface, and provides its own editor That editor only applies to the Contact

class, and needs to change certain attributes of the Contact, it is best to use an inner class The inner class has direct access to the attributes of the outer class If you used another (non-inner) class, Contact would need to provide accessor and mutator methods, making it harder to restrict access to the object’s private data

Note that the editor itself is not a Swing component, but only an object that can serve as a factory for such a component The greatest benefit is that you can serialize and send this object across a stream To implement this feature, declare all Swing component attributes in ContactEditor transient—they’re constructed when and where they’re needed

The EditorGui represents a generic editor you might use in the PIM Note that the class uses the ItemEditor

interface to entirely manage its edit window It constructs a JPanel for its edit window, and places the

JComponent obtained by the call to getGUI inside The Swing component provides all the edit capabilities for the

Contact, while the EditorGui provides control buttons and a JTextArea to display the state of the Contact

12 public class EditorGui implements ActionListener{

13 private JFrame mainFrame;

14 private JTextArea display;

15 private JButton update, exit;

16 private JPanel controlPanel, displayPanel, editorPanel;

17 private ItemEditor editor;

23 public void createGui(){

24 mainFrame = new JFrame("Factory Pattern Example");

25 Container content = mainFrame.getContentPane();

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

Trang 13

32 displayPanel = new JPanel();

33 display = new JTextArea(10, 40);

34 display.setEditable(false);

35 displayPanel.add(display);

36 content.add(displayPanel);

37

38 controlPanel = new JPanel();

39 update = new JButton("Update Item");

40 exit = new JButton("Exit");

54 public void actionPerformed(ActionEvent evt){

55 Object originator = evt.getSource();

64 private class WindowCloseManager extends WindowAdapter{

65 public void windowClosing(WindowEvent evt){

Note that the Update Item button makes a call to the ItemEditor 's commitChanges method

The RunPattern class runs this pattern by creating a Contact and an EditorGui object The EditorGui

constructor sets the ItemEditor for the example

Example A.25 RunPattern.java

7 public class RunPattern{

8 public static void main(String [] arguments){

9 System.out.println("Example for the FactoryMethod pattern");

19 System.out.println("It accepts an argument of type ItemEditor, and delegates");

20 System.out.println(" all editing tasks to its ItemEditor and the associated GUI.");

Trang 14

21 System.out.println(" The getEditor() Factory Method is used to obtain the

ItemEditor");

22 System.out.println(" for the example.");

23 System.out.println();

24 System.out.println("Notice that the editor in the top portion of the GUI is,");

25 System.out.println(" in fact, returned by the ItemEditor belonging to the");

26 System.out.println(" Contact class, and has appropriate fields for that class.");

Trang 15

Prototype

The Address class in this example uses the Prototype pattern to create an address based on an existing entry The core functionality for the pattern is defined in the interface Copyable

Example A.26 Copyable.java

1 public interface Copyable{

2 public Object copy();

3 }

The Copyable interface defines a copy method and guarantees that any classes that implement the interface will define a copy operation This example produces a shallow copy—that is, it copies the object references from the original address to the duplicate

The code also demonstrates an important feature of the copy operation: not all fields must necessarily be

duplicated In this case, the address type is not copied to the new object A user would manually specify a new address type from the PIM user interface

Example A.27 Address.java

1 public class Address implements Copyable{

2 private String type;

3 private String street;

4 private String city;

5 private String state;

6 private String zipCode;

7 public static final String EOL_STRING =

8 System.getProperty("line.separator");

9 public static final String COMMA = ",";

10 public static final String HOME = "home";

11 public static final String WORK = "work";

12

13 public Address(String initType, String initStreet,

14 String initCity, String initState, String initZip){

22 public Address(String initStreet, String initCity,

23 String initState, String initZip){

24 this(WORK, initStreet, initCity, initState, initZip);

31 public String getType(){ return type; }

32 public String getStreet(){ return street; }

33 public String getCity(){ return city; }

34 public String getState(){ return state; }

35 public String getZipCode(){ return zipCode; }

36

37 public void setType(String newType){ type = newType; }

38 public void setStreet(String newStreet){ street = newStreet; }

39 public void setCity(String newCity){ city = newCity; }

40 public void setState(String newState){ state = newState; }

41 public void setZipCode(String newZip){ zipCode = newZip; }

42

43 public Object copy(){

44 return new Address(street, city, state, zipCode);

45 }

46

47 public String toString(){

48 return "\t" + street + COMMA + " " + EOL_STRING +

49 "\t" + city + COMMA + " " + state + " " + zipCode;

50 }

51 }

Trang 16

The RunPattern class demonstrates the use of this pattern by creating an Address object, then duplicating that

object by calling its copy method The fact that the Address objects return two different hash code values

(numeric values that represent unique object identity) further confirms that the copy operation has produced a

different object from the first

Example A.28 RunPattern.java

1 public class RunPattern{

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

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

4 System.out.println();

5 System.out.println("This example will create an Address object,");

6 System.out.println(" which it will then duplicate by calling the");

7 System.out.println(" object's clone method.");

8 System.out.println();

9

10 System.out.println("Creating first address.");

11 Address address1 = new Address("8445 Silverado Trail", "Rutherford", "CA", "91734");

12 System.out.println("First address created.");

13 System.out.println(" Hash code = " + address1.hashCode());

14 System.out.println(address1);

15 System.out.println();

16

17 System.out.println("Creating second address using the clone() method.");

18 Address address2 = (Address)address1.copy();

19 System.out.println("Second address created.");

20 System.out.println(" Hash code = " + address2.hashCode());

Trang 17

Singleton

Application users want the option of undoing previous commands To support that functionality, a history list is needed That history list has to be accessible from everywhere in the PIM and only one instance of it is needed Therefore, it’s a perfect candidate for the implementation of the Singleton pattern

Example A.29 HistoryList.java

1 import java.util.ArrayList;

2 import java.util.Collections;

3 import java.util.List;

4 public class HistoryList{

5 private List history = Collections.synchronizedList(new ArrayList());

6 private static HistoryList instance = new HistoryList();

22 public String toString(){

23 StringBuffer result = new StringBuffer();

24 for (int i = 0; i < history.size(); i++){

Example A.30 SingletonGUI.java

11 public class SingletonGui implements ActionListener{

12 private JFrame mainFrame;

13 private JTextArea display;

14 private JButton newContact, newAppointment, undo, refresh, exit;

15 private JPanel controlPanel, displayPanel;

16 private static int historyCount;

17

18 public void createGui(){

19 mainFrame = new JFrame("Singleton Pattern Example");

Trang 18

20 Container content = mainFrame.getContentPane();

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

22

23 displayPanel = new JPanel();

24 display = new JTextArea(20, 60);

25 display.setEditable(false);

26 displayPanel.add(display);

27 content.add(displayPanel);

28

29 controlPanel = new JPanel();

30 newContact = new JButton("Create contact");

31 newAppointment = new JButton("Create appointment");

32 undo = new JButton("Undo");

33 refresh = new JButton("Refresh");

34 exit = new JButton("Exit");

53 public void refreshDisplay(String actionMessage){

54 display.setText(actionMessage + "\nCOMMAND HISTORY:\n" +

55 HistoryList.getInstance().toString());

56 }

57

58 public void actionPerformed(ActionEvent evt){

59 Object originator = evt.getSource();

60 if (originator == newContact){

61 addCommand(" New Contact");

62 }

63 else if (originator == newAppointment){

64 addCommand(" New Appointment");

77 private class WindowCloseManager extends WindowAdapter{

78 public void windowClosing(WindowEvent evt){

88 private void undoCommand(){

89 Object result = HistoryList.getInstance().undoCommand();

Ngày đăng: 09/08/2014, 12:22