工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有以下几种形态:
·       简单工厂(Simple Factory)模式
·       工厂方法(Factory Method)模式
·       抽象工厂(Abstract Factory)模式

    Simple Factory模式根据提供给它的数据,返回几个可能类中的一个类的实例。通常它返回的类都有一个公共的父类和公共的方法。

Simple Factory模式实际上不是GoF 23个设计模式中的一员。
下面我们来看看一个Simple Factory的例子:


以上为整个类结构的UML图。
工厂类角色Creator (PersonSimFactory):工厂类在客户端的直接控制下(GetPerson方法)创建产品对象。

抽象产品角色Product (Person):定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口(我们这里使用了类为例)当然你也可以把下面的Person类改为abstract类,把GetInfo()变为abstract函数来运行或者可以将Person变为Interface,将实现延迟到子类中也没有问题。

具体产品角色CreatedProduct (WritePerson, YellowPerson,BlackPerson):定义工厂具体加工出的对象。

具体代码(C#):

using System;

namespace SimFactory
{
    
/// <summary>
    
///============== Program Description==============
    
///Name:SimFactory.cs
    
///Objective:SimFactory 
    
///Date:2006-02-09 
    
///Written By coffee.liu
    
///================================================
    
/// </summary>

    public  class Person
    
{
        
protected string sex,race;
        
public string GetSex(){
        
return sex;
        }

        
public string GetRace(){
        
return race;
        }

        
public virtual void GetInfo(){
        }

    }


    
public class YellowPerson:Person
    
{
        
public YellowPerson()
        
{
            sex
="Man";
            race
="Yellow";
        }

        
public YellowPerson(string Ysex)
        
{
           sex
=Ysex;
           race
="Yellow";
        }

        
public override void GetInfo(){
          Console.WriteLine(
"the "+race+" Person Info:"+sex); 
        }

    }


    
public class BlackPerson:Person
    
{
        
public BlackPerson()
        
{
            sex
="Man";
            race
="Black";
        }

        
public BlackPerson(string Bsex)
        
{
            sex
=Bsex;
            race
="Black";
        }

        
public override void GetInfo()
        
{
            Console.WriteLine(
"the "+race+" Person Info:"+sex); 
        }

    }


    
public class WritePerson:Person
    
{
        
public WritePerson()
        
{
            sex
="Man";
            race
="Write";
        }

        
public WritePerson(string Wsex)
        
{
            sex
=Wsex;
            race
="Write";
        }

        
public override void GetInfo()
        
{
            Console.WriteLine(
"the "+race+" Person Info:"+sex); 
        }

    }

    
public class PersonSimFactory{
        
public PersonSimFactory(){}
        
public Person GetPerson(string RaceType){
            
if (RaceType=="Yellow")
               
return new YellowPerson();
            
else
            
if (RaceType=="Black")
                
return new BlackPerson();
            
else
            
if (RaceType=="Write")
                
return new WritePerson();
            
else
                
return new YellowPerson();
            
        }

    }

}

////////
///////
///////

using System;

namespace SimFactory
{
    
/// <summary>
    
///============== Program Description==============
    
///Name:SimFactory.cs
    
///Objective:SimFactory 
    
///Date:2006-02-09 
    
///Written By coffee.liu
    
///================================================
    
/// </summary>

    class Class1
    
{
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            PersonSimFactory PSF
=new PersonSimFactory();
            Person PP
=PSF.GetPerson("Yellow");
            PP.GetInfo();
            Console.WriteLine(
".");
            PP
=PSF.GetPerson("Black");
            PP.GetInfo();
            Console.WriteLine(
".");
             PP
=PSF.GetPerson("Write");
            PP.GetInfo();
        }

    }

}


具体代码(Pascal):

program SimFactory;
     
//============== Program Description==============
    
//Name:SimFactory.dpr
    
//Objective:SimFactory
    
//Date:2006-04-23
    
//Written By coffee.liu
    
//================================================
{$APPTYPE CONSOLE}

uses
  SysUtils;
  type Person
=class
       
protected
        sex:
string;
        race:
string;
        
public function GetSex():string;
        
public function GetRace():string;
        
public procedure GetInfo;virtual;abstract;

   
end;
   type YellowPerson
=class(Person)
       constructor YellowPerson();
        
public procedure GetInfo;override;
     
end;
    type BlackPerson
=class(Person)
       constructor BlackPerson();
        
public procedure GetInfo;override;
     
end;
    type WritePerson
=class(Person)
       constructor WritePerson();
        
public procedure GetInfo;override;
     
end;
    type PersonSimFactory
=class
        constructor PersonSimFactory();
        
public function  GetPerson(RaceType:string):Person;
         
end;
{ Person }

function Person.GetRace: string;
begin
 result:
=race;
end;

function Person.GetSex: string;
begin
  result:
=sex;
end;

{ YellowPerson }

constructor YellowPerson.YellowPerson;
begin
            sex:
='Man';
            race:='Yellow';
end;
procedure YellowPerson.GetInfo;
   begin
    inherited;
      WriteLn(
'the '+race+' Person Info:'+sex);
   end;
{ WritePerson }

procedure WritePerson.GetInfo;
begin
  inherited;
     WriteLn(
'the '+race+' Person Info:'+sex);
end;

constructor WritePerson.WritePerson;
begin
            sex:
='Man';
            race:='Write';
end;

{ BlackPerson }

constructor BlackPerson.BlackPerson;
begin
            sex:
='Man';
            race:='Black';
end;

procedure BlackPerson.GetInfo;
begin
  inherited;
      WriteLn(
'the '+race+' Person Info:'+sex);
end;

{ PersonSimFactory }

function PersonSimFactory.GetPerson(RaceType: string): Person;
begin

            
if RaceType='Yellow' then
               result:=YellowPerson.YellowPerson
            
else
            
if RaceType='Black' then
                result:=BlackPerson.BlackPerson
            
else
            
if RaceType='Write' then
                 result:=WritePerson.WritePerson
            
else
                 result:
=YellowPerson.YellowPerson;

end;

constructor PersonSimFactory.PersonSimFactory;
begin
      inherited;
end;
var
PSF:PersonSimFactory;
PP:Person;
begin
   PSF:
=PersonSimFactory.PersonSimFactory;
   PP:
=PSF.GetPerson('Yellow');
   PP.GetInfo;
   WriteLn(
'..');
   PP:=PSF.GetPerson('Black');
   PP.GetInfo;
   WriteLn(
'..');
   PP:=PSF.GetPerson('Write');
   PP.GetInfo;
   WriteLn(
'..error.');
   PP:=PSF.GetPerson('Write11');
   PP.GetInfo;
end.


我们甚至可以将抽象产品类作为子类的工厂:


程序代码(C#):
 

using System;

namespace SimFactoryPlus1
{
    
/// <summary>
    
///============== Program Description==============
    
///Name:SimFactory.cs
    
///Objective:SimFactory 
    
///Date:2006-02-09 
    
///Written By coffee.liu
    
///================================================
    
/// </summary>

    class Class1
    
{
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            
            Person PP
=Person.GetPerson("Yellow");
            PP.GetInfo();
            Console.WriteLine(
".");
            PP
=Person.GetPerson("Black");
            PP.GetInfo();
            Console.WriteLine(
".");
            PP
=Person.GetPerson("Write");
            PP.GetInfo();
        }

    }

    
public  class Person
    
{
        
protected string sex,race;
        
public string GetSex()
        
{
            
return sex;
        }

        
public string GetRace()
        
{
            
return race;
        }

        
public virtual void GetInfo()
        
{
        }

        
public static Person GetPerson(string RaceType)
        
{
            
if (RaceType=="Yellow")
                
return new YellowPerson();
            
else
                
if (RaceType=="Black")
                
return new BlackPerson();
            
else
                
if (RaceType=="Write")
                
return new WritePerson();
            
else
                
return new YellowPerson();
            
        }

    }


    
public class YellowPerson:Person
    
{
        
public YellowPerson()
        
{
            sex
="Man";
            race
="Yellow";
        }

        
public YellowPerson(string Ysex)
        
{
            sex
=Ysex;
            race
="Yellow";
        }

        
public override void GetInfo()
        
{
            Console.WriteLine(
"the "+race+" Person Info:"+sex); 
        }

    }


    
public class BlackPerson:Person
    
{
        
public BlackPerson()
        
{
            sex
="Man";
            race
="Black";
        }

        
public BlackPerson(string Bsex)
        
{
            sex
=Bsex;
            race
="Black";
        }

        
public override void GetInfo()
        
{
            Console.WriteLine(
"the "+race+" Person Info:"+sex); 
        }

    }


    
public class WritePerson:Person
    
{
        
public WritePerson()
        
{
            sex
="Man";
            race
="Write";
        }

        
public WritePerson(string Wsex)
        
{
            sex
=Wsex;
            race
="Write";
        }

        
public override void GetInfo()
        
{
            Console.WriteLine(
"the "+race+" Person Info:"+sex); 
        }

    }


}

程序代码(Pascal)

program SimFactory;
     
//============== Program Description==============
    
//Name:SimFactory.dpr
    
//Objective:SimFactory
    
//Date:2006-04-23
    
//Written By coffee.liu
    
//================================================
{$APPTYPE CONSOLE}

uses
  SysUtils;
  type Person
=class
       
protected
        sex:
string;
        race:
string;
        
public function GetSex():string;
        
public function GetRace():string;
        
public procedure GetInfo;virtual;abstract;
        
class function  GetPerson(RaceType:string):Person;
   
end;
   type YellowPerson
=class(Person)
       constructor YellowPerson();
        
public procedure GetInfo;override;
     
end;
    type BlackPerson
=class(Person)
       constructor BlackPerson();
        
public procedure GetInfo;override;
     
end;
    type WritePerson
=class(Person)
       constructor WritePerson();
        
public procedure GetInfo;override;
     
end;
{ Person }

class function Person.GetPerson(RaceType: string): Person;
begin
      
if RaceType='Yellow' then
               result:=YellowPerson.YellowPerson
            
else
            
if RaceType='Black' then
                result:=BlackPerson.BlackPerson
            
else
            
if RaceType='Write' then
                 result:=WritePerson.WritePerson
            
else
                 result:
=YellowPerson.YellowPerson;
end;

function Person.GetRace: string;
begin
 result:
=race;
end;

function Person.GetSex: string;
begin
  result:
=sex;
end;

{ YellowPerson }

constructor YellowPerson.YellowPerson;
begin
            sex:
='Man';
            race:='Yellow';
end;
procedure YellowPerson.GetInfo;
   begin
    inherited;
      WriteLn(
'the '+race+' Person Info:'+sex);
   end;
{ WritePerson }

procedure WritePerson.GetInfo;
begin
  inherited;
     WriteLn(
'the '+race+' Person Info:'+sex);
end;

constructor WritePerson.WritePerson;
begin
            sex:
='Man';
            race:='Write';
end;

{ BlackPerson }

constructor BlackPerson.BlackPerson;
begin
            sex:
='Man';
            race:='Black';
end;

procedure BlackPerson.GetInfo;
begin
  inherited;
      WriteLn(
'the '+race+' Person Info:'+sex);
end;

var
PP:Person;
begin

   PP:
=Person.GetPerson('Yellow');
   PP.GetInfo;
   WriteLn(
'..');
   PP:=Person.GetPerson('Black');
   PP.GetInfo;
   WriteLn(
'..');
   PP:=Person.GetPerson('Write');
   PP.GetInfo;
   WriteLn(
'..error.');
   PP:=Person.GetPerson('Write11');
   PP.GetInfo;
end.


我们甚至可以将3种角色全部合并!

程序代码(C#):

using System;

namespace SimFactoryPlus2
{
    
/// <summary>
    
///============== Program Description==============
    
///Name:SimFactory.cs
    
///Objective:SimFactory 
    
///Date:2006-02-09 
    
///Written By coffee.liu
    
///================================================
    
/// </summary>

    class Class1
    
{
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            Person PP
=Person.GetPerson("Yellow");
            PP.GetInfo();
            Console.WriteLine(
".");
            PP
=Person.GetPerson("Black");
            PP.GetInfo();
            Console.WriteLine(
".");
            PP
=Person.GetPerson("Write");
            PP.GetInfo();
        }

    }

    
public  class Person
    
{
        
private class YellowPerson:Person
        
{
            
public YellowPerson()
            
{
                sex
="Man";
                race
="Yellow";
            }

            
public YellowPerson(string Ysex)
            
{
                sex
=Ysex;
                race
="Yellow";
            }

            
public override void GetInfo()
            
{
                Console.WriteLine(
"the "+race+" Person Info:"+sex); 
            }

        }

        
private class BlackPerson:Person
        
{
            
public BlackPerson()
            
{
                sex
="Man";
                race
="Black";
            }

            
public BlackPerson(string Bsex)
            
{
                sex
=Bsex;
                race
="Black";
            }

            
public override void GetInfo()
            
{
                Console.WriteLine(
"the "+race+" Person Info:"+sex); 
            }

        }

        
private class WritePerson:Person
        
{
            
public WritePerson()
            
{
                sex
="Man";
                race
="Write";
            }

            
public WritePerson(string Wsex)
            
{
                sex
=Wsex;
                race
="Write";
            }

            
public override void GetInfo()
            
{
                Console.WriteLine(
"the "+race+" Person Info:"+sex); 
            }

        }


        
protected string sex,race;
        
public string GetSex()
        
{
            
return sex;
        }

        
public string GetRace()
        
{
            
return race;
        }

        
public virtual void GetInfo()
        
{
        }

        
public static Person GetPerson(string RaceType)
        
{
            
if (RaceType=="Yellow")
                
return new YellowPerson();
            
else
                
if (RaceType=="Black")
                
return new BlackPerson();
            
else
                
if (RaceType=="Write")
                
return new WritePerson();
            
else
                
return new YellowPerson();
            
        }


    }

}

程序代码(Pascal)

program SimFactoryPlus2;
     
//============== Program Description==============
    
//Name:SimFactory.dpr
    
//Objective:SimFactory
    
//Date:2006-04-23
    
//Written By coffee.liu
    
//================================================
{$APPTYPE CONSOLE}

uses
  SysUtils;
  type Person
=class
       
protected
        sex:
string;
        race:
string;
        constructor Create(Se:
string;Ra:String);
        
public function GetSex():string;
        
public function GetRace():string;
        
public procedure GetInfo;
        
class function  GetPerson(RaceType:string):Person;
   
end;
{ Person }

constructor Person.Create(Se:
string;Ra:String);
begin
  inherited create;
   sex:
=Se;
   race:
=Ra;
end;

procedure Person.GetInfo;
begin
WriteLn(
'the '+race+' Person Info:'+sex);
end;

class function Person.GetPerson(RaceType: string): Person;
begin
      
if RaceType='Yellow' then
               result:=person.Create('Man','Yellow')
            else
            
if RaceType='Black' then
                result:=person.Create('Man','Black')
            else
            
if RaceType='Write' then
                 result:=person.Create('Man','Write')
            else
                 result:
=person.Create('Man','Yellow');
end;

function Person.GetRace: string;
begin
 result:
=race;
end;

function Person.GetSex: string;
begin
  result:
=sex;
end;
var
PP:Person;
begin

   PP:
=Person.GetPerson('Yellow');
   PP.GetInfo;
   WriteLn(
'..');
   PP:=Person.GetPerson('Black');
   PP.GetInfo;
   WriteLn(
'..');
   PP:=Person.GetPerson('Write');
   PP.GetInfo;
   WriteLn(
'..error.');
   PP:=Person.GetPerson('Write11');
   PP.GetInfo;
end.

注意上面Pascal代码由于功能上的限制其实已经退化。
小结:
简单工厂能返回具有相同方法的类的实例,他们可以是不同的派生子类的实例,也可以是实际上毫无关系仅仅是共享了相同借口的类。不管哪种形式,这些实例中的方法必须是相同的,并且能够交替使用。





 

posted on 2006-04-21 17:35  coffeeliu  阅读(619)  评论(0编辑  收藏  举报