设计模式之简单工厂方法模式和工厂方法模式

来源:互联网 发布:mac什么打开exe文件 编辑:程序博客网 时间:2024/06/05 06:01

    假设现在有一个网上车辆交易系统,现在有三种车型,林肯、凯迪拉克和别克,系统根据用户的选择来显示相应产品的具体信息,那么我们可以这样设计:


所有汽车类的接口:

public interface Car {public abstract String getDescription();}
Lincoln类:

public class Lincoln implements Car {@Overridepublic String getDescription() {String description = "this is Lincoln";return description;}}

Cadillac类:

public class Cadillac implements Car {@Overridepublic String getDescription() {String description = "this is Cadillac";return description;}}

Buick类:

public class Buick implements Car {@Overridepublic String getDescription() {String description = "this is Buick";return description;}}

用户界面类:

import java.awt.Dimension;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;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 LINCOLN = "Lincoln";private String CADILLAC = "Cadillac";private String BUICK = "Buick";private JLabel labelShowChoice;private JTextArea textShowInfo;private JComboBox Choice;private JPanel panelNorth;private JPanel panelCenter;public void initComponents(){labelShowChoice = new JLabel("请选择车型:   ");textShowInfo = new JTextArea();textShowInfo.setColumns(15);Choice = new JComboBox();Choice.addItem(LINCOLN);Choice.addItem(CADILLAC);Choice.addItem(BUICK);Choice.addActionListener(this);panelNorth = new JPanel();panelCenter = new JPanel();}public void panelAddComponenets(){panelNorth.add(labelShowChoice);panelNorth.add(Choice);panelCenter.add(textShowInfo);}public void mainFrameAddPanel(){this.add("North", panelNorth);this.add("Center", panelCenter);}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();}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource() == Choice){String choice = (String)Choice.getSelectedItem();Car car = null;if(choice.equals(LINCOLN)){car = new Lincoln();}if(choice.equals(CADILLAC)){car = new Cadillac();}if(choice.equals(BUICK)){car = new Buick();}String carDescription = car.getDescription();textShowInfo.setText(carDescription);}}}

测试:

public class main {public static void main(String[] args) {clientGUI  cGUI = new clientGUI();}}

  这样设计无疑是有很多缺点的,首先,在客户端有很多if语句,其次,客户端需要知道所有的产品类细节。那么如何改善上述的设计呢?或许我们可以根据条件的选择,用一个专门的类来创建具体的产品。这样客户端就可以不需要知道所有产品的细节了。这就是设计模式就是工厂方法模式,下面我们来介绍用简单工厂方法模式和工厂方法模式来实现上述的例子。

简单工厂方式模式

    使用简单工厂方法模式,类图的设计是这样的:

所有汽车的接口:
public interface Car {public abstract String getDescription();}

Lincoln类:
public class Lincoln implements Car {@Overridepublic String getDescription() {String description = "this is Lincoln";return description;}}

Cadillac类:
public class Cadillac implements Car {@Overridepublic String getDescription() {String description = "this is Cadillac";return description;}}

Buick类:
public class Buick implements Car {@Overridepublic String getDescription() {String description = "this is Buick";return description;}}

工厂类:
public class carObjCreator {private String LINCOLN = "Lincoln";private String CADILLAC = "Cadillac";private String BUICK = "Buick";public Car getCarObj(String carType){Car car = null;if(carType.equals(LINCOLN)){car = new Lincoln();}if(carType.equals(CADILLAC)){car = new Cadillac();}if(carType.equals(BUICK)){car = new Buick();}return car;}}


用户界面:
import java.awt.Dimension;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;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 LINCOLN = "Lincoln";private String CADILLAC = "Cadillac";private String BUICK = "Buick";private JLabel labelShowChoice;private JTextArea textShowInfo;private JComboBox Choice;private JPanel panelNorth;private JPanel panelCenter;public void initComponents(){labelShowChoice = new JLabel("请选择车型");textShowInfo = new JTextArea();textShowInfo.setColumns(15);Choice = new JComboBox();Choice.addItem(LINCOLN);Choice.addItem(CADILLAC);Choice.addItem(BUICK);Choice.addActionListener(this);panelNorth = new JPanel();panelCenter = new JPanel();}public void panelAddComponenets(){panelNorth.add(labelShowChoice);panelNorth.add(Choice);panelCenter.add(textShowInfo);}public void mainFrameAddPanel(){this.add("North", panelNorth);this.add("Center", panelCenter);}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();}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource() == Choice){String choice = (String)Choice.getSelectedItem();carObjCreator carCreator = new carObjCreator();Car car = carCreator.getCarObj(choice);String carDescription = car.getDescription();textShowInfo.setText(carDescription);}}}


测试:
public class main {public static void main(String[] args) {clientGUI  cGUI = new clientGUI();}}

    可以看到,用户在使用时创建实例的职责全交给工厂类,这样客户端就不需要那么多if语句,也不需要知道对象是如何创建和组织的。
    但是,由于工厂类集中了所有实例的创建逻辑,一旦工厂类出现问题,那么所有的客户端都会受影响。此外,一旦我们新增加一个产品,就要修改工厂类,相应的工厂类就需要重新编译,违背了“开闭原则”,即系统对扩展开放,对修改关闭的原则

工厂方法模式

    使用工厂方法模式,上述例子的设计应该是这样的:


所有汽车的接口:
public interface Car {public abstract String getDescription();}

Lincoln类:
public class Lincoln implements Car {@Overridepublic String getDescription() {String description = "this is Lincoln";return description;}}

Cadillac类:
public class Cadillac implements Car {@Overridepublic String getDescription() {String description = "this is Cadillac";return description;}}

Buick类:
public class Buick implements Car {@Overridepublic String getDescription() {String description = "this is Buick";return description;}}

所有工厂类的接口:
public interface carCreator {public Car getCarObj();}

创建Lincoln对象类:
public class LincolnCreator implements carCreator {@Overridepublic Car getCarObj() {// TODO Auto-generated method stubreturn new Lincoln();}}

创建Cadillac对象类:
public class CadillacCreator implements carCreator {@Overridepublic Car getCarObj() {// TODO Auto-generated method stubreturn new Cadillac();}}

创建Buick对象类:
public class BuickCreator implements carCreator {@Overridepublic Car getCarObj() {// TODO Auto-generated method stubreturn new Buick();}}

用户界面:
import java.awt.Dimension;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;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 LINCOLN = "Lincoln";private String CADILLAC = "Cadillac";private String BUICK = "Buick";private JLabel labelShowChoice;private JTextArea textShowInfo;private JComboBox Choice;private JPanel panelNorth;private JPanel panelCenter;public void initComponents(){labelShowChoice = new JLabel("请选择车型:");textShowInfo = new JTextArea();textShowInfo.setColumns(15);Choice = new JComboBox();Choice.addItem(LINCOLN);Choice.addItem(CADILLAC);Choice.addItem(BUICK);Choice.addActionListener(this);panelNorth = new JPanel();panelCenter = new JPanel();}public void panelAddComponenets(){panelNorth.add(labelShowChoice);panelNorth.add(Choice);panelCenter.add(textShowInfo);}public void mainFrameAddPanel(){this.add("North", panelNorth);this.add("Center", panelCenter);}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();}@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif(e.getSource() == Choice){String choice = (String)Choice.getSelectedItem();carCreator CC = null;if(choice.equals(LINCOLN)){ CC = new LincolnCreator();}if(choice.equals(CADILLAC)){ CC = new CadillacCreator();}if(choice.equals(BUICK)){ CC = new BuickCreator();}Car car =  CC.getCarObj();String carDescription = car.getDescription();textShowInfo.setText(carDescription);}}}

测试:
public class main {public static void main(String[] args) {clientGUI  cGUI = new clientGUI();}}

    假如我们要增加一种车型,只需要增加该车型的类和创建该车型对象的创建类,符合开闭原则。
1 0