Abstract Factory抽象工厂模式-java设计模式2

一、概念:Abstract Factory是比Factory method更加抽象的一种模式,不是在factory也不是在子类中决定返回的子类,而是将这种判断交给的应用类。1.判断在应用类,返回创建类的子类 对象组对象。2.用对象组对象可以factory基类中声明的方法返回模型对象,模型对象可以返回不同的具体对象。
二、实例:创建一个园林的设计方案小程序,可以根据种植时间长短返回不同的种植方案,种植方案下可以返回不同的具体植物类型,程序的UML类图:


三、源代码解析:
3.1创建类的Garden接口:
package create.factory.abstractfactory;
public interface Garden {
    public Plant getShade();
    public Plant getCenter();
    public Plant getBorder();
}
只是声明了相关的方法。
3.2创建接口的多个子类:
package create.factory.abstractfactory;
public class VeggieGarden implements Garden {
    public Plant getShade() {
        return new Plant("Broccoli");
    }
    public Plant getCenter() {
        return new Plant("Corn");
    }
    public Plant getBorder() {
        return new Plant("Peas");
    }
}
只是实现了接口中定义的方法,返回实体模型类的不同对象(将对象实体创建)。其它两个类类似。
3.3对象实体模型类:
package create.factory.abstractfactory;
public class Plant {
    private String name;
    public Plant(String pname) {
        name = pname;     //save name
    }       
    public String getName() {
        return name;
    }
    }
3.4应用程序框架类:
package create.factory.abstractfactory;
import java.awt.*;
import java.awt.event.*;
//illustrates use of Abstract Factory pattern
public class Gardener extends Frame
implements ActionListener {
    private Checkbox Veggie, 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"); //super时就是调用父类构造函数,此为Frame(String title);
        setGUI();
    }
    //----------------------------------
    private void setGUI() {
        setBackground(Color.lightGray); //getContentPane.setBackground(...)也就是Frame类设置背景色
        setLayout(new GridLayout(1,2));//使用了GridLayout,将Frame设置为(1,2)网格。
        Panel left = new Panel();
        add(left);                           //Frame.add(left);
        Panel right= new Panel();
        add(right);                               //Frame.add(right);
 //create label and 3 radio buttons on left side
        left.setLayout(new GridLayout(4, 1)); 
//再将 Panel类型的left设置(4,1)网格。
        left.add(new Label("Garden type"));//在网格中默认为从上到下,从左到右添加。
        CheckboxGroup grp= new CheckboxGroup();
        Veggie = new Checkbox("Vegetable", grp, false);
       
//设置Checkbox构造方法用CheckboxGroup初始化属性,所以为聚合关系。
        Annual = new Checkbox("Annual", grp, false);
        Peren = new Checkbox("Perennial", grp, false);
        left.add(Veggie); //通过聚合关系后拥有了特性,在用left.add Checkbox对象而不是CheckboxGroup对象。
        left.add(Annual);
        left.add(Peren);
        Veggie.addItemListener(new VeggieListener()); //为其添加监听器,从而决定返回那个对象组。
        Peren.addItemListener(new PerenListener());
        Annual.addItemListener(new AnnualListener());

        //now create right side
        right.setLayout(new GridLayout(2,1)); //
再将 Panel类型的right设置(2,1)网格。
        gardenPlot = new GardenPanel(); //后面显示具体对象的类,为其创建对象。
        gardenPlot.setBackground(Color.white);
        Panel botRight = new Panel();

        right.add(gardenPlot);//将显示具体对象类添加到right网格的第一行
        right.add(botRight); //将Button Panel面板放置到第二行
        Center = new Button("Central");
        Border =  new Button("Border");
        Shade = new Button("Shade");
        Quit = new Button("Quit");
        botRight.add(Center); //连续的添加button及它的监听器。
        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) { 
//button类共同的默认监听器实现方法actionPerformed(),此处没有定义监听器类。
        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() {//通过得到的返回子类对象组garden,调用getCenter返回Plant类型,getName返回String类型。
        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();
    }
    private void clearPlants() {            //当用户切换到其他的对象组时,将具体对象清除,然后repaint 会调用paint方法生效。
        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);
        }
    }
    //-----------------------------
    class VeggieListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
/*对于Checkbox类型,由关联关系,ItemListener是将ItemEvent消息标识和checkbox标识,传递给特定的ItemStateChange方法来处理的。*/
            garden = new VeggieGarden();
            clearPlants();
        }
    }
    //-----------------------------
    class PerenListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            garden = new PerennialGarden();
            clearPlants();
        }
    }
    //-----------------------------
    class AnnualListener implements ItemListener {
        public void itemStateChanged(ItemEvent e) {
            garden = new AnnualGarden();
            clearPlants();
        }
    }
}     //end of Gardener class
四、结论:
1.抽象工厂模式的一个主要目的是把所生成的具体类相分离,这些类的实际名称被隐藏在工厂中,客户不必了解。
2.修改类时,可以自由地修改或者交换这些产品类系列,不会导致系列间的相互影响。
3.添加类时,不可避免的会有额外不相同方法的类;此时:
(1)可以在基类中定义所有的方法(即使他们不一定有实际的功能)。
(2)派生一个新的基类,使之包含所需的全部方法,然后为所有的园林类型派生相应的子类。

你可能感兴趣的:(UML)