zoukankan      html  css  js  c++  java
  • 设计模式之抽象工厂模式

        在上一篇博客中我们使用了工厂模式来设计一个网上车辆交易系统。在那个样例中仅仅有汽车这一种单一类型的商品。那么,假设有多种类型的商品。还能用工厂方法模式吗?举个样例,如今有个网上服装买卖系统。有三种服装---鞋、套装和衬衫,当中又分为男鞋女鞋、男套装和女套装、男衬衫和女衬衫。即例如以下商品:


       依照上节中说到的工厂方法模式,应该这样设计。使用三个工厂来创建三个对象:


        这样做也能实现。可是工厂类有点多吧,并且在client中将会有非常多的条件语句,有没有什么更好的办法呢?我们在分析看看。商品有三种,性别相应着男、女,那么我们为什么不从还有一个角度来思考问题,不再建立生产shoes、shirt和suit的工厂。而是建立生产男人的衣服工厂ManCloseFactory和生产女人衣服的工厂WomanCLoseFactory。例如以下设计:


        类图设计好了。如今仅仅须要两个工厂就能搞定了,那么编代码试试吧:

    shirt接口:

    public interface Shirt {
    	public String getInfo();
    }

    suit接口:

    public interface Suit {
    	public String getInfo();
    }

    shoes接口:

    public interface Shoes {
    	public String getInfo();
    }

    ManShirt类:

    public class ManShirt implements Shirt {
    
    	@Override
    	public String getInfo() {
    		// TODO Auto-generated method stub
    		String info = "男  衬衫";
    		return info;
    	}
    }

    WomanShirt类:

    public class WomanShirt implements Shirt {
    
    	@Override
    	public String getInfo() {
    		// TODO Auto-generated method stub
    		String info = "女  衬衫";
    		return info;
    	}
    }

    ManSuit类:

    public class ManSuit implements Suit {
    
    	@Override
    	public String getInfo() {
    		// TODO Auto-generated method stub
    		String info = "男  套装";
    		return info;
    	}
    }

    WomanSuit类:

    public class WomanSuit implements Suit {
    
    	@Override
    	public String getInfo() {
    		// TODO Auto-generated method stub
    		String info = "女  套装";
    		return info;
    	}
    }

    ManShoes类:

    public class ManShoes implements Shoes {
    
    	@Override
    	public String getInfo() {
    		// TODO Auto-generated method stub
    		String info = "男  鞋";
    		return info;
    	}
    }

    WomanShoes类:

    public class WomanShoes implements Shoes {
    
    	@Override
    	public String getInfo() {
    		// TODO Auto-generated method stub
    		String info = "女  鞋";
    		return info;
    	}
    }

    工厂类的基类:

    public abstract class CloseFactory {
    	public static final String MAN = "男";
    	public static final String WOMAN = "女";
    	
    	public abstract Shoes getShoes();
    	public abstract Suit getSuit();
    	public abstract Shirt getShirt();
    
    	public static CloseFactory getCloseFactory(String Sex){
    		CloseFactory CF = null;
    		if(Sex.equals(MAN)){
    			CF = new ManCloseFactory();
    		}else if(Sex.equals(WOMAN)){
    			CF = new WomanCloseFactory();
    		}
    		return CF;
    	}
    }

    男服生产工厂,ManCloseFactory:

    public class ManCloseFactory extends CloseFactory {
    
    	@Override
    	public Shoes getShoes() {
    		// TODO Auto-generated method stub
    		return new ManShoes();
    	}
    
    	@Override
    	public Suit getSuit() {
    		// TODO Auto-generated method stub
    		return new ManSuit();
    	}
    
    	@Override
    	public Shirt getShirt() {
    		// TODO Auto-generated method stub
    		return new ManShirt();
    	}
    }

    女服生产工厂,WomanCloseFactory:

    public class WomanCloseFactory extends CloseFactory {
    
    	@Override
    	public Shoes getShoes() {
    		// TODO Auto-generated method stub
    		return new WomanShoes();
    	}
    
    	@Override
    	public Suit getSuit() {
    		// TODO Auto-generated method stub
    		return new WomanSuit();
    	}
    
    	@Override
    	public Shirt getShirt() {
    		// TODO Auto-generated method stub
    		return new WomanShirt();
    	}
    }

    client:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    
    public class clientGUI extends JFrame implements ActionListener{
    
    	private String SHOES = "鞋";
    	private String SHIRT = "衬衫";
    	private String SUIT = "套装";
    	
    	private String MAN = "男";
    	private String WOMAN = "女";
    	
    	private JLabel labelShowSex;
    	private JLabel labelShowType;
    	
    	private JTextArea textShowInfo;
    	private JComboBox ChoiceSex;
    	private JComboBox ChoiceType;
    	
    	private JButton BtnOK;
    	private JButton BtnExit;
    	
    	private JPanel panelNorth;
    	private JPanel panelCenter;
    	private JPanel panelSouth;
    	
    	public void initComponents(){
    		labelShowSex = new JLabel("请选择性别:");
    		labelShowType = new JLabel("请选择服饰:");
    		
    		textShowInfo = new JTextArea();
    		textShowInfo = new JTextArea();
    		textShowInfo.setColumns(20);
    		textShowInfo.setRows(100);
    		textShowInfo.setBackground(Color.PINK);
    		ChoiceSex = new JComboBox();
    		ChoiceSex.addItem(MAN);
    		ChoiceSex.addItem(WOMAN);
    		
    		ChoiceType = new JComboBox();
    		ChoiceType.addItem(SHOES);
    		ChoiceType.addItem(SHIRT);
    		ChoiceType.addItem(SUIT);
    		
    		BtnOK = new JButton("OK");
    		BtnOK.addActionListener(this);
    		BtnExit = new JButton("EXIT");
    		BtnExit.addActionListener(this);
    		
    		panelNorth = new JPanel();
    		panelCenter = new JPanel();
    		panelSouth = new JPanel();
    	}
    	
    	public void panelAddComponenets(){
    		panelNorth.add(labelShowSex);
    		panelNorth.add(ChoiceSex);
    		
    		panelNorth.add(labelShowType);
    		panelNorth.add(ChoiceType);
    		
    		panelCenter.add(textShowInfo);
    		panelSouth.add(BtnOK);
    		panelSouth.add(BtnExit);
    	}
    	
    	public void mainFrameAddPanel(){
    		this.add("North", panelNorth);
    		this.add("Center", panelCenter);
    		this.add("South", panelSouth);
    	}
    	
    	public void mianFramSet(){
    		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    		this.setLocation((d.width - this.getSize().width)/2, (d.height - this.getSize().height)/2);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setSize(300, 200);
    		this.setVisible(true);
    	}
    
    	public clientGUI(){
    		initComponents();
    		panelAddComponenets();
    		mainFrameAddPanel();
    		mianFramSet();
    	}
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		// TODO Auto-generated method stub
    		if(e.getSource() == BtnOK){
    			String Sex = ChoiceSex.getSelectedItem().toString();
    			String Type = ChoiceType.getSelectedItem().toString();
    			CloseFactory cf =  CloseFactory.getCloseFactory(Sex);//依据性别调用对应的工厂
    			if(Type.equals(SHIRT)){//依据类型生产对应的产品
    				Shirt s = cf.getShirt();
    				String info = s.getInfo();
    				textShowInfo.setText(info);
    			}else if(Type.equals(SHOES)){
    				Shoes s = cf.getShoes();
    				String info = s.getInfo();
    				textShowInfo.setText(info);
    			}else if(Type.equals(SUIT)){
    				Suit s = cf.getSuit();
    				String info = s.getInfo();
    				textShowInfo.setText(info);
    			}
    		}
    		if(e.getSource() == BtnExit){
    			System.exit(0);
    		}
    	}
    }
    

    測试:

    public class mian {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		clientGUI cGUI = new clientGUI();
    	}
    
    }

        这样设计是不是好多了。!

        总结一下,抽象工厂模式应用在产品类别不唯一的情况,而工厂模式应用在产品类别单一的情况。再画一下抽象工厂模式的设计图:


        上节中说到。工厂方法符合开闭原则,可是抽象工厂方法仅仅是部分的符合开闭原则,举个样例:



  • 相关阅读:
    Android中Context具体解释 ---- 你所不知道的Context
    JDK6、Oracle11g、Weblogic10 For Linux64Bit安装部署说明
    matplotlib 可视化 —— 定制 matplotlib
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    指数函数的研究
    指数函数的研究
    指数分布的研究
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7241908.html
Copyright © 2011-2022 走看看