设计模式之抽象工厂模式

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


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


    这样做也能实现,但是工厂类有点多吧,而且在客户端中将会有很多的条件语句,有没有什么更好的办法呢?我们在分析看看,商品有三种,性别对应着男、女,那么我们为什么不从另一个角度来思考问题,不再建立生产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();
	}
}

客户端:

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

}

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

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


    上节中说到,工厂方法符合开闭原则,但是抽象工厂方法只是部分的符合开闭原则,举个例子:



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值