有一个父类假设叫A,有几个从A继承的子类A1,A2,A3......
在主控程序中,我希望创建A1, A2, A3......
我想采用工厂模式能够方便些
但是我的疑惑是我怎样创建A1,A2,A3......
我看到一些书上的例子是这样的:
if ( sClassName='A1') then
  A1.Create();
else if sClassName='A2' then
  A2.Create();
......
我感觉这样仅仅是代码进行了封装,并没有进行抽象呀,有没有办法实现抽象呀?比如
函数(sClassName).Create 就是直接将字符串sClassName转换成类名
getClass可以将字符串转换成类,但是转换成的类还是需要进行类型转换的,现在我的想法就是希望工厂(主控程序)不必知道具体要创建什么类,只要在数据库或者配置文件中写好要创建多少类,系统就可以自动创建

解决方案 »

  1.   

    本省工厂模式 的工厂就不管具体产生什么类以C++描述是通过模板的
    delphi 不清楚
    class Creator
    {
    public:
    virtual Product* CreateProduct() = 0 ;
    };template < class ConcreteProduct > // 就是你上面说的 A1, A2....
    class ConcreteCreator: public Creator
    {
    public:
    virtual Product* CreateProduct() { return new ConcreteProduct() ; }
    };
      

  2.   

    实现下面是一个用来创建上面带有三个编辑框(edit boxe)的面板(panel)的例子,在这个例
    子中,我们准备用专门创建的一个叫PanelMaker的类的CreatePanel方法来创建我们的
    面板。TypeTPanelMaker = class (TObject)
    public
    function CreatePanel( aOwner : TWinControl;
    Factory : TAbstractFactory ): TPanel;
    end;implementationfunction TPanelMaker.CreatePanel(aOwner : TWinControl; Factory : TAbstractFactory): TPanel;
    var
    TempPanel : TPanel;
    TempEdit1 : TEdit;
    TempEdit2 : TEdit;
    TempEdit3 : TEdit;
    begin
    TempPanel := Factory.MakePanel( aOwner );
    TempEdit1 := Factory.MakeEdit( TempPanel, 'Test1', 10, 10 );
    TempEdit2 := Factory.MakeEdit( TempPanel, 'Test2', TempEdit1.Top + TempEdit1.Height + 10,
    TempEdit1.Left );
    TempEdit3 := Factory.MakeEdit( TempPanel, 'Test3', TempEdit2.Top + TempEdit2.Height + 10,
    TempEdit2.Left );
    CreatePanel := TempPanel;
    end;请注意,我们并没有直接用TPanel.Create来创建我们的面板,而是用了一个抽象工厂的
    方法MakePanel来代替它,这样,如果我们要改动的时候,将变得更加容易。抽象工厂的具体定义如下:typeTAbstractFactory = class (TObject)
    protected
    FPanel : TPanel;
    public
    function MakeEdit( aOwner : TWinControl;vText : string;vTop : Integer;vLeft : Integer ): TEdit; virtual;
    function MakePanel( aOwner : TWinControl ) : TPanel; virtual;
    end;implementationfunction TAbstractFactory.MakeEdit( aOwner : TWinControl;vText : string;vTop : Integer;vLeft : Integer ): TEdit;
    var
    TempEdit : TEdit;
    begin
    TempEdit := TEdit.Create( aOwner );
    TempEdit.Parent := aOwner;
    TempEdit.Text := vText;
    TempEdit.Top := vTop;
    TempEdit.Left := vLeft;
    MakeEdit := TempEdit;
    end;function TAbstractFactory.MakePanel( aOwner : TWinControl ) : TPanel;
    var
    TempPanel : TPanel;
    begin
    TempPanel := TPanel.Create( aOwner );
    TempPanel.Parent := aOwner;
    MakePanel := TempPanel;
    end;这个定义是用来创建标准编辑框和标准面板的,但是,如果我们想要创建一个特殊类型
    的编辑框,比如说,我们希望那个编辑框只允许大写字母。TypeTUppercaseEdit = class (TEdit)
    protected
    FOnChange : TNotifyEvent;
    procedure Change; override;
    function GetUppercase : string;
    procedure SetUppercase( Value : string );
    public
    property Text : string read GetUppercase write SetUppercase;
    end;现在你可以创建一个用这个编辑框来代替标准编辑框的抽象工厂类的子类。function TUppercaseFactory.MakeEdit( aOwner : TWinControl;vText : string;vTop : Integer;vLeft : Integer ): TEdit;
    var
    TempEdit : TUppercaseEdit;
    begin
    TempEdit := TUppercaseEdit.Create( aOwner );
    TempEdit.Parent := aOwner;
    TempEdit.Text := vText;
    TempEdit.Top := vTop;
    TempEdit.Left := vLeft;
    MakeEdit := TempEdit;
    end;就像这样,你并不需要对PanelMaker.CreatePanel方法有任何改动。
      

  3.   

    to  aiirii(ari-爱的眼睛) :
      我在A中定义了一些虚方法,比如f1,f2,在每个子类中overload了f1,f2,写了自己的实现,factory中定义了一个actionForm,类型是父类型
    问题是但是如果直接使用actionForm.f1调用的是A中的f1方法,我希望能够执行子类型的方法
      

  4.   

    >>问题是但是如果直接使用actionForm.f1调用的是A中的f1方法,我希望能够执行子类型的方法
    面向對象中的多態可以保證你要的如
    var 
     a: TA;
    begin
     a := TChildA.Create;
     a.f1; 這樣調用的 TChildA的 f1 方法>>在每个子类中overload了
    應用用 override
      

  5.   

    帮忙顶一下吧!我很想学,可是还没学!刻苦学习中ing.......................
      

  6.   

    声明
     TabstractA=class(Tobject)
     ......
     TA1=class(TabstractA)
     ......
     TA2=class(TabstractA)
     ......
     TA3=class(TabstractA)
     ......
    实现时应为
     var Taa;TabstractA
     begin
       Taa:=TabstractA(TA1.create);
     end;
    注意的是抽象类接口和派生类接口的定义是一样的