Factory Method工厂方法模式-java设计模式1
一、概念:在Simple Factory基础上做了扩展,1.不再直接由Factory做判断生成业务基类类型的子类对象(引用不同的子类),而是将判断推迟到Factory的子类中完成;2.但是生成的业务基类类型对象将一样调用自己已声明的方法实现功能,模型类也将从中获取子类处理结果后显示结果。
二、示例:游泳选手的比赛中,分为预赛和决赛。规则是预赛先按照报名的以前最好成绩排序,假如有40人参赛,一场比赛的泳道为8个,预赛有5场。成绩最好的3位将排在最后三场的中间赛道,最后一场的中间赛道是最强的(假如为菲尔普斯),向上递减;紧随其后的3名选手将被安排在最后三场的紧靠中间的赛道,其它赛道的安排以此类推。这样就安排了24为选手,还剩下的16名则按决赛排序。(详看游泳比赛赛道安排规则)。Factory Method的UML类图:
?三、重点代码解析:其它类已经指明了关系,下面就主程序了说明下:package create.factory.factorymethod;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
public class showSeeding extends JxFrame? //JxFrame类为继承了Frame类的简单类,代码看后面。
?? implements ListSelectionListener {
?JawtList evList, swList;
//JawtList extends JScrollPane implements ListSelectionListener, awtList,此处不详解,主要是可以滚动,增添项的列表。
?? Vector events;
public showSeeding() {
?? super("Factory Method Seeding");
?? events =? new Vector();
JPanel jp = new JPanel();
?? getContentPane().add(jp);
?? jp.setLayout(new GridLayout(1,2)); //框架类和布局类的聚合关系
??
?? evList = new JawtList(20);//JawList
?? swList = new JawtList(20);
?? jp.add(evList);
?? jp.add(swList);
?? evList.addListSelectionListener(this);
events.addElement(new TimedFinalEvent("500free.txt", 6));//在此处调用了调用了创建子类,返回具体对象。
?? evList.add("500 Free");
?? events.addElement(new PrelimEvent("100free.txt", 6));
?? evList.add("100 Free");
?? setSize(new Dimension(300,200));//encapsulates the width and height of a component (in integer precision) in a single object
?? setVisible(true);
?? }
//-----------------------------------------
?? public void valueChanged(ListSelectionEvent e)//在ListSelectionListener里面的方法,当值改变时会由关联关系调用。
?? {
????? swList.clear();
????? int index = evList.getSelectedIndex();
????? System.out.println("index="+index);
????? Event ev = (Event)events.elementAt(index);
????? Seeding sd = ev.getSeeding();
????? Enumeration enum1? =sd.getSwimmers();
????? while(enum1.hasMoreElements())
????? {
???????? Swimmer sw = (Swimmer)enum1.nextElement();
???????? swList.add(sw.getHeat()+" "+sw.getLane()+" "+sw.getName()+" "+sw.getTime());
????? }
?? }
?? //----------------------------------------??
?? static public void main(String argv[]) {
????? new showSeeding();
?? }
}
/****JxFrame类**/
public class JxFrame extends JFrame
{
?? public JxFrame(String title)
?? {
????? super(title);
????? setCloseClick();
????? setLF();
?? }
?? private void setCloseClick()
?? {
????? //create window listener to respond to window close click
????? addWindowListener(new WindowAdapter()
?????? {
??? ??? public void windowClosing(WindowEvent e) {System.exit(0);}
??? ??? });
?? }
?? //------------------------------------------
?? private void setLF()
?? {
?? // Force SwingApp to come up in the System L&F
??? String laf = UIManager.getSystemLookAndFeelClassName();//UIManager类返回the
String of the LookAndFeel class? ? try {
?????? UIManager.setLookAndFeel(laf);
/*装载Loads the
LookAndFeel specified by the given class name, using the current thread's context class loader, and passes it to setLookAndFeel(LookAndFeel). */
?? ??? ?}
?????? catch (UnsupportedLookAndFeelException exc)
???????? {System.err.println("Warning: UnsupportedLookAndFeel: " + laf);}
?????? catch (Exception exc) {System.err.println("Error loading " + laf + ": " + exc);
??? ?? }
?? }
}
四、总结:1.何时使用工厂模式:(1)类无法预计出必须创建那个类的对象(由事件激发)。(2)类要使用其子类指定所要创建的对象(将判断下移到工厂子类中)。(3)对于将创建那个类,希望将有关信息局部化(读入相同的信息或方法名输出不一样的结果或提供不一样的功能)。2.工厂模式有几种不同的形式:(1)基类是抽象类,并且这种模式必须返回一个完全可工作的类(决策点在抽象类)。(2)基类中包含默认的方法,并且只有当默认的方法不够用时,才需要派生子类。(3)传递给工厂的参数将通知要返回那些类类型,这种情况下,所有的了必须有相同的方法名,但是每个方法可完成完全不同的操作。