您的位置:首页 > 其它

二、工厂方法模式(Factory Method Pattern)

2008-03-13 00:36 190 查看
不是用一个专门的类来决定实例化哪一个子类,而是超类把这种决定延迟到每个子类.按这种模式编写的程序定义了一个抽象类,它去创建对象,但让子类决定创建哪一种对象.
例子: 在游泳比赛中为运动员确定泳道.最快的三名选手安排在最快的三组里的中央泳道上,第二快的三名选手安排在头三组的紧邻的泳道上,依次类推.
抽象类Event与其派生类:




public abstract class Event ...{ //抽象类:Event


protected int numLanes;


protected ArrayList swimmers;






public Event(string filename, int lanes) ...{


numLanes = lanes;


swimmers = new ArrayList();


//读取游泳者信息数据


csFile f = new csFile(filename);


f.OpenForRead ();


string s = f.readLine();




while (s != null) ...{


Swimmer sw = new Swimmer(s);


swimmers.Add (sw);


s = f.readLine();


}


f.close();


}


public abstract Seeding getSeeding();


public abstract bool isPrelim();


public abstract bool isFinal();


public abstract bool isTimedFinal();


}




public class PrelimEvent:Event ...{ //Event的派生类PrelimEvent




public PrelimEvent(string filename, int lanes):base(filename,lanes) ...{


}


//return circle seeding




public override Seeding getSeeding() ...{


return new CircleSeeding(swimmers, numLanes);


//返回CircleSeeding的一个实例


}




public override bool isPrelim() ...{


return true;


}




public override bool isFinal() ...{


return false;


}




public override bool isTimedFinal() ...{


return false;


}


}




public class TimedFinalEvent:Event ...{ //Event的派生类TimedFinalEvent






public TimedFinalEvent(string filename, int lanes):base(filename, lanes) ...{


}


//return StraightSeeding class




public override Seeding getSeeding() ...{


return new StraightSeeding(swimmers, numLanes);


//返回StraightSeeding的一个实例


}




public override bool isPrelim() ...{


return false;


}




public override bool isFinal() ...{


return false;


}




public override bool isTimedFinal() ...{


return true;


}


}

抽象类:Seeding与其派生类




public abstract class Seeding ...{ //抽象类:Seeding


protected int numLanes;


protected int[] lanes;


public abstract IEnumerator getSwimmers();


public abstract int getCount();


public abstract int getHeats();


protected abstract void seed();


//--------------------------------




protected void calcLaneOrder() ...{


lanes = new int[numLanes];


int mid = numLanes / 2;


if (odd(numLanes))


mid = mid + 1; //start in middle lane


int incr = 1;


int ln = mid;


//create array of lanes from


//center to outside




for (int i=0; i< numLanes; i++) ...{


lanes[i] = ln;


ln = mid + incr;


incr = - incr;


if (incr > 0)


incr=incr+1;


}


}


//--------------------------------




private bool odd(int x) ...{


return(((x / 2)*2) != x);


}


}


//直接排位




public class StraightSeeding :Seeding ...{ //Seeding的派生类StraightSeeding


protected ArrayList swimmers;


protected Swimmer[] swmrs;


protected int count;


protected int numHeats;






public StraightSeeding(ArrayList sw, int lanes) ...{


swimmers = sw;


numLanes = lanes;


count = sw.Count;


calcLaneOrder();


seed();


}


//--------------------------------




protected override void seed() ...{


//loads the swmrs array and sorts it


sortUpwards();




int lastHeat = count % numLanes;


if (lastHeat < 3)


lastHeat = 3; //last heat must have 3 or more


int lastLanes = count - lastHeat;


numHeats = count / numLanes;


if (lastLanes > 0)


numHeats++;


int heats = numHeats;




//place heat and lane in each swimmer's object


int j = 0;




for (int i = 0; i < lastLanes; i++) ...{


Swimmer sw = swmrs[i];


sw.setLane(lanes[j++]);


sw.setHeat(heats);




if (j >= numLanes) ...{


heats--;


j=0;


}


}


//Add in last partial heat


if (j < numLanes)


heats--;


j = 0;




for (int i = lastLanes-1; i<count; i++) ...{


Swimmer sw = swmrs[i];


sw.setLane(lanes[j++]);


sw.setHeat(heats);


}


//copy from array back into ArrayList


swimmers = new ArrayList();


for (int i=0; i< count; i++)


swimmers.Add(swmrs[i]);


}


//--------------------------------




protected void sortUpwards() ...{


swmrs = new Swimmer[count];


for (int i=0; i < count; i++)


swmrs[i] = (Swimmer)swimmers[i];




for ( int i=0; i < count; i++) ...{




for (int j = i; j < count; j++) ...{




if (swmrs[i].getTime() > swmrs[j].getTime()) ...{


Swimmer swtemp = swmrs[i];


swmrs[i] = swmrs[j];


swmrs[j] = swtemp;


}


}


}


}


//--------------------------------




public override int getCount() ...{


return swimmers.Count ;


}






public override IEnumerator getSwimmers() ...{


return swimmers.GetEnumerator ();


}


//----------------------------------




public override int getHeats() ...{


return numHeats;


}




}


//循环排位


public class CircleSeeding:StraightSeeding //StraightSeeding的派生类CircleSeeding




...{




public CircleSeeding(ArrayList sw, int lanes):base(sw,lanes) ...{


seed();


}


//----------------------------




protected override void seed() ...{


int circle;




base.seed(); //do straight seed as default




if (numHeats >= 2 ) ...{


if (numHeats >= 3)


circle = 3;


else


circle = 2;


int i = 0;




for (int j = 0; j < numLanes; j++) ...{




for (int k = 0; k < circle; k++) ...{


swmrs[i].setLane(lanes[j]);


swmrs[i++].setHeat(numHeats - k);


}


}


}


}游泳者类Swimmer与使用到的其它类:


public class Swimmer //游泳者类




...{


private string firstName, lastName;


private int age;


private string club;


private float time;




private int heat, lane;


//--------------------------------------




public Swimmer(String dataline) ...{


StringTokenizer st = new StringTokenizer(dataline, " ");


string lineNumber = st.nextToken(); //ignore and discard


firstName = st.nextToken();


lastName = st.nextToken();


age = Convert.ToInt32 (st.nextToken().Trim());


club = st.nextToken().Trim();




string stime = st.nextToken().Trim();


int i = stime.IndexOf(":");




if (i > 0) ...{


stime = stime.Substring(0, i) + stime.Substring (i+1);


}


time = Convert.ToSingle ( stime);




}




//-------------------------------




public void setLane(int ln) ...{


lane = ln;


}


//-------------------------------




public int getLane() ...{


return lane;


}


//-------------------------------




public void setHeat(int ht) ...{


heat = ht;


}


//-------------------------------




public int getHeat() ...{


return heat;


}


//-------------------------------




public int getAge() ...{


return age;


}


//-------------------------------




public float getTime() ...{


return time;


}


//-------------------------------




public string getName() ...{


return firstName+" "+lastName;


}


//-------------------------------




public string getClub() ...{


return club;


}




}






/**//// <summary>


/// A simple file handlng class


/// </summary>


public class csFile




...{


private string fileName;


StreamReader ts;


StreamWriter ws;


private bool opened, writeOpened;


//-----------




public csFile() ...{


init();


}


//-----------




private void init() ...{


opened = false;


writeOpened = false;


}


//-----------




public csFile(string file_name) ...{


fileName = file_name;


init();


}


//-----------




public bool OpenForRead(string file_name)...{


fileName = file_name;




try ...{


ts = new StreamReader (fileName);


opened=true;


}




catch(FileNotFoundException e) ...{


return false;


}


return true;


}


//-----------




public bool OpenForRead() ...{


return OpenForRead(fileName);


}


//-----------




public string readLine() ...{


return ts.ReadLine ();


}


//-----------




public void writeLine(string s) ...{


ws.WriteLine (s);


}


//-----------




public void close() ...{


if (opened)


ts.Close ();


if(writeOpened)


ws.Close();


}


//-----------




public bool OpenForWrite() ...{


return OpenForWrite(fileName);


}


//-----------




public bool OpenForWrite(string file_name) ...{




try...{


ws = new StreamWriter (file_name);


fileName = file_name;


writeOpened = true;


return true;


}




catch(FileNotFoundException e) ...{


return false;


}


}


}






public class StringTokenizer ...{


private string data, delimiter;


private string[] tokens;


private int index;




public StringTokenizer(string dataLine) ...{


init(dataLine, " ");


}




private void init(String dataLine, string delim) ...{


delimiter = delim;


data = dataLine;


tokens = data.Split (delimiter.ToCharArray() );


index = 0;


}




public StringTokenizer(string dataLine, string delim) ...{


init(dataLine, delim);


}




public bool hasMoreElements() ...{


return (index < (tokens.Length));


}




public string nextToken() ...{


return nextElement();


}




public string nextElement() ...{


string s = tokens[index++];


while((s.Length <=0) && (index<tokens.Length ))


s = tokens[index++];


return s;


}


}

调用:


using System;


using System.Drawing;


using System.Collections;


using System.ComponentModel;


using System.Windows.Forms;


using System.Data;




namespace Seeding




...{




/**//// <summary>


/// Summary description for Form1.


/// </summary>


public class Form1 : System.Windows.Forms.Form




...{


private System.Windows.Forms.ListBox lsEvents;


private System.Windows.Forms.ListBox lsSwimmers;




/**//// <summary>


/// Required designer variable.


/// </summary>


private System.ComponentModel.Container components = null;


private ArrayList events;






private void init() ...{


//create array of events


events = new ArrayList ();


lsEvents.Items.Add ("500 Free");


lsEvents.Items.Add ("100 Free");


//and read in their data


events.Add (new TimedFinalEvent ("500free.txt", 6));


events.Add (new PrelimEvent ("100free.txt", 6));


}


public Form1()




...{


//


// Required for Windows Form Designer support


//


InitializeComponent();


init();


//


// TODO: Add any constructor code after InitializeComponent call


//


}






/**//// <summary>


/// Clean up any resources being used.


/// </summary>


protected override void Dispose( bool disposing )




...{


if( disposing )




...{


if (components != null)




...{


components.Dispose();


}


}


base.Dispose( disposing );


}






Windows Form Designer generated code#region Windows Form Designer generated code




/**//// <summary>


/// Required method for Designer support - do not modify


/// the contents of this method with the code editor.


/// </summary>


private void InitializeComponent()




...{


this.lsEvents = new System.Windows.Forms.ListBox();


this.lsSwimmers = new System.Windows.Forms.ListBox();


this.SuspendLayout();


//


// lsEvents


//


this.lsEvents.Location = new System.Drawing.Point(8, 24);


this.lsEvents.Name = "lsEvents";


this.lsEvents.Size = new System.Drawing.Size(112, 69);


this.lsEvents.TabIndex = 0;


this.lsEvents.SelectedIndexChanged += new System.EventHandler(this.lsEvents_SelectedIndexChanged);


//


// lsSwimmers


//


this.lsSwimmers.Location = new System.Drawing.Point(144, 24);


this.lsSwimmers.Name = "lsSwimmers";


this.lsSwimmers.Size = new System.Drawing.Size(192, 160);


this.lsSwimmers.TabIndex = 1;


//


// Form1


//


this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);


this.ClientSize = new System.Drawing.Size(384, 205);




this.Controls.AddRange(new System.Windows.Forms.Control[] ...{


this.lsSwimmers,


this.lsEvents});


this.Name = "Form1";


this.Text = "Seeding Factory";


this.ResumeLayout(false);




}


#endregion






/**//// <summary>


/// The main entry point for the application.


/// </summary>


[STAThread]


static void Main()




...{


Application.Run(new Form1());


}






private void lsEvents_SelectedIndexChanged(object sender, System.EventArgs e) ...{


int index = lsEvents.SelectedIndex ;


Event ev = (Event)events[index];


Seeding sd = ev.getSeeding();


IEnumerator en = sd.getSwimmers();


lsSwimmers.Items.Clear() ;




while(en.MoveNext ()) ...{


Swimmer sw = (Swimmer)en.Current ;


lsSwimmers.Items.Add(sw.getHeat()+" "+sw.getLane()+" "+sw.getName()+" "+sw.getTime());


}


}


}


}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: