Java/Design Pattern/Factory Pattern

Материал из Java эксперт
Перейти к: навигация, поиск

Abstract Factory 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.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 javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; public class AutoSearchUI extends JFrame {

 public static final String newline = "\n";
 public static final String SEARCH = "Search";
 public static final String EXIT = "Exit";
 public static final String CAR = "Car";
 public static final String SUV = "SUV";
 private JComboBox cmbVehicleCategory, cmbVehicleType;
 private JLabel lblVehicleCategory, lblVehicleType, lblCarName,
     lblCarNameValue;
 public AutoSearchUI() {
   super("Abstract Factory - Example");
   cmbVehicleCategory = new JComboBox();
   cmbVehicleCategory.addItem(VehicleFactory.LUXURY_VEHICLE);
   cmbVehicleCategory.addItem(VehicleFactory.NON_LUXURY_VEHICLE);
   cmbVehicleType = new JComboBox();
   cmbVehicleType.addItem(AutoSearchUI.CAR);
   cmbVehicleType.addItem(AutoSearchUI.SUV);
   lblVehicleCategory = new JLabel("Vehicle Category:");
   lblVehicleType = new JLabel("VehicleType:");
   lblCarName = new JLabel("Search Result:");
   lblCarNameValue = new JLabel(" Please click on Search button");
   //Create the open button
   JButton openButton = new JButton(AutoSearchUI.SEARCH);
   openButton.setMnemonic(KeyEvent.VK_S);
   JButton exitButton = new JButton(AutoSearchUI.EXIT);
   exitButton.setMnemonic(KeyEvent.VK_X);
   ButtonHandler objButtonHandler = new ButtonHandler(this);
   openButton.addActionListener(objButtonHandler);
   exitButton.addActionListener(new ButtonHandler());
   JPanel buttonPanel = new JPanel();
   //****************************************************
   GridBagLayout gridbag = new GridBagLayout();
   buttonPanel.setLayout(gridbag);
   GridBagConstraints gbc = new GridBagConstraints();
   buttonPanel.add(lblVehicleCategory);
   buttonPanel.add(cmbVehicleCategory);
   buttonPanel.add(lblVehicleType);
   buttonPanel.add(cmbVehicleType);
   buttonPanel.add(lblCarName);
   buttonPanel.add(lblCarNameValue);
   buttonPanel.add(openButton);
   buttonPanel.add(exitButton);
   gbc.insets.top = 5;
   gbc.insets.bottom = 5;
   gbc.insets.left = 5;
   gbc.insets.right = 5;
   gbc.anchor = GridBagConstraints.EAST;
   gbc.gridx = 0;
   gbc.gridy = 0;
   gridbag.setConstraints(lblVehicleCategory, gbc);
   gbc.anchor = GridBagConstraints.WEST;
   gbc.gridx = 1;
   gbc.gridy = 0;
   gridbag.setConstraints(cmbVehicleCategory, gbc);
   gbc.anchor = GridBagConstraints.EAST;
   gbc.gridx = 0;
   gbc.gridy = 1;
   gridbag.setConstraints(lblVehicleType, gbc);
   gbc.anchor = GridBagConstraints.WEST;
   gbc.gridx = 1;
   gbc.gridy = 1;
   gridbag.setConstraints(cmbVehicleType, gbc);
   gbc.anchor = GridBagConstraints.EAST;
   gbc.gridx = 0;
   gbc.gridy = 2;
   gridbag.setConstraints(lblCarName, gbc);
   gbc.anchor = GridBagConstraints.WEST;
   gbc.gridx = 1;
   gbc.gridy = 2;
   gridbag.setConstraints(lblCarNameValue, gbc);
   gbc.insets.left = 2;
   gbc.insets.right = 2;
   gbc.insets.top = 40;
   gbc.anchor = GridBagConstraints.EAST;
   gbc.gridx = 0;
   gbc.gridy = 5;
   gridbag.setConstraints(openButton, gbc);
   gbc.anchor = GridBagConstraints.WEST;
   gbc.gridx = 1;
   gbc.gridy = 5;
   gridbag.setConstraints(exitButton, 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(AutoSearchUI.this);
   } catch (Exception ex) {
     System.out.println(ex);
   }
 }
 public static void main(String[] args) {
   JFrame frame = new AutoSearchUI();
   frame.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   //frame.pack();
   frame.setSize(400, 300);
   frame.setVisible(true);
 }
 public String getSelectedCategory() {
   return (String) cmbVehicleCategory.getSelectedItem();
 }
 public String getSelectedType() {
   return (String) cmbVehicleType.getSelectedItem();
 }
 public void setResult(String searchResult) {
   lblCarNameValue.setText(searchResult);
 }

} // End of class AutoSearchUI class ButtonHandler implements ActionListener {

 AutoSearchUI objAutoSearchUI;
 public void actionPerformed(ActionEvent e) {
   String searchResult = null;
   if (e.getActionCommand().equals(AutoSearchUI.EXIT)) {
     System.exit(1);
   }
   if (e.getActionCommand().equals(AutoSearchUI.SEARCH)) {
     //get input values
     String vhCategory = objAutoSearchUI.getSelectedCategory();
     String vhType = objAutoSearchUI.getSelectedType();
     //get one of Luxury or NonLuxury vehicle factories
     VehicleFactory vf = VehicleFactory.getVehicleFactory(vhCategory);
     if (vhType.equals(AutoSearchUI.CAR)) {
       Car c = vf.getCar();
       searchResult = "Name: " + c.getCarName() + "  Features: "
           + c.getCarFeatures();
     }
     if (vhType.equals(AutoSearchUI.SUV)) {
       SUV s = vf.getSUV();
       searchResult = "Name: " + s.getSUVName() + "  Features: "
           + s.getSUVFeatures();
     }
     objAutoSearchUI.setResult(searchResult);
   }
 }
 public ButtonHandler() {
 }
 public ButtonHandler(AutoSearchUI inObjAutoSearchUI) {
   objAutoSearchUI = inObjAutoSearchUI;
 }

} // End of class ButtonHandler abstract class VehicleFactory {

 public static final String LUXURY_VEHICLE = "Luxury";
 public static final String NON_LUXURY_VEHICLE = "Non-Luxury";
 public abstract Car getCar();
 public abstract SUV getSUV();
 public static VehicleFactory getVehicleFactory(String type) {
   if (type.equals(VehicleFactory.LUXURY_VEHICLE))
     return new LuxuryVehicleFactory();
   if (type.equals(VehicleFactory.NON_LUXURY_VEHICLE))
     return new NonLuxuryVehicleFactory();
   return new LuxuryVehicleFactory();
 }

} // End of class interface Car {

 public String getCarName();
 public String getCarFeatures();

} // End of class interface SUV {

 public String getSUVName();
 public String getSUVFeatures();

} // End of class class LuxuryCar implements Car {

 private String name;
 public LuxuryCar(String cName) {
   name = cName;
 }
 public String getCarName() {
   return name;
 }
 public String getCarFeatures() {
   return "Luxury Car Features ";
 };

} // End of class class LuxurySUV implements SUV {

 private String name;
 public LuxurySUV(String sName) {
   name = sName;
 }
 public String getSUVName() {
   return name;
 }
 public String getSUVFeatures() {
   return "Luxury SUV Features ";
 };

} // End of class class LuxuryVehicleFactory extends VehicleFactory {

 public Car getCar() {
   return new LuxuryCar("L-C");
 }
 public SUV getSUV() {
   return new LuxurySUV("L-S");
 }

} // End of class class NonLuxuryCar implements Car {

 private String name;
 public NonLuxuryCar(String cName) {
   name = cName;
 }
 public String getCarName() {
   return name;
 }
 public String getCarFeatures() {
   return "Non-Luxury Car Features ";
 };

} // End of class class NonLuxurySUV implements SUV {

 private String name;
 public NonLuxurySUV(String sName) {
   name = sName;
 }
 public String getSUVName() {
   return name;
 }
 public String getSUVFeatures() {
   return "Non-Luxury SUV Features ";
 };

} // End of class class NonLuxuryVehicleFactory extends VehicleFactory {

 public Car getCar() {
   return new NonLuxuryCar("NL-C");
 }
 public SUV getSUV() {
   return new NonLuxurySUV("NL-S");
 }

} // End of class


      </source>
   
  
 
  



Abstract Factory Pattern in Java 2

   <source lang="java">

//[C] 2002 Sun Microsystems, Inc.--- public class RunAbstractFactoryPattern {

   public static void main(String [] arguments){
       System.out.println("Example for the AbstractFactory pattern");
       System.out.println();
       System.out.println(" (take a look in the RunPattern code. Notice that you can");
       System.out.println("  use the Address and PhoneNumber classes when writing");
       System.out.println("  almost all of the code. This allows you to write a very");
       System.out.println("  generic framework, and plug in Concrete Factories");
       System.out.println("  and Products to specialize the behavior of your code)");
       System.out.println();
       
       System.out.println("Creating U.S. Address and Phone Number:");
       AddressFactory usAddressFactory = new USAddressFactory();
       Address usAddress = usAddressFactory.createAddress();
       PhoneNumber usPhone = usAddressFactory.createPhoneNumber();
       
       usAddress.setStreet("142 Lois Lane");
       usAddress.setCity("Metropolis");
       usAddress.setRegion("WY");
       usAddress.setPostalCode("54321");
       usPhone.setPhoneNumber("7039214722");
       
       System.out.println("U.S. address:");
       System.out.println(usAddress.getFullAddress());
       System.out.println("U.S. phone number:");
       System.out.println(usPhone.getPhoneNumber());
       System.out.println();
       System.out.println();
       
       System.out.println("Creating French Address and Phone Number:");
       AddressFactory frenchAddressFactory = new FrenchAddressFactory();
       Address frenchAddress = frenchAddressFactory.createAddress();
       PhoneNumber frenchPhone = frenchAddressFactory.createPhoneNumber();
       
       frenchAddress.setStreet("21 Rue Victor Hugo");
       frenchAddress.setCity("Courbevoie");
       frenchAddress.setPostalCode("40792");
       frenchPhone.setPhoneNumber("011324290");
       
       System.out.println("French address:");
       System.out.println(frenchAddress.getFullAddress());
       System.out.println("French phone number:");
       System.out.println(frenchPhone.getPhoneNumber());
   }

} class FrenchAddressFactory implements AddressFactory{

   public Address createAddress(){
       return new FrenchAddress();
   }
   
   public PhoneNumber createPhoneNumber(){
       return new FrenchPhoneNumber();
   }

} class USAddressFactory implements AddressFactory{

   public Address createAddress(){
       return new USAddress();
   }
   
   public PhoneNumber createPhoneNumber(){
       return new USPhoneNumber();
   }

} class USPhoneNumber extends PhoneNumber{

   private static final String COUNTRY_CODE = "01";
   private static final int NUMBER_LENGTH = 10;
   
   public String getCountryCode(){ return COUNTRY_CODE; }
   
   public void setPhoneNumber(String newNumber){
       if (newNumber.length() == NUMBER_LENGTH){
           super.setPhoneNumber(newNumber);
       }
   }

} interface AddressFactory{

   public Address createAddress();
   public PhoneNumber createPhoneNumber();

} abstract class Address{

   private String street;
   private String city;
   private String region;
   private String postalCode;
   
   public static final String EOL_STRING =
       System.getProperty("line.separator");
   public static final String SPACE = " ";
   
   public String getStreet(){ return street; }
   public String getCity(){ return city; }
   public String getPostalCode(){ return postalCode; }
   public String getRegion(){ return region; }
   public abstract String getCountry();
   
   public String getFullAddress(){
       return street + EOL_STRING +
           city + SPACE + postalCode + EOL_STRING;
   }
   
   public void setStreet(String newStreet){ street = newStreet; }
   public void setCity(String newCity){ city = newCity; }
   public void setRegion(String newRegion){ region = newRegion; }
   public void setPostalCode(String newPostalCode){ postalCode = newPostalCode; }

} abstract class PhoneNumber{

   private String phoneNumber;
   public abstract String getCountryCode();
   
   public String getPhoneNumber(){ return phoneNumber; }
   
   public void setPhoneNumber(String newNumber){
       try{
           Long.parseLong(newNumber);
           phoneNumber = newNumber;
       }
       catch (NumberFormatException exc){
       }
   }

}

class FrenchPhoneNumber extends PhoneNumber{

   private static final String COUNTRY_CODE = "33";
   private static final int NUMBER_LENGTH = 9;
   
   public String getCountryCode(){ return COUNTRY_CODE; }
   
   public void setPhoneNumber(String newNumber){
       if (newNumber.length() == NUMBER_LENGTH){
           super.setPhoneNumber(newNumber);
       }
   }

} class FrenchAddress extends Address{

   private static final String COUNTRY = "FRANCE";
   
   public String getCountry(){ return COUNTRY; }
   
   public String getFullAddress(){
       return getStreet() + EOL_STRING +
           getPostalCode() + SPACE + getCity() +
           EOL_STRING + COUNTRY + EOL_STRING;
   }

} class USAddress extends Address{

   private static final String COUNTRY = "UNITED STATES";
   private static final String COMMA = ",";
   
   public String getCountry(){ return COUNTRY; }
   
   public String getFullAddress(){
       return getStreet() + EOL_STRING +
           getCity() + COMMA + SPACE + getRegion() +
           SPACE + getPostalCode() + EOL_STRING +
           COUNTRY + EOL_STRING;
   }

}


      </source>
   
  
 
  



Factory Method Pattern in Java

   <source lang="java">

//[C] 2002 Sun Microsystems, Inc.--- import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.Serializable; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField;

public class RunFactoryMethodPattern {

   public static void main(String [] arguments){
       System.out.println("Example for the FactoryMethod pattern");
       System.out.println();
       
       System.out.println("Creating a Contact object");
       System.out.println();
       Contact someone = new Contact();
       
       System.out.println("Creating a GUI editor for the Contact");
       System.out.println();
       System.out.println("The GUI defined in the EditorGui class is a truly generic editor.");
       System.out.println("It accepts an argument of type ItemEditor, and delegates");
       System.out.println(" all editing tasks to its ItemEditor and the associated GUI.");
       System.out.println(" The getEditor() Factory Method is used to obtain the ItemEditor");
       System.out.println(" for the example.");
       System.out.println();
       System.out.println("Notice that the editor in the top portion of the GUI is,");
       System.out.println(" in fact, returned by the ItemEditor belonging to the");
       System.out.println(" Contact class, and has appropriate fields for that class.");
       
       EditorGui runner = new EditorGui(someone.getEditor());
       runner.createGui();
   }

} class EditorGui implements ActionListener{

   private JFrame mainFrame;
   private JTextArea display;
   private JButton update, exit;
   private JPanel controlPanel, displayPanel, editorPanel;
   private ItemEditor editor;
   
   public EditorGui(ItemEditor edit){
       editor = edit;
   }
   
   public void createGui(){
       mainFrame = new JFrame("Factory Pattern Example");
       Container content = mainFrame.getContentPane();
       content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
       
       editorPanel = new JPanel();
       editorPanel.add(editor.getGUI());
       content.add(editorPanel);
       
       displayPanel = new JPanel();
       display = new JTextArea(10, 40);
       display.setEditable(false);
       displayPanel.add(display);
       content.add(displayPanel);
       
       controlPanel = new JPanel();
       update = new JButton("Update Item");
       exit = new JButton("Exit");
       controlPanel.add(update);
       controlPanel.add(exit);
       content.add(controlPanel);
       
       update.addActionListener(this);
       exit.addActionListener(this);
       
       mainFrame.addWindowListener(new WindowCloseManager());
       mainFrame.pack();
       mainFrame.setVisible(true);
   }
   
   
   public void actionPerformed(ActionEvent evt){
       Object originator = evt.getSource();
       if (originator == update){
           updateItem();
       }
       else if (originator == exit){
           exitApplication();
       }
   }
   
   private class WindowCloseManager extends WindowAdapter{
       public void windowClosing(WindowEvent evt){
           exitApplication();
       }
   }
   
   private void updateItem(){
       editor.rumitChanges();
       display.setText(editor.toString());
   }
   
   private void exitApplication(){
       System.exit(0);
   }

} class Contact implements Editable, Serializable {

   private String name;
   private String relationship;
   public ItemEditor getEditor() {
       return new ContactEditor();
   }
   
   private class ContactEditor implements ItemEditor, Serializable {
       private transient JPanel panel;
       private transient JTextField nameField;
       private transient JTextField relationField;
       
       public JComponent getGUI() {
           if (panel == null) {
               panel = new JPanel();
               nameField = new JTextField(name);
               relationField = new JTextField(relationship);
               panel.setLayout(new GridLayout(2,2));
               panel.add(new JLabel("Name:"));
               panel.add(nameField);
               panel.add(new JLabel("Relationship:"));
               panel.add(relationField);
           } else {
               nameField.setText(name);
               relationField.setText(relationship);
           }
           return panel;
       }
       
       public void commitChanges() {
           if (panel != null) {
               name = nameField.getText();
               relationship = relationField.getText();
           }
       }
       
       public String toString(){
           return "\nContact:\n" +
               "    Name: " + name + "\n" +
               "    Relationship: " + relationship;
       }
   }

} interface Editable {

   public ItemEditor getEditor();

} interface ItemEditor {

   public JComponent getGUI();
   public void commitChanges();

}


      </source>
   
  
 
  



Fly weight Factory

   <source lang="java">

/* Software Architecture Design Patterns in Java by Partha Kuchana Auerbach Publications

  • /

import java.util.HashMap; import java.util.StringTokenizer; import java.util.Vector; public class FlyweightTest {

 public static void main(String[] args) throws Exception {
   Vector empList = initialize();
   FlyweightFactory factory = FlyweightFactory.getInstance();
   for (int i = 0; i < empList.size(); i++) {
     String s = (String) empList.elementAt(i);
     StringTokenizer st = new StringTokenizer(s, ",");
     String name = st.nextToken();
     String title = st.nextToken();
     String division = st.nextToken();
     FlyweightIntr flyweight = factory.getFlyweight(division);
     //associate the flyweight
     //with the extrinsic data object.
     VCard card = new VCard(name, title, flyweight);
     card.print();
   }
 }
 private static Vector initialize() {
   //for simplicity values are being hardcoded.
   Vector v = new Vector();
   v.add("name1,title1,North");
   v.add("name2,title2,South");
   v.add("name3,title1,North");
   v.add("name4,title3,East");
   v.add("name5,title4,East");
   v.add("name6,title2,East");
   v.add("name7,title1,West");
   v.add("name8,title3,West");
   v.add("name9,title1,West");
   v.add("name10,title6,South");
   v.add("name11,title5,North");
   v.add("name12,title1,North");
   return v;
 }

} class FlyweightFactory {

 private HashMap lstFlyweight;
 private static FlyweightFactory factory = new FlyweightFactory();
 private FlyweightFactory() {
   lstFlyweight = new HashMap();
 }
 public synchronized FlyweightIntr getFlyweight(String divisionName) {
   if (lstFlyweight.get(divisionName) == null) {
     FlyweightIntr fw = new Flyweight(divisionName);
     lstFlyweight.put(divisionName, fw);
     return fw;
   } else {
     return (FlyweightIntr) lstFlyweight.get(divisionName);
   }
 }
 public static FlyweightFactory getInstance() {
   return factory;
 }
 //Inner flyweight class
 private class Flyweight implements FlyweightIntr {
   private String company;
   private String address;
   private String city;
   private String state;
   private String zip;
   private void setValues(String cmp, String addr, String cty, String st,
       String zp) {
     company = cmp;
     address = addr;
     city = cty;
     state = st;
     zip = zp;
   }
   private Flyweight(String division) {
     // values are hard coded
     //for simplicity
     if (division.equals("North")) {
       setValues("CMP", "addr1", "cty1", "st1", "10000");
     }
     if (division.equals("South")) {
       setValues("CMP", "addr2", "cty2", "st2", "20000");
     }
     if (division.equals("East")) {
       setValues("CMP", "addr3", "cty3", "st3", "30000");
     }
     if (division.equals("West")) {
       setValues("CMP", "addr4", "cty4", "st4", "40000");
     }
   }
   public String getCompany() {
     return company;
   }
   public String getAddress() {
     return address;
   }
   public String getCity() {
     return city;
   }
   public String getState() {
     return state;
   }
   public String getZip() {
     return zip;
   }
 }// end of Flyweight

}// end of FlyweightFactory interface FlyweightIntr {

 public String getCompany();
 public String getAddress();
 public String getCity();
 public String getState();
 public String getZip();

} class VCard {

 String name;
 String title;
 FlyweightIntr objFW;
 public VCard(String n, String t, FlyweightIntr fw) {
   name = n;
   title = t;
   objFW = fw;
 }
 public void print() {
   System.out.println(name);
   System.out.println(title);
   System.out.println(objFW.getAddress() + "-" + objFW.getCity() + "-"
       + objFW.getState() + "-" + objFW.getZip());
   System.out.println("----------------");
 }

}

      </source>
   
  
 
  



Illustrates use of Abstract Factory pattern

   <source lang="java">

/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center

  • /

import java.awt.Button; import java.awt.Checkbox; import java.awt.CheckboxGroup; import java.awt.Color; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Label; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; public class Gardener extends Frame implements ActionListener, ItemListener {

 private Checkbox Vegie, Annual, Peren;
 private Button Center, Border, Shade, Quit;
 private Garden garden = null;
 private GardenPanel gardenPlot;
 private String borderPlant = "", centerPlant = "", shadePlant = "";
 public Gardener() {
   super("Garden planner");
   setGUI();
 }
 //----------------------------------
 private void setGUI() {
   setBackground(Color.lightGray);
   setLayout(new GridLayout(1, 2));
   Panel left = new Panel();
   add(left);
   Panel right = new Panel();
   add(right);
   //create label and 3 radio buttons on left side
   left.setLayout(new GridLayout(4, 1));
   left.add(new Label("Garden type"));
   CheckboxGroup grp = new CheckboxGroup();
   Vegie = new Checkbox("Vegetable", grp, false);
   Annual = new Checkbox("Annual", grp, false);
   Peren = new Checkbox("Perennial", grp, false);
   left.add(Vegie);
   left.add(Annual);
   left.add(Peren);
   Vegie.addItemListener(this);
   Peren.addItemListener(this);
   Annual.addItemListener(this);
   //now create right side
   right.setLayout(new GridLayout(2, 1));
   gardenPlot = new GardenPanel();
   gardenPlot.setBackground(Color.white);
   Panel botRight = new Panel();
   right.add(gardenPlot);
   right.add(botRight);
   Center = new Button("Central");
   Border = new Button("Border");
   Shade = new Button("Shade");
   Quit = new Button("Quit");
   botRight.add(Center);
   Center.addActionListener(this);
   botRight.add(Border);
   Border.addActionListener(this);
   botRight.add(Shade);
   Shade.addActionListener(this);
   botRight.add(Quit);
   Quit.addActionListener(this);
   setBounds(200, 200, 400, 300);
   setVisible(true);
 }
 //----------------------------------
 public void actionPerformed(ActionEvent e) {
   Object obj = e.getSource();
   if (obj == Center)
     setCenter();
   if (obj == Border)
     setBorder();
   if (obj == Shade)
     setShade();
   if (obj == Quit)
     System.exit(0);
 }
 //----------------------------------
 private void setCenter() {
   if (garden != null)
     centerPlant = garden.getCenter().getName();
   gardenPlot.repaint();
 }
 private void setBorder() {
   if (garden != null)
     borderPlant = garden.getBorder().getName();
   gardenPlot.repaint();
 }
 private void setShade() {
   if (garden != null)
     shadePlant = garden.getShade().getName();
   gardenPlot.repaint();
 }
 //----------------------------------
 public void itemStateChanged(ItemEvent e) {
   Checkbox ck = (Checkbox) e.getSource();
   garden = new GardenMaker().getGarden(ck.getLabel());
   shadePlant = "";
   centerPlant = "";
   borderPlant = "";
   gardenPlot.repaint();
 }
 //----------------------------------
 static public void main(String argv[]) {
   new Gardener();
 }
 //--------------------------------
 class GardenPanel extends Panel {
   public void paint(Graphics g) {
     Dimension sz = getSize();
     g.setColor(Color.lightGray);
     g.fillArc(0, 0, 80, 80, 0, 360);
     g.setColor(Color.black);
     g.drawRect(0, 0, sz.width - 1, sz.height - 1);
     g.drawString(centerPlant, 100, 50);
     g.drawString(borderPlant, 75, 120);
     g.drawString(shadePlant, 10, 40);
   }
 }

} //end of Gardener class //============================================= class GardenMaker {

 //Abstract Factory which returns one of three gardens
 private Garden gd;
 public Garden getGarden(String gtype) {
   gd = new VegieGarden(); //default
   if (gtype.equals("Perennial"))
     gd = new PerennialGarden();
   if (gtype.equals("Annual"))
     gd = new AnnualGarden();
   return gd;
 }

} abstract class Garden {

 public abstract Plant getShade();
 public abstract Plant getCenter();
 public abstract Plant getBorder();

} class Plant {

 String name;
 public Plant(String pname) {
   name = pname; //save name
 }
 public String getName() {
   return name;
 }

} class VegieGarden extends Garden {

 public Plant getShade() {
   return new Plant("Broccoli");
 }
 public Plant getCenter() {
   return new Plant("Corn");
 }
 public Plant getBorder() {
   return new Plant("Peas");
 }

} class AnnualGarden extends Garden {

 public Plant getShade() {
   return new Plant("Coleus");
 }
 public Plant getCenter() {
   return new Plant("Marigold");
 }
 public Plant getBorder() {
   return new Plant("Alyssum");
 }

} class PerennialGarden extends Garden {

  public Plant getShade()
  {
     return new Plant("Astilbe");
  }
public Plant getCenter()
{
   return new Plant("Dicentrum");
}
public Plant getBorder()
{
   return new Plant("Sedum");
}

}


      </source>