Delphi中的工厂模式

    在面向对象的程序设计中,某一功能的实现往往是依赖多个类的协同工作,这当中不必可避免的会有一个核心的关键类,非关键类对关键类的依赖程度比较高(耦合比较紧),关键类的变动会景响到非关键类与其通信。比如在某个MIS系统中,用户数据是存储在文件中的,那么所有数据的读取与保存都依赖与那和与文件进行通信的类。突然某一天客户说要将数据存储到数据库中,那么我们是必要找出所有使用这些与文件通信的类的代码,并使用新写的与数据库通信的类将其替换掉。这个改动量是可想而知的。那么有没有一种好的设计模式能够降低这种情况下的代码改动量呢?

    答案是肯定的。使用工厂模式。我们可以定义一个工厂类,提供一系列的创造对象的方法,代替类似TObject.Create的代码,降低类与类之间的耦合。

    我们就以前面讲到的情况为例,来说明工厂模式的使用。在系统中我们已经定义了一个负责数据读取的抽像类TDataReader和负责数据保存的抽象类TDataWriter,并分别派生了文件读取类TFileDataReader和文件保存类TFileDataWriter。

// 此处仅为说明,其他定义省略
type
  TDataReader 
=   class
  
private
    .......
  
protected
    .......
  
public
    .......
    procedure Read; 
virtual abstract ;
    .......
  end;

  TDataWriter 
=   class
  
private
    .......
  
protected
    .......
  
public
    .......
    procedure Write; 
virtual abstract ;
    .......
  end;

  TFileDataReader 
=   class (TDataReader)
  
private
    .......
  
protected
    .......
  
public
    .......
    procedure Read; 
override ;
    .......
  end;

  TFileDataWriter 
=   class (TDataWriter)
  
private
    .......
  
protected
    .......
  
public
    .......
    procedure Write; 
override ;
    .......
  end;

在重构这前,凡是用到数据读取与保存的地方,都是使用类似下面的代码

var
  Reader: TFileDataReader;
begin
  ......
  Reader :
=  TFileDataReader.Create;
  Reader.Read;
  ......
end;


var
  Writer: TFileDataWriter;
begin
  ......
  Writer :
=  TFileDataWriter.Create;
  Writer.Write;
  ......
end;

    现在客户要求我们将所有的数据存储到数据库中,就意味着我们要再分别从TDataReader类和TDataWriter类派生出两个与数据库通信的类TDBDataReader和TDBDataWriter(之前良好的类继承设计使我们在此省下了许多修工作),然后将类似上面的的Reader和Writer的构建语句改为

Reader :=  TDBDataReader.Crette;

Writer :
= TDBDataWriter.Create;

这样的改动也能达到客户的要求,但我们谁也不能保证在此之后不会再有任何的变化,为了不让噩梦重演,我们决定不使用这种修改方式。而是定义一个工厂类,负责创建出我们需要的数据读取类和保存类,即使将来再有变化,我们的修改也仅限于在工厂类内部的改动。

Type
  TDataReaderFactory 
=   class
  
public
    function CreatReader: TDataReader;
  end;

  TDataWriterFactory 
=   class
  
public
    function CreateWriter: TDataWriter;
  end;

implementation

{ TDataReaderFactory }

function TDataReaderFactory.CreatReader: TDataReader;
begin
  Result :
=  TDBDataReader.Create;
end;

{ TDataWriterFactory }

function TDataWriterFactory.CreateWriter: TDataWriter;
begin
  Result :
=  TDBDataWriter.Create;
end;

    在使用到数据读写类的地方,将代码改为

Reader :=  TDataReaderFactory.CretteReader;

Writer :
= TDataWriterFactory.CreateWriter;

至此,我们就通过工厂模式实现了客户端代码与数据存取类的松散耦合,也为将来的再修改提供了灵活性。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页