Java/Design Pattern/Builder Pattern
Builder Pattern - Example
<source lang="java">
/* Software Architecture Design Patterns in Java by Partha Kuchana Auerbach Publications
- /
import java.awt.BorderLayout; import java.awt.Container; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Calendar; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; public class SearchManager extends JFrame {
public static final String GET_SQL = "Get SQL"; public static final String EXIT = "Exit"; public static final String CANDIDATE_SRCH = "Candidate Search"; public static final String EMPLOYER_SRCH = "Employer Search"; public static final String BLANK = ""; private JComboBox cmbSearchType; private JPanel pSearchCriteria; private JTextArea txtSQL; public SearchManager() throws Exception { super("Builder Pattern - Example"); // Create controls cmbSearchType = new JComboBox(); txtSQL = new JTextArea(" The SQL statement will be displayed here.", 5, 25); txtSQL.setFont(new Font("Serif", Font.ITALIC, 12)); txtSQL.setLineWrap(true); txtSQL.setWrapStyleWord(true); pSearchCriteria = new JPanel(); cmbSearchType.addItem(SearchManager.BLANK); cmbSearchType.addItem(SearchManager.CANDIDATE_SRCH); cmbSearchType.addItem(SearchManager.EMPLOYER_SRCH); //Create Labels JLabel lblSearchType = new JLabel("Search:"); JLabel lblWhereClause = new JLabel("SQL:"); JLabel lblSearchCriteria = new JLabel("Search Criteria:"); //Create the open button JButton btnGetWhereClause = new JButton(SearchManager.GET_SQL); btnGetWhereClause.setMnemonic(KeyEvent.VK_G); JButton btnExit = new JButton(SearchManager.EXIT); btnExit.setMnemonic(KeyEvent.VK_X); buttonHandler vf = new buttonHandler(this); btnGetWhereClause.addActionListener(vf); btnExit.addActionListener(vf); cmbSearchType.addActionListener(vf); //For layout purposes, put the buttons in a separate panel JPanel buttonPanel = new JPanel(); //**************************************************** GridBagLayout gridbag = new GridBagLayout(); buttonPanel.setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); buttonPanel.add(lblSearchType); buttonPanel.add(cmbSearchType); buttonPanel.add(lblSearchCriteria); buttonPanel.add(pSearchCriteria); buttonPanel.add(lblWhereClause); buttonPanel.add(txtSQL); buttonPanel.add(btnGetWhereClause); buttonPanel.add(btnExit); gbc.insets.top = 5; gbc.insets.bottom = 5; gbc.insets.left = 5; gbc.insets.right = 5; gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 0; gbc.gridy = 0; gridbag.setConstraints(lblSearchType, gbc); gbc.gridx = 1; gbc.gridy = 0; gridbag.setConstraints(cmbSearchType, gbc); gbc.gridx = 0; gbc.gridy = 1; gridbag.setConstraints(lblSearchCriteria, gbc); gbc.gridx = 1; gbc.gridy = 2; gridbag.setConstraints(pSearchCriteria, gbc); gbc.gridx = 0; gbc.gridy = 3; gridbag.setConstraints(lblWhereClause, gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridwidth = 3; gbc.gridheight = 5; gbc.gridx = 1; gbc.gridy = 3; gridbag.setConstraints(txtSQL, gbc); gbc.gridwidth = 1; gbc.gridheight = 1; gbc.anchor = GridBagConstraints.EAST; gbc.insets.left = 2; gbc.insets.right = 2; gbc.insets.top = 40; gbc.gridx = 0; gbc.gridy = 8; gridbag.setConstraints(btnGetWhereClause, gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 1; gbc.gridy = 8; gridbag.setConstraints(btnExit, gbc); //**************************************************** //Add the buttons and the log to the frame Container contentPane = getContentPane(); contentPane.add(buttonPanel, BorderLayout.CENTER); try { UIManager.setLookAndFeel(new WindowsLookAndFeel()); SwingUtilities.updateComponentTreeUI(SearchManager.this); } catch (Exception ex) { System.out.println(ex); } } public void setSQL(String str) { txtSQL.setText(str); } public String getSearchType() { return (String) cmbSearchType.getSelectedItem(); } public JComboBox getSearchTypeCtrl() { return cmbSearchType; } public void displayNewUI(JPanel panel) { pSearchCriteria.removeAll(); pSearchCriteria.add(panel); pSearchCriteria.validate(); validate(); } public static void main(String[] args) throws Exception { JFrame frame = new SearchManager(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); //frame.pack(); frame.setSize(450, 400); frame.setVisible(true); }
} class buttonHandler implements ActionListener {
SearchManager manager; UIBuilder builder; public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(SearchManager.EXIT)) { System.exit(1); } if (e.getActionCommand().equals(SearchManager.GET_SQL)) { manager.setSQL(builder.getSQL()); } if (e.getSource() == manager.getSearchTypeCtrl()) { String selection = manager.getSearchType(); if (selection.equals("") == false) { BuilderFactory factory = new BuilderFactory(); //create an appropriate builder instance builder = factory.getUIBuilder(selection); //configure the director with the builder UIDirector director = new UIDirector(builder); //director invokes different builder // methods director.build(); //get the final build object JPanel UIObj = builder.getSearchUI(); manager.displayNewUI(UIObj); } } } public buttonHandler() { } public buttonHandler(SearchManager inManager) { manager = inManager; }
} class MyUtil {
public static String handleRecordLength(String str, int len) { int i; String retStr = ""; if (str.length() > len) { retStr = str.substring(0, len); } else { i = len - str.length(); for (int j = 0; j < i; j++) { str = str + " "; } retStr = str; } return retStr; }
} class BuilderFactory {
public UIBuilder getUIBuilder(String str) { UIBuilder builder = null; if (str.equals(SearchManager.CANDIDATE_SRCH)) { builder = new CandSrchBuilder(); } else if (str.equals(SearchManager.EMPLOYER_SRCH)) { builder = new EmpSrchBuilder(); } return builder; }
} abstract class UIBuilder {
protected JPanel searchUI; public abstract void addUIControls(); public abstract void initialize(); public abstract String getSQL(); public JPanel getSearchUI() { return searchUI; }
} class UIDirector {
private UIBuilder builder; public UIDirector(UIBuilder bldr) { builder = bldr; } public void build() { builder.addUIControls(); builder.initialize(); }
} class EmpSrchBuilder extends UIBuilder {
JLabel lblUserName = new JLabel("Name :"); private JTextField txtUserName = new JTextField(15); private JTextField txtCity = new JTextField(15); private JTextField txtRenewal = new JTextField(10); public void addUIControls() { searchUI = new JPanel(); JLabel lblUserName = new JLabel("Name :"); JLabel lblCity = new JLabel("City:"); JLabel lblRenewal = new JLabel("Membership Renewal :"); GridBagLayout gridbag = new GridBagLayout(); searchUI.setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); searchUI.add(lblUserName); searchUI.add(txtUserName); searchUI.add(lblCity); searchUI.add(txtCity); searchUI.add(lblRenewal); searchUI.add(txtRenewal); gbc.anchor = GridBagConstraints.WEST; gbc.insets.top = 5; gbc.insets.bottom = 5; gbc.insets.left = 5; gbc.insets.right = 5; gbc.gridx = 0; gbc.gridy = 0; gridbag.setConstraints(lblUserName, gbc); gbc.gridx = 0; gbc.gridy = 1; gridbag.setConstraints(lblCity, gbc); gbc.gridx = 0; gbc.gridy = 2; gridbag.setConstraints(lblRenewal, gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 1; gbc.gridy = 0; gridbag.setConstraints(txtUserName, gbc); gbc.gridx = 1; gbc.gridy = 1; gridbag.setConstraints(txtCity, gbc); gbc.gridx = 1; gbc.gridy = 2; gridbag.setConstraints(txtRenewal, gbc); } public void initialize() { Calendar cal = Calendar.getInstance(); cal.setTime(new java.util.Date()); txtUserName.setText("Enter UserName Here"); txtRenewal.setText((cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DATE) + "/" + cal.get(Calendar.YEAR)); } public String getSQL() { return ("Select * from Employer where Username="" + txtUserName.getText() + """ + " and City="" + txtCity.getText() + "" and DateRenewal="" + txtRenewal.getText() + """); }
} class CandSrchBuilder extends UIBuilder {
private JTextField txtUserName = new JTextField(15); private JTextField txtSkill = new JTextField(10); private JComboBox cmbExperience = new JComboBox(); public void addUIControls() { searchUI = new JPanel(); JLabel lblUserName = new JLabel("Name :"); JLabel lblExperienceRange = new JLabel("Experience(min Yrs.):"); JLabel lblSkill = new JLabel("Skill :"); cmbExperience.addItem("<5"); cmbExperience.addItem(">5"); GridBagLayout gridbag = new GridBagLayout(); searchUI.setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.WEST; searchUI.add(lblUserName); searchUI.add(txtUserName); searchUI.add(lblExperienceRange); searchUI.add(cmbExperience); searchUI.add(lblSkill); searchUI.add(txtSkill); gbc.insets.top = 5; gbc.insets.bottom = 5; gbc.insets.left = 5; gbc.insets.right = 5; gbc.gridx = 0; gbc.gridy = 0; gridbag.setConstraints(lblUserName, gbc); gbc.gridx = 0; gbc.gridy = 1; gridbag.setConstraints(lblExperienceRange, gbc); gbc.gridx = 0; gbc.gridy = 2; gridbag.setConstraints(lblSkill, gbc); gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 1; gbc.gridy = 0; gridbag.setConstraints(txtUserName, gbc); gbc.gridx = 1; gbc.gridy = 1; gridbag.setConstraints(cmbExperience, gbc); gbc.gridx = 1; gbc.gridy = 2; gridbag.setConstraints(txtSkill, gbc); } public void initialize() { txtUserName.setText("Enter UserName Here"); txtSkill.setText("Internet Tech"); } public String getSQL() { String experience = (String) cmbExperience.getSelectedItem(); return ("Select * from Candidate where Username="" + txtUserName.getText() + "" and Experience " + experience + " and Skill="" + txtSkill.getText() + """); }
}
</source>
Builder Pattern in Java
<source lang="java">
//[C] 2002 Sun Microsystems, Inc.--- import java.io.Serializable; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; public class RunBuilderPattern {
private static Calendar dateCreator = Calendar.getInstance(); public static void main(String [] arguments){ Appointment appt = null; System.out.println("Example for the Builder pattern"); System.out.println(); System.out.println("This example demonstrates the use of the Builder"); System.out.println("pattern to create Appointment objects for the PIM."); System.out.println(); System.out.println("Creating a Scheduler for the example."); Scheduler pimScheduler = new Scheduler(); System.out.println("Creating an AppointmentBuilder for the example."); System.out.println(); AppointmentBuilder apptBuilder = new AppointmentBuilder(); try{ System.out.println("Creating a new Appointment with an AppointmentBuilder"); appt = pimScheduler.createAppointment( apptBuilder, createDate(2066, 9, 22, 12, 30), null, "Trek convention", new LocationImpl("Fargo, ND"), createAttendees(4)); System.out.println("Successfully created an Appointment."); System.out.println("Appointment information:"); System.out.println(appt); System.out.println(); } catch (InformationRequiredException exc){ printExceptions(exc); } System.out.println("Creating a MeetingBuilder for the example."); MeetingBuilder mtgBuilder = new MeetingBuilder(); try{ System.out.println("Creating a new Appointment with a MeetingBuilder"); System.out.println("(notice that the same create arguments will produce"); System.out.println(" an exception, since the MeetingBuilder enforces a"); System.out.println(" mandatory end date)"); appt = pimScheduler.createAppointment( mtgBuilder, createDate(2066, 9, 22, 12, 30), null, "Trek convention", new LocationImpl("Fargo, ND"), createAttendees(4)); System.out.println("Successfully created an Appointment."); System.out.println("Appointment information:"); System.out.println(appt); System.out.println(); } catch (InformationRequiredException exc){ printExceptions(exc); } System.out.println("Creating a new Appointment with a MeetingBuilder"); System.out.println("(This time, the MeetingBuilder will provide an end date)"); try{ appt = pimScheduler.createAppointment( mtgBuilder, createDate(2002, 4, 1, 10, 00), createDate(2002, 4, 1, 11, 30), "OOO Meeting", new LocationImpl("Butte, MT"), createAttendees(2)); System.out.println("Successfully created an Appointment."); System.out.println("Appointment information:"); System.out.println(appt); System.out.println(); } catch (InformationRequiredException exc){ printExceptions(exc); } } public static Date createDate(int year, int month, int day, int hour, int minute){ dateCreator.set(year, month, day, hour, minute); return dateCreator.getTime(); } public static ArrayList createAttendees(int numberToCreate){ ArrayList group = new ArrayList(); for (int i = 0; i < numberToCreate; i++){ group.add(new ContactImpl("John", getLastName(i), "Employee (non-exempt)", "Yoyodyne Corporation")); } return group; } public static String getLastName(int index){ String name = ""; switch (index % 6){ case 0: name = "Worfin"; break; case 1: name = "Smallberries"; break; case 2: name = "Bigbootee"; break; case 3: name = "Haugland"; break; case 4: name = "Maassen"; break; case 5: name = "Sterling"; break; } return name; } public static void printExceptions(InformationRequiredException exc){ int statusCode = exc.getInformationRequired(); System.out.println("Unable to create Appointment: additional information is required"); if ((statusCode & InformationRequiredException.START_DATE_REQUIRED) > 0){ System.out.println(" A start date is required for this appointment to be complete."); } if ((statusCode & InformationRequiredException.END_DATE_REQUIRED) > 0){ System.out.println(" An end date is required for this appointment to be complete."); } if ((statusCode & InformationRequiredException.DESCRIPTION_REQUIRED) > 0){ System.out.println(" A description is required for this appointment to be complete."); } if ((statusCode & InformationRequiredException.ATTENDEE_REQUIRED) > 0){ System.out.println(" At least one attendee is required for this appointment to be complete."); } if ((statusCode & InformationRequiredException.LOCATION_REQUIRED) > 0){ System.out.println(" A location is required for this appointment to be complete."); } System.out.println(); }
} interface Contact extends Serializable{
public static final String SPACE = " "; public String getFirstName(); public String getLastName(); public String getTitle(); public String getOrganization(); public void setFirstName(String newFirstName); public void setLastName(String newLastName); public void setTitle(String newTitle); public void setOrganization(String newOrganization);
} class ContactImpl implements Contact{
private String firstName; private String lastName; private String title; private String organization; public ContactImpl(String newFirstName, String newLastName, String newTitle, String newOrganization){ firstName = newFirstName; lastName = newLastName; title = newTitle; organization = newOrganization; } public String getFirstName(){ return firstName; } public String getLastName(){ return lastName; } public String getTitle(){ return title; } public String getOrganization(){ return organization; } public void setFirstName(String newFirstName){ firstName = newFirstName; } public void setLastName(String newLastName){ lastName = newLastName; } public void setTitle(String newTitle){ title = newTitle; } public void setOrganization(String newOrganization){ organization = newOrganization; } public String toString(){ return firstName + SPACE + lastName; }
} interface Location extends Serializable{
public String getLocation(); public void setLocation(String newLocation);
} class LocationImpl implements Location{
private String location; public LocationImpl(){ } public LocationImpl(String newLocation){ location = newLocation; } public String getLocation(){ return location; } public void setLocation(String newLocation){ location = newLocation; } public String toString(){ return location; }
} class Scheduler{
public Appointment createAppointment(AppointmentBuilder builder, Date startDate, Date endDate, String description, Location location, ArrayList attendees) throws InformationRequiredException{ if (builder == null){ builder = new AppointmentBuilder(); } builder.buildAppointment(); builder.buildDates(startDate, endDate); builder.buildDescription(description); builder.buildAttendees(attendees); builder.buildLocation(location); return builder.getAppointment(); }
} class Appointment{
private Date startDate; private Date endDate; private String description; private ArrayList attendees = new ArrayList(); private Location location; public static final String EOL_STRING = System.getProperty("line.separator"); public Date getStartDate(){ return startDate; } public Date getEndDate(){ return endDate; } public String getDescription(){ return description; } public ArrayList getAttendees(){ return attendees; } public Location getLocation(){ return location; } public void setDescription(String newDescription){ description = newDescription; } public void setLocation(Location newLocation){ location = newLocation; } public void setStartDate(Date newStartDate){ startDate = newStartDate; } public void setEndDate(Date newEndDate){ endDate = newEndDate; } public void setAttendees(ArrayList newAttendees){ if (newAttendees != null){ attendees = newAttendees; } } public void addAttendee(Contact attendee){ if (!attendees.contains(attendee)){ attendees.add(attendee); } } public void removeAttendee(Contact attendee){ attendees.remove(attendee); } public String toString(){ return " Description: " + description + EOL_STRING + " Start Date: " + startDate + EOL_STRING + " End Date: " + endDate + EOL_STRING + " Location: " + location + EOL_STRING + " Attendees: " + attendees; }
} class AppointmentBuilder{
public static final int START_DATE_REQUIRED = 1; public static final int END_DATE_REQUIRED = 2; public static final int DESCRIPTION_REQUIRED = 4; public static final int ATTENDEE_REQUIRED = 8; public static final int LOCATION_REQUIRED = 16; protected Appointment appointment; protected int requiredElements; public void buildAppointment(){ appointment = new Appointment(); } public void buildDates(Date startDate, Date endDate){ Date currentDate = new Date(); if ((startDate != null) && (startDate.after(currentDate))){ appointment.setStartDate(startDate); } if ((endDate != null) && (endDate.after(startDate))){ appointment.setEndDate(endDate); } } public void buildDescription(String newDescription){ appointment.setDescription(newDescription); } public void buildAttendees(ArrayList attendees){ if ((attendees != null) && (!attendees.isEmpty())){ appointment.setAttendees(attendees); } } public void buildLocation(Location newLocation){ if (newLocation != null){ appointment.setLocation(newLocation); } } public Appointment getAppointment() throws InformationRequiredException{ requiredElements = 0; if (appointment.getStartDate() == null){ requiredElements += START_DATE_REQUIRED; } if (appointment.getLocation() == null){ requiredElements += LOCATION_REQUIRED; } if (appointment.getAttendees().isEmpty()){ requiredElements += ATTENDEE_REQUIRED; } if (requiredElements > 0){ throw new InformationRequiredException(requiredElements); } return appointment; } public int getRequiredElements(){ return requiredElements; }
} class InformationRequiredException extends Exception{
private static final String MESSAGE = "Appointment cannot be created because further information is required"; public static final int START_DATE_REQUIRED = 1; public static final int END_DATE_REQUIRED = 2; public static final int DESCRIPTION_REQUIRED = 4; public static final int ATTENDEE_REQUIRED = 8; public static final int LOCATION_REQUIRED = 16; private int informationRequired; public InformationRequiredException(int itemsRequired){ super(MESSAGE); informationRequired = itemsRequired; } public int getInformationRequired(){ return informationRequired; }
} class MeetingBuilder extends AppointmentBuilder{
public Appointment getAppointment() throws InformationRequiredException{ try{ super.getAppointment(); } finally{ if (appointment.getEndDate() == null){ requiredElements += END_DATE_REQUIRED; } if (requiredElements > 0){ throw new InformationRequiredException(requiredElements); } } return appointment; }
}
</source>