J
jxyyl
Unregistered / Unconfirmed
GUEST, unregistred user!
delphi是非常不错的开发工具,尤其是非常丰富的控件资源,这是其它语言很少能比拟的。
但它也有一个非常大的缺点,太多使用了数据感知控件,这样业务逻辑与界面逻辑不能
很好地分离,系统维护成本极高。
本人参考c#的ntiergen思路,整体分为数据访问层,业务逻辑层(从数据访问层继承用于放自定义的函数),界面层,而且不使用数据感知控件,现试开发一个小的软件,总体感觉程序结构清晰,程序可控制能力强,现将一点体会与大家分享。
1、数据访问层代码:
unit uDataAccessoper;
interface
uses sysutils,Classes,SqlExpr,DBXpress;
type Toper=class
private
FId:integer;
FOperCode:string;
FOperName:string;
FOperPasswd:string;
FCreateDate:TDateTime;
FCreateOper:string;
FOrgAccredit:string;
public
constructor Load(id:integer);
procedure Save;
procedure Delete(id:integer);
{%PublicMothed%}
published
Property Id:integer read FId write FId;
Property OperCode:string read FOperCode write FOperCode;
Property OperName:string read FOperName write FOperName;
Property OperPasswd:string read FOperPasswd write FOperPasswd;
Property CreateDate:TDateTime read FCreateDate write FCreateDate;
Property CreateOper:string read FCreateOper write FCreateOper;
Property OrgAccredit:string read FOrgAccredit write FOrgAccredit;
end;
type Topers=class(TList)
constructor GetAll();
end;
implementation
uses uConnection;
{ tBussinessOrg }
procedure Toper.Delete(id: integer);
var
sql:string;
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQL.Clear;
query.ParamCheck:=false;
query.SQLConnection:=GetConn;
query.SQL.Add('delete from oper where id=:id');
query.Params.ParseSQL(query.SQL.Text,true);
query.ParamByName('id').AsInteger:=id;
try
query.ExecSQL;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
constructor Toper.Load(id: integer);
var
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQL.Clear;
query.ParamCheck:=false;
query.SQLConnection:=GetConn;
query.SQL.Add('select * from oper where (id=:id)');
query.Params.ParseSQL(query.sql.text,true);
query.ParamByName('id').AsInteger:=id;
try
query.Open;
FId:=query.FieldByName('Id').asinteger;
FOperCode:=query.FieldByName('OperCode').asstring;
FOperName:=query.FieldByName('OperName').asstring;
FOperPasswd:=query.FieldByName('OperPasswd').asstring;
FCreateDate:=query.FieldByName('CreateDate').asDateTime;
FCreateOper:=query.FieldByName('CreateOper').asstring;
FOrgAccredit:=query.FieldByName('OrgAccredit').asstring;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
procedure Toper.Save;
var
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQLConnection:=GetConn;
//insert
if self.FId=0 then
begin
try
query.SQL.Clear;
query.ParamCheck:=false;
query.SQL.Add('insert into oper(Id,OperCode,OperName,OperPasswd,CreateDate,CreateOper,OrgAccredit) valuesId,:OperCode,:OperName,:OperPasswd,:CreateDate,:CreateOper,:OrgAccredit)');
query.Params.ParseSQL(query.SQL.Text,true);
query.ParamByName('Id').asinteger:=Id;
query.ParamByName('OperCode').asstring:=OperCode;
query.ParamByName('OperName').asstring:=OperName;
query.ParamByName('OperPasswd').asstring:=OperPasswd;
query.ParamByName('CreateDate').asDateTime:=CreateDate;
query.ParamByName('CreateOper').asstring:=CreateOper;
query.ParamByName('OrgAccredit').asstring:=OrgAccredit;
query.ExecSQL;
query.Close;
query.SQL.Clear;
query.SQL.Add('select last_insert_id() as id');
query.Params.Clear;
query.Open;
self.FId:=query.FieldValues['id'];
finally
query.SQLConnection.Close;
query.Free;
end;
end
//update
else
begin
try
query.SQL.Clear;
query.ParamCheck:=false;
query.SQL.Add('update oper set OperCode=:OperCode,OperName=:OperName,OperPasswd=:OperPasswd,CreateDate=:CreateDate,CreateOper=:CreateOper,OrgAccredit=:OrgAccredit where id=:id');
query.Params.ParseSQL(query.SQL.Text,true);
query.ParamByName('Id').asinteger:=Id;
query.ParamByName('OperCode').asstring:=OperCode;
query.ParamByName('OperName').asstring:=OperName;
query.ParamByName('OperPasswd').asstring:=OperPasswd;
query.ParamByName('CreateDate').asDateTime:=CreateDate;
query.ParamByName('CreateOper').asstring:=CreateOper;
query.ParamByName('OrgAccredit').asstring:=OrgAccredit;
query.ExecSQL;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
end;
constructor Topers.GetAll;
var
query:TSQLQuery;
oper:Toper;
begin
query:=TSQLQuery.Create(nil);
query.SQLConnection:=GetConn;;
query.SQL.Add('select * from oper');
try
query.Open;
while not query.Eofdo
begin
oper:=Toper.create;
oper.FId:=query.FieldByName('Id').asinteger;
oper.FOperCode:=query.FieldByName('OperCode').asstring;
oper.FOperName:=query.FieldByName('OperName').asstring;
oper.FOperPasswd:=query.FieldByName('OperPasswd').asstring;
oper.FCreateDate:=query.FieldByName('CreateDate').asDateTime;
oper.FCreateOper:=query.FieldByName('CreateOper').asstring;
oper.FOrgAccredit:=query.FieldByName('OrgAccredit').asstring;
self.Add(oper);
query.Next;
end;
finally
query.SqlConnection.Close;
query.Free;
end;
end;
end.
2、业务逻辑层代码:
unit uBusinessoper;
interface
uses sysutils,Classes,uDataAccessoper,SqlExpr,DBXpress;
type TB_oper=class(Toper)
private
public
procedure VerifyPassword(passwd:string);
constructor GetOperByCode(code:string);
published
end;
type TB_opers=class(Topers)
public
end;
implementation
uses uConnection;
{ TB_oper }
constructor TB_oper.GetOperByCode(code: string);
var
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQL.Clear;
query.ParamCheck:=false;
query.SQLConnection:=GetConn;
query.SQL.Add('select * from oper where (opercode=percode)');
query.Params.ParseSQL(query.sql.text,true);
query.ParamByName('opercode').AsString:=code;
try
query.Open;
if query.Eof and query.Bof then
raise exception.Create('没有该操作员!');
Id:=query.FieldByName('Id').asinteger;
OperCode:=query.FieldByName('OperCode').asstring;
OperName:=query.FieldByName('OperName').asstring;
OperPasswd:=query.FieldByName('OperPasswd').asstring;
CreateDate:=query.FieldByName('CreateDate').asDateTime;
CreateOper:=query.FieldByName('CreateOper').asstring;
OrgAccredit:=query.FieldByName('OrgAccredit').asstring;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
procedure TB_oper.VerifyPassword( passwd: string);
begin
if passwd <>self.OperPasswd then
raise exception.Create('密码错误!');
end;
end.
3、界面层代码(登录):
unit uLogin;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uDialogForm, StdCtrls, ExtCtrls;
type
TfrmLogin = class(TDialogForm)
GroupBox1: TGroupBox;
cmdlogin: TButton;
cmdCancel: TButton;
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
txtPasswd: TEdit;
txtUser: TEdit;
procedure cmdCancelClick(Sender: TObject);
procedure cmdloginClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmLogin: TfrmLogin;
function ShowForm:TModalResult;
implementation
uses uFrmMain, uBusinessoper;
{$R *.dfm}
function ShowForm:TModalResult;
begin
frmLogin:=TfrmLogin.Create(nil);
result:=frmLogin.ShowModal;
end;
procedure TfrmLogin.cmdCancelClick(Sender: TObject);
begin
inherited;
self.ModalResult:=mrCancel;
end;
procedure TfrmLogin.cmdloginClick(Sender: TObject);
begin
inherited;
frmMain.oper:=TB_oper.Create;
try
frmMain.oper.GetOperByCode(self.txtUser.Text);
frmMain.oper.VerifyPassword(self.txtPasswd.Text);
except
on e:exceptiondo
begin
showmessage(e.Message);
exit;
end
end;
self.ModalResult:=mrOk;
end;
end.
4、数据访问层与业务逻辑层可以用生成器生成,修改数据库后需要改动代码较少
欢迎大家多提意见!
但它也有一个非常大的缺点,太多使用了数据感知控件,这样业务逻辑与界面逻辑不能
很好地分离,系统维护成本极高。
本人参考c#的ntiergen思路,整体分为数据访问层,业务逻辑层(从数据访问层继承用于放自定义的函数),界面层,而且不使用数据感知控件,现试开发一个小的软件,总体感觉程序结构清晰,程序可控制能力强,现将一点体会与大家分享。
1、数据访问层代码:
unit uDataAccessoper;
interface
uses sysutils,Classes,SqlExpr,DBXpress;
type Toper=class
private
FId:integer;
FOperCode:string;
FOperName:string;
FOperPasswd:string;
FCreateDate:TDateTime;
FCreateOper:string;
FOrgAccredit:string;
public
constructor Load(id:integer);
procedure Save;
procedure Delete(id:integer);
{%PublicMothed%}
published
Property Id:integer read FId write FId;
Property OperCode:string read FOperCode write FOperCode;
Property OperName:string read FOperName write FOperName;
Property OperPasswd:string read FOperPasswd write FOperPasswd;
Property CreateDate:TDateTime read FCreateDate write FCreateDate;
Property CreateOper:string read FCreateOper write FCreateOper;
Property OrgAccredit:string read FOrgAccredit write FOrgAccredit;
end;
type Topers=class(TList)
constructor GetAll();
end;
implementation
uses uConnection;
{ tBussinessOrg }
procedure Toper.Delete(id: integer);
var
sql:string;
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQL.Clear;
query.ParamCheck:=false;
query.SQLConnection:=GetConn;
query.SQL.Add('delete from oper where id=:id');
query.Params.ParseSQL(query.SQL.Text,true);
query.ParamByName('id').AsInteger:=id;
try
query.ExecSQL;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
constructor Toper.Load(id: integer);
var
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQL.Clear;
query.ParamCheck:=false;
query.SQLConnection:=GetConn;
query.SQL.Add('select * from oper where (id=:id)');
query.Params.ParseSQL(query.sql.text,true);
query.ParamByName('id').AsInteger:=id;
try
query.Open;
FId:=query.FieldByName('Id').asinteger;
FOperCode:=query.FieldByName('OperCode').asstring;
FOperName:=query.FieldByName('OperName').asstring;
FOperPasswd:=query.FieldByName('OperPasswd').asstring;
FCreateDate:=query.FieldByName('CreateDate').asDateTime;
FCreateOper:=query.FieldByName('CreateOper').asstring;
FOrgAccredit:=query.FieldByName('OrgAccredit').asstring;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
procedure Toper.Save;
var
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQLConnection:=GetConn;
//insert
if self.FId=0 then
begin
try
query.SQL.Clear;
query.ParamCheck:=false;
query.SQL.Add('insert into oper(Id,OperCode,OperName,OperPasswd,CreateDate,CreateOper,OrgAccredit) valuesId,:OperCode,:OperName,:OperPasswd,:CreateDate,:CreateOper,:OrgAccredit)');
query.Params.ParseSQL(query.SQL.Text,true);
query.ParamByName('Id').asinteger:=Id;
query.ParamByName('OperCode').asstring:=OperCode;
query.ParamByName('OperName').asstring:=OperName;
query.ParamByName('OperPasswd').asstring:=OperPasswd;
query.ParamByName('CreateDate').asDateTime:=CreateDate;
query.ParamByName('CreateOper').asstring:=CreateOper;
query.ParamByName('OrgAccredit').asstring:=OrgAccredit;
query.ExecSQL;
query.Close;
query.SQL.Clear;
query.SQL.Add('select last_insert_id() as id');
query.Params.Clear;
query.Open;
self.FId:=query.FieldValues['id'];
finally
query.SQLConnection.Close;
query.Free;
end;
end
//update
else
begin
try
query.SQL.Clear;
query.ParamCheck:=false;
query.SQL.Add('update oper set OperCode=:OperCode,OperName=:OperName,OperPasswd=:OperPasswd,CreateDate=:CreateDate,CreateOper=:CreateOper,OrgAccredit=:OrgAccredit where id=:id');
query.Params.ParseSQL(query.SQL.Text,true);
query.ParamByName('Id').asinteger:=Id;
query.ParamByName('OperCode').asstring:=OperCode;
query.ParamByName('OperName').asstring:=OperName;
query.ParamByName('OperPasswd').asstring:=OperPasswd;
query.ParamByName('CreateDate').asDateTime:=CreateDate;
query.ParamByName('CreateOper').asstring:=CreateOper;
query.ParamByName('OrgAccredit').asstring:=OrgAccredit;
query.ExecSQL;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
end;
constructor Topers.GetAll;
var
query:TSQLQuery;
oper:Toper;
begin
query:=TSQLQuery.Create(nil);
query.SQLConnection:=GetConn;;
query.SQL.Add('select * from oper');
try
query.Open;
while not query.Eofdo
begin
oper:=Toper.create;
oper.FId:=query.FieldByName('Id').asinteger;
oper.FOperCode:=query.FieldByName('OperCode').asstring;
oper.FOperName:=query.FieldByName('OperName').asstring;
oper.FOperPasswd:=query.FieldByName('OperPasswd').asstring;
oper.FCreateDate:=query.FieldByName('CreateDate').asDateTime;
oper.FCreateOper:=query.FieldByName('CreateOper').asstring;
oper.FOrgAccredit:=query.FieldByName('OrgAccredit').asstring;
self.Add(oper);
query.Next;
end;
finally
query.SqlConnection.Close;
query.Free;
end;
end;
end.
2、业务逻辑层代码:
unit uBusinessoper;
interface
uses sysutils,Classes,uDataAccessoper,SqlExpr,DBXpress;
type TB_oper=class(Toper)
private
public
procedure VerifyPassword(passwd:string);
constructor GetOperByCode(code:string);
published
end;
type TB_opers=class(Topers)
public
end;
implementation
uses uConnection;
{ TB_oper }
constructor TB_oper.GetOperByCode(code: string);
var
query:TSQLQuery;
begin
query:=TSQLQuery.Create(nil);
query.SQL.Clear;
query.ParamCheck:=false;
query.SQLConnection:=GetConn;
query.SQL.Add('select * from oper where (opercode=percode)');
query.Params.ParseSQL(query.sql.text,true);
query.ParamByName('opercode').AsString:=code;
try
query.Open;
if query.Eof and query.Bof then
raise exception.Create('没有该操作员!');
Id:=query.FieldByName('Id').asinteger;
OperCode:=query.FieldByName('OperCode').asstring;
OperName:=query.FieldByName('OperName').asstring;
OperPasswd:=query.FieldByName('OperPasswd').asstring;
CreateDate:=query.FieldByName('CreateDate').asDateTime;
CreateOper:=query.FieldByName('CreateOper').asstring;
OrgAccredit:=query.FieldByName('OrgAccredit').asstring;
finally
query.SQLConnection.Close;
query.Free;
end;
end;
procedure TB_oper.VerifyPassword( passwd: string);
begin
if passwd <>self.OperPasswd then
raise exception.Create('密码错误!');
end;
end.
3、界面层代码(登录):
unit uLogin;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, uDialogForm, StdCtrls, ExtCtrls;
type
TfrmLogin = class(TDialogForm)
GroupBox1: TGroupBox;
cmdlogin: TButton;
cmdCancel: TButton;
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
txtPasswd: TEdit;
txtUser: TEdit;
procedure cmdCancelClick(Sender: TObject);
procedure cmdloginClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmLogin: TfrmLogin;
function ShowForm:TModalResult;
implementation
uses uFrmMain, uBusinessoper;
{$R *.dfm}
function ShowForm:TModalResult;
begin
frmLogin:=TfrmLogin.Create(nil);
result:=frmLogin.ShowModal;
end;
procedure TfrmLogin.cmdCancelClick(Sender: TObject);
begin
inherited;
self.ModalResult:=mrCancel;
end;
procedure TfrmLogin.cmdloginClick(Sender: TObject);
begin
inherited;
frmMain.oper:=TB_oper.Create;
try
frmMain.oper.GetOperByCode(self.txtUser.Text);
frmMain.oper.VerifyPassword(self.txtPasswd.Text);
except
on e:exceptiondo
begin
showmessage(e.Message);
exit;
end
end;
self.ModalResult:=mrOk;
end;
end.
4、数据访问层与业务逻辑层可以用生成器生成,修改数据库后需要改动代码较少
欢迎大家多提意见!