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();
    	}
    
    }

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

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


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



  • 相关阅读:
    后台管理UI的选择
    通过Js对电话和姓名身份证等进行部分隐藏处理
    12个用得着的JQuery代码片段
    Java获取登录用户IP地址
    Android Gson解析json详解
    Android——SD卡工具类——SDCardUtils.java
    【读书笔记】---《失控》
    【读书笔记】.Net并行编程(三)---并行集合
    Wix 安装部署教程(十六) -- 自动生成多语言文件
    【月末轻松篇】--- 那些奇葩的Bugs
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7241908.html
Copyright © 2011-2022 走看看