模式与数据库(仅供参考,嘿嘿)

angelface 2004-08-20 10:59:26
记得以前看过一个贴子关于数据库与面向对像的,所以
就写了这么一个小东西,(算是个演示程序吧, 也算是面向对像吧,嘿嘿),有问题的话请大家指正! -------CLH
//抽像接口
unit User;

interface

type
TUser = class
protected
FUserName: string;
FPassword: string;
FEmail: string;
procedure SetUserName(const AName: string); virtual; abstract;
function GetUserName: string; virtual; abstract;
procedure SetPassword(const APass: string); virtual; abstract;
function GetPassword: string; virtual; abstract;
procedure SetEmail(const AEmail: string); virtual; abstract;
function GetEmail: string; virtual; abstract;
public
property UserName: string read GetUserName write SetUserName;
property Password: string read GetPassword write SetPassword;
property Email: string read GetEmail write SetEmail;
end;

TUserBuilder = class
private
FUser: TUser;
public
procedure SetUserName(const AName: string); dynamic;
procedure SetPassword(const APass: string); dynamic;
procedure SetEmail(const AEmail: string); dynamic;
constructor Create(User: TUser);
end;

implementation

{ TUserBuilder }

constructor TUserBuilder.Create(User: TUser);
begin
FUser := User;
end;

procedure TUserBuilder.SetEmail(const AEmail: string);
begin
FUser.SetEmail(AEmail);
end;

procedure TUserBuilder.SetPassword(const APass: string);
begin
FUser.SetPassword(APass);
end;

procedure TUserBuilder.SetUserName(const AName: string);
begin
FUser.SetUserName(AName);
end;

end.

//真实的用户

unit GeneralUser;

interface

uses User, SysUtils, Windows, Controls, Classes, Variants;

type
TGeneralUser = class(TUser)
protected
procedure SetUserName(const AName: string); override;
function GetUserName: string; override;
procedure SetPassword(const APass: string); override;
function GetPassword: string; override;
procedure SetEmail(const AEmail: string); override;
function GetEmail: string; override;
end;

implementation

{ TGeneralUser }

function TGeneralUser.GetEmail: string;
begin
Result := FEmail;
end;

function TGeneralUser.GetPassword: string;
begin
if FPassword = '' then Result := ' ' else
Result := FPassword;
end;

function TGeneralUser.GetUserName: string;
begin
Result := FUserName;
end;

procedure TGeneralUser.SetEmail(const AEmail: string);
begin
if AEmail <> '' then FEmail := AEmail;
end;

procedure TGeneralUser.SetPassword(const APass: string);
begin
if APass <> '' then FPassword := APass;
end;

procedure TGeneralUser.SetUserName(const AName: string);
begin
if AName <> '' then FUserName := AName;
end;

end.

//用户控制接口
unit UserController;

interface

uses User;

type
IUserController = interface
function GetUser(UserName: string): TUser;
function Insert(User: TUser): Boolean;
function Update(User: TUser): Boolean;
function Delete(UserName: string): Boolean;
end;

implementation

end.

//代理用户控制
unit ProxyUserController;

interface

uses User, UserController, DbController;

type
TProxyUserController = class(TInterfacedObject, IUserController)
private
FDbUserController: IUserController;
public
function GetUser(UserName: string): TUser;
function Insert(User: TUser): Boolean;
function Update(User: TUser): Boolean;
function Delete(UserName: string): Boolean;
function CheckExsit(userName: string): Boolean;
constructor Create(connStr: string);
end;

implementation

{ TProxyUserController }

function TProxyUserController.CheckExsit(userName: string): Boolean;
begin

end;

constructor TProxyUserController.Create(connStr: string);
begin
FDbUserController := TDbController.Create(connStr);
end;

function TProxyUserController.Delete(UserName: string): Boolean;
begin
FDbUserController.Delete(UserName);
end;

function TProxyUserController.GetUser(UserName: string): TUser;
begin
Result := FDbUserController.GetUser(UserName);
end;

function TProxyUserController.Insert(User: TUser): Boolean;
begin
if not CheckExsit(User.UserName) then Exit else
FDbUserController.Insert(User);
end;

function TProxyUserController.Update(User: TUser): Boolean;
begin
FDbUserController.Update(User);
end;

end.

//真实的用户控制类,主要是和数据库打交道
unit DbController;

interface

uses User, UserController, Resource, DB, ADODB, SysUtils;

type
TDbController = class(TInterfacedObject, IUserController)
private
FConnection: TADOConnection;
FQuery: TADOQuery;
public
function GetUser(UserName: string): TUser;
function Insert(User: TUser): Boolean;
function Update(User: TUser): Boolean;
function Delete(UserName: string): Boolean;
constructor Create(connStr: string); virtual;
destructor Destroy; override;
end;

implementation

{ TDbController }

constructor TDbController.Create(connStr: string);
begin
FConnection := TADOConnection.Create(nil);
FConnection.ConnectionString := connStr;
if not FConnection.Connected then FConnection.Connected := true;
FQuery := TADOQuery.Create(nil);
FQuery.Connection := FConnection;
end;

function TDbController.Delete(UserName: string): Boolean;
begin

end;

destructor TDbController.Destroy;
begin
FConnection.Close;
FreeAndNil(FConnection);
FreeAndNil(FQuery);
inherited;
end;

function TDbController.GetUser(UserName: string): TUser;
begin

end;

function TDbController.Insert(User: TUser): Boolean;
begin
with FQuery do
begin
Close;
SQL.Clear;
SQL.Add('INSERT INTO Account(userName, pass, email) VALUES(:userName, :pass, :email)');
Parameters.ParamByName('userName').Value := User.UserName;
Parameters.ParamByName('Pass').Value := User.Password;
Parameters.ParamByName('Email').Value := User.Email;
ExecSQL;
end;
end;

function TDbController.Update(User: TUser): Boolean;
begin

end;

end.

//客户端
unit Main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, GeneralUser, User, UserController, DbController, ProxyUserController;

type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
FUser: TUser;
FUserController: IUserController;
FUserBuilder: TUserBuilder;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
DbPath: string;
begin
DbPath := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + ExtractFilePath(Application.ExeName) + 'user.mdb' + ';Persist Security Info=false';
FUser := TGeneralUser.Create;
FUserBuilder := TUserBuilder.Create(FUser);
FUserController := TProxyUserController.Create(DbPath);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
FUserBuilder.SetUserName(edit1.Text);
FUserBuilder.SetPassword(edit2.Text);
FUserBuilder.SetEmail(edit3.Text);
FUserController.Insert(FUser);
end;

end.
...全文
452 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
qizhanfeng 2004-09-16
  • 打赏
  • 举报
回复
不错
学习
xhh_88 2004-09-15
  • 打赏
  • 举报
回复
mark
angelface 2004-09-02
  • 打赏
  • 举报
回复
妈呀, 要强制结贴了, 还是早结了吧#
angelface 2004-08-31
  • 打赏
  • 举报
回复
嘿嘿,

TUser是抽像出来的一个类,代表一般的user, 如果要添加其它的就可以从这个类派生出来即可(如GeneralUser)。TUserBuilder是一个建造类,用途是用来创建产品零件.

interface的做用只是规范接口,而TProxyUserController是真正实现这个规范的接口的类,从而使客户端只管调用这个接口即可,而不用管具体的实现, 这个接口是不变的!所以TProxyUserController是必要的,
alphax 2004-08-30
  • 打赏
  • 举报
回复
认真看了一下,有几点个人看法说出来交流交流

1. 首先,标识符命名潜在地反映了设计人的设计思想,Controller,说明你比较倾向于具体把握对象的行为特征以及实现细节,这和现在大家比较认同的对象(被)驱动不大一样。从你的客户端的调用代码看来,也反映了这一点

2. 如果TUser是一个数据,那么TGeneralUser又是什么?TUserBuilder具体又有什么实在的作用?如果TUser是一个对象,好像改变它的状态(数据)不会产生任何的回应

3. 既然你用Interface,Interface本身就具有你所说的“代理”的作用,TProxyUserController就没有必要了
angelface 2004-08-30
  • 打赏
  • 举报
回复
因为TProxyUserController是一个代理, 为什么要引入这个代理呢? 就是要它来完成一个其它的任务, 而这些任务呢, 不应该是由TDbController来完成的,
angelface 2004-08-30
  • 打赏
  • 举报
回复
怎么说呢, 就是要让TProxyUserController做更多的工作(作一些TDbController不应可以做的工作) ,
qxj 2004-08-27
  • 打赏
  • 举报
回复
不乱套模式,
根据实际情况对待,

以前好像看过小小也写过这东东的吧.

angelface 2004-08-27
  • 打赏
  • 举报
回复
to: drift1981:private里的东西是外界访问不了的,但是protected里的东西是子类可以访问, 但是基它类访问不了的,

to: yinzhiw: 1.CheckExsit方法是用来检测此用户是否存在的.
        2.这样也可以,那样就是一个退化的建造模式!
yinzhiw 2004-08-27
  • 打赏
  • 举报
回复
想请教楼主两个问题:
1.你的CheckExsit方法放在TProxyUserController类里面,你如何能去实现它呢?
2.你用FUserBuilder := TUserBuilder.Create(FUser);创建FUserBuilder ,然后再
FUserBuilder.SetUserName(edit1.Text);方法来作,如果直接用,
FGeneralUser:=TGeneralUser.Create;然后FGeneralUser:=SetUserName(edit1.Text);
这样有什么不妥吗?
drift1981 2004-08-27
  • 打赏
  • 举报
回复
楼主这么热心,想请教你个问题
什么时候该把类成员写到private或者protected里,什么时候写到public里,是不是不想让外界访问的方法都要存到private,protected
yinzhiw 2004-08-27
  • 打赏
  • 举报
回复
不错
oop我也想用,看了oop的书籍,好像也能看懂,但是一旦
到了自己写代码的时候就不知道怎么去用了
angelface 2004-08-27
  • 打赏
  • 举报
回复
自己顶一下@
yinzhiw 2004-08-27
  • 打赏
  • 举报
回复
个人认为如果你放在TProxyUserController会增加很多的工作量,而且放在TDbController里面并没有什么不妥
angelface 2004-08-27
  • 打赏
  • 举报
回复
如果放在TDbController里,就正好相反, 因为, 要这个TProxyUserController就是用来做一些额外工作的, 比如不是它本身该做的工作@
yinzhiw 2004-08-27
  • 打赏
  • 举报
回复
我觉得你的CheckExsit这个函数是不是可以直接放在TDbController类里面呢?
这样就不需要别的类来实现了?
angelface 2004-08-27
  • 打赏
  • 举报
回复
因为不想搞的太复杂, 所以没有写嘿嘿
angelface 2004-08-27
  • 打赏
  • 举报
回复
to:qxj, 嘿嘿, 绝对没有乱套模式, 因为, 这就是实际项目中做的,

to: yinzhiw , 这里可以用另一个类来实现,
yinzhiw 2004-08-27
  • 打赏
  • 举报
回复
To 楼主
我知道你的CheckExsit方法是用来检测此用户是否存在的
但是你放在TProxyUserController类里面,能实现此功能吗?
你要检查的话,必须到数据库中查找,但是在你的类里面好像是
实现不了的把?
beyondtkl 2004-08-26
  • 打赏
  • 举报
回复
呵呵 路过 不过楼主好像太多嘿嘿了哦。。
加载更多回复(22)

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧