Delphi制作客户端系统功能组件分离的架构设计

如何将界面代码和功能代码分离(基于Delphi/VCL)  东日文档    很多朋友看了上次我写的“创建良好设计的代码(基于Delphi/VCL)”后,对我说感觉上可以接受其中的观点,但似乎说得太简单,不够具体;也有的朋友对其中的一个小例子有些异议。因此便有了此文。    上次,我举的例子是这样的:假设要从某处获得一个字符串列表,然后显示于 TListBox 中,我所推崇的代码是:    ObjectXXX := TObjectXXX.Cre 阅读详情

Delphi制作客户端系统功能组件分离的架构设计

 

一.             目标:

a)         减少客户端exe程序的长度

b)        更好的组织源代码项目文件夹的结构

c)        使用基于接口的方式编程,减少模块之间的耦合度

d)        物理分离不同的功能组件

二.             实现方式:

a)         三类子项目:

l         主窗体和主框架项目

l         全局资源包项目(package BPL项目)

l         功能组件项目(com dll组件)

b)        主项目是普通的窗体项目或者MDI项目

l         主项目是整个项目的主框架,负责组织所有的功能组件

l         负责验证用户身份和初始化全局资源(如全局网络连接)

l         利用菜单或者子窗体调用功能组件

l         将“全局资源包”项目中的全局数据模块和全局变量单元增加到本项目中

c)        全局资源包bpl项目。

l         本项目封装全局使用的数据资源。

1.         本项目生成和安装后,其他项目将本项目产生的bpl包编译到里面

2.         主项目和功能组件项目都将本项目的包编译进去后,运行时本项目的所有变量均有一个唯一实例

3.         利用这一点可以共享全局数据以及不同项目之间进行数据交流

l         包含全局使用的数据模块

l         也可以放置全局变量。

d)        功能组件子项目是activeX Library项目

新建activeXLibrary项目,增加一个automachine object控件

l         令新接口继承IPlug接口

1.         IPlug是插件的通用接口,所有功能组件都要支持这个接口

2.         本接口支持getname函数和run函数

3.         getname函数用于返回插件名字

4.         run函数用来运行插件(如果插件是个独立的子系统的话)

l         子功能组件在新接口中增加函数,对外提供子功能

l         将“全局资源包”项目中的全局数据模块和全局变量单元增加到本项目中

 

三.             缺点和需要注意的问题:

本方案只是利用部分OO思想主要解决在客户端桌面程序上的物理分离问题,并不是纯粹用OO的方法做系统分析和设计。

特别是各个功能模块(COM组件)访问全局的数据模块,是通过delphi的共享包(bpl)来解决的。利用这种方式,com组件可以直接在编程中访问数据模块单元。(如果将数据模块作为单独的一个dll或者com,复杂度太大而且面临无法随时修改的问题。所以采用了这种方式。)

但是这样一来不同的功能组件都依赖于这个共享包,增加了功能组件耦合度。所以最好在每个功能组件项目中增加自己的数据模块,存放本模块专用的数据库资源。在全局数据模块中只保存全局链接、通用的查询组件(例如登陆和权限)等。尽量减少功能组件对全局数据模块的依赖。

可以在全局数据包项目中增加一个单元,将通用的业务逻辑操作封装在内,供所有项目调用;

可以在每个功能组件项目中增加业务逻辑操作单元,以便减少业务逻辑功能代码对界面的依赖性;

 

客户端和com组件的参数传递:

com只能使用标准的数据类型,对于编程中其他类型只能通过间接的类型转换来实现

1)对于某些控件对象(Tform类型和TwinContrl类型等)delphi数据类型,可以使用int类型与指针类型进行类型转换来实现,(必须在同一个进程内,否则指针无法这个能取映射),例如下面的实现:

接口方法:

  ITLogin = interface(IPlug)

    ['{06B82963-EE63-49B6-8989-8D3021928447}']

    procedure ShowSub(POwner: SYSUINT; ParentHand: SYSUINT); safecall;

    // POwner在com接口中参数类型是整形,在实现中当作指针来用

    // ParentHand在com接口中参数类型是整形,在实现中当作HWND类型来用

Com的接口实现:

procedure TTLogin.ShowSub(POwner: SYSUINT; ParentHand: SYSUINT);

type

  PComp=^TComponent;

begin

  if SubForm=nil then

    SubForm:= TSubForm.Create(PComp(POwner)^);

//利用强制类型转换,先还原成^Tcomponent的指针类型,然后解除指针参照

  subform.ParentWindow:=ParentHand;//直接赋值,隐式类型转换

  subform.Show;

end;

客户端

var

loginCom:ITLogin;

begin

    if loginCom=nil then

       loginCom:=CreateComObject(CLASS_TLogin) as ITLogin;

    LoginCom.ShowSub(cardinal(@self),self.Panel1.Handle);

// cardinal(@self)   先取地址,再显式类型转换

// self.Panel1.Handle 隐式类型转换

End;

 

 

 

 

2)对于不同进程空间内的转换,就不能简单的像上面一样利用指针进行数据传递了。对于“记录”类型:对于下面一种方法,应该小心使用:

记录类型的类型转换,利用Move和SizeOf

装入Variant:

  MyQuery: Record;

  V:Variant;

  P:Pointer;

 

  V:=VarArrayCreate([0,Sizeof(Record)],varByte);

  P:=VarArrayLock(V);

  Move(MyQuery,P^,Sizeof(Record));

  VarArrayUnLock(V);

 

取出 V:variant:

var

P:Pointer;

MyQuery: Record;

begin

  P:=VarArrayLock(V);

  Move(P^,MyQuery,Sizeof(Record));

  VarArrayUnLock(V);

 

 

 

四.             项目文件夹结构

项目文件夹

Bin

Tmp

Frame

class

Interface

CommDataPk

Com组件1

Com组件2

编译后的可执行文件以及dll文件

编译产生的dcu等中间文件

主程序框架

项目所需要的公共工具类

项目所需要的公共接口单元(例如IPlug)

公共数据模块和公共数据 bpl项目

功能组件  子系统

注意以下设置要点:

      

 

2

五.             日后的改进和演化:

增加主框架对子功能组件的组织能力(例如快捷键、主菜单、com组件的载入器);

增加服务器的功能,配合子功能做一些编码,将单纯的数据访问演化为逻辑中间件;

delphi Restful:客户端实现的四种方式及其比较 delphi Restful:客户端实现的四种方式 摘要: 一、NetHTTP技术体系: TNetHTTPClient; TNetHTTPRequest二、REST技术体系: TRESTClient; TRESTRequest; TRESTResponse; TRESTResponseDataSetAdapter三、Indy技术体系:IdHTTP + IdSSLOpenSS... 阅读详情

相关推荐

在Delphi中制作以浏览器为界面的程序

网页浏览器是个显示网站服务器或文件系统内的文件,并让用户与这些文件交互的一种应用软件。它用来显示在万维网或局域网等内的文字、图像及其他信息,浏览器是最常用的客户端程序。在这篇教程中,小编主要为你介绍在Delphi中制作以浏览器为界面的程序。   相信有不少的朋友都希望将自己编写出来的应用程序制作成为以浏览器作为界面,然后只需要通过打开浏览器的方式来使用应用程序吧。大家以为这样子操作很

zyj66666的博客 3545

delphi dll模块化三层框架下载

源码下载,delphi源码,dll客户端,delphi dll

173713873 898

Delphi 7打造RESTful API客户端

尽管Delphi 7是一个相对较老的开发工具,但通过结合Indy组件和其他第三方库,我们仍然可以使用它来创建一个功能强大的RESTful API客户端。希望这篇文章能给你带来一些启发和帮助!如果你有任何问题或建议,请随时留言交流。

程序猿视角 1195

Delphi 实现界面和业务分离(2)-界面和业务分离演化实例

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, ADODB, ExtCtrls, DBCtrls, StdCtrls, Grids, DBGrids, Mask, ...

aishizhuang1602的博客 278

用Delphi制作BPL包

用Delphi制作BPL包 2007-6-21 背景 GCM3构造时间长的问题由来已久。伴随着时间的流逝,系统功能越来越强大,模块越来越多,目前仅GCM一项,需要编译的客户端dll达389个之多。在编译机上,一次完整的编译过程(GCM+GCC_PE)耗时更是长达100分钟。经常出现这样的情况:开发人员和测试人员并没有别的事情,就是在等待编译版本,比如发版前的完整构造,或者每日构造

流年~~ 8783

基于 Delphi 的前后端分离:之三,使用 HTMX

前后端分离的例子

pcplayer的博客 1742

Delphi 三层框架开发客户端开发

新建一个application 如图 添加以下控件 代码如下

gykthh的专栏 5901

跨平台Delphi UI开发——FMSoft uniGUI组件库

Delphi作为一款历史悠久的集成开发环境,以其强大的VCL框架和FireMonkey (FMX) 框架,一直深受开发者喜爱。在Delphi 10.2 Tokyo及之后的版本中,引入了FMSoft的uniGUI组件库,它为Delphi提供了在多平台下开发富客户端应用程序的能力。FMSoft uniGUI的组件库是构建富客户端应用程序的核心,它拥有广泛的标准组件和高级控件。uniGUI组件库的设计理念强调了组件的复用性、可扩展性和平台无关性。

weixin_34598113的博客 1802

悟透delphi 第十章 操作界面与操作逻辑

第一章  DELPHI的原子世界第二章  DELPHI与WIN32时空第三章  多线程第四章  接口第五章  包第六章  事件与消息第七章  组织你的模块第八章  探索数据库第九章  多层体系结构第十章  操作界面与操作逻辑第十一章  面向对象数据库基础本书原著李战(leadzen)大牛,由tingsking18整理,本人blog发布的版本经过战哥同意,转载请著名出处和原作者!第十章   

我一路走来--- 4153

MQTT协议客户端实现:Delphi中的mosquitto应用

本文还有配套的精品资源,点击获取 简介:mosquitto-client是一个基于MQTT协议的客户端程序,利用mosquitto库实现轻量级发布/订阅消息传输。它支持多种编程语言,并在物联网中广泛使用。本文介绍了在Delphi中如何利用mosquitto库实现MQTT客户端功能,包括连接服务器、发布和订阅消息、处理回调及接收消息等。同时,也讨论了错误处理、重连策略等关键考...

weixin_36427956的博客 2056

利用Delphi Socket组件制作的简单TCP服务器和客户端

利用Delphi Socket控件开发的一个简单的TCP服务器和客户端。经过回送地址测试,本机IP和其它主机测试都可用。 TClientSocket 本来是D5默认安装的,但是D7使用的Indy组件后,就没有默认安装了,如果你喜欢这个组件,可以在delphi 7,delphi2007 delphi 2009 delphi 2010的安装目录lib文件夹或是bin文件夹找到dclsockets70.bpl or dclsockets100.bpl dclsockets140.bpl 组件包,安装上去就OK了.dclsockets70.bpl or dclsockets100.bpl dclsockets140.bpl 是TCientSocket和TServerSocket必需的运行包.

基于 Delphi 的前后端分离:之五,使用 HTMX 让页面元素组件化之面向对象的Delphi代码封装

用 Delphi 的类封装前端图表组件

pcplayer的博客 1450

flink定位反压节点

在 Apache Flink 中定位反压(Backpressure)节点需要结合监控工具和作业行为分析。

2301_80954266的博客 1046

FTP客户端(Delphi7&Indy组件实现)

2004.6.27首发于blogcn.com。转发至此老师布置了大作业,占70分,没办法,做吧.编程实现ftp客户端程序(加权1.3)要求:1. 地址列表、端口和用户名以及用户密码的简单管理功能;2. 文件的断点续传功能;3. 简单的容错功能;4. 本地资源与远程资源的列表显示功能;5. 友好的用户界面;语言不限,环境为Linux或windows;    为了迁就工作的原因,采用了自己不熟悉的DE

成片的大树 4359

Unity插件-Mirror使用方法(一)Mirror介绍

Unity Mirror 是一个专为 Unity 引擎设计的开源、社区驱动的网络库,主要用于简化多人联机游戏的开发。它最初是为了替代 Unity 原生的 UNet 系统(已被官方弃用)而创建的,因其轻量、灵活和高效的特点,成为 Unity 开发者构建多人游戏的热门选择。

qq_44501691的博客 4099

四足机器人机械结构设计:从腿型到驱动的全面解析

本文全面解析了四足机器人机械结构设计的核心要点。资深工程师老张深入探讨了并联腿与串联腿的选型策略、不同腿型布局对稳定性的影响,并详细对比了皮带轮与连杆驱动方式的优劣。文章结合实战经验,强调了足端设计、材料选择及整体结构轻量化等关键细节,为机器人开发者提供了从理论到实践的宝贵指导。

assembly8low的博客 632

Delphi MQTT客户端库

本仓库提供了一个专为Delphi 7设计的MQTT(Message Queuing Telemetry Transport)客户端实现。MQTT是一种轻量级的消息协议,广泛应用于物联网(IoT)、移动应用以及需要高效、可靠且低带宽通信的场景。此客户端库特别适合那些希望在Delphi应用程序中集成MQTT协议的开发者。它已验证可与EMQ等主流MQTT broker兼容,并确保了基本的网络连接维持、心

gitblog_09708的博客 994

ENVI 5.6保姆级教程:高分七号DLC影像从打开到融合的完整流程(附避坑指南)

本文详细介绍了ENVI 5.6处理高分七号DLC影像的完整流程,包括环境准备、数据解压、正射校正、图像融合等关键步骤。特别针对国产卫星数据处理的独特挑战,提供了实用的避坑指南和优化技巧,帮助用户高效完成光学影像的预处理和质量提升。

weixin_33269743的博客 382

用Delphi制作DLL

用Delphi制作DLL  一  Dll的制作一般步骤  二  参数传递  三  DLL的初始化和退出清理[如果需要初始化和退出清理]  四  全局变量的使用  五  调用静态载入  六  调用动态载入  七  在DLL建立一个TForM  八  在DLL中建立一个TMDIChildForM  九  示例:  十  Delphi制作的Dll与其他语言的混合编程中常遇问题:  十一  相关资料   

yuhongwei的专栏 1160

【2024年华为秋招-12月25日-第三题(300分)- PCB印刷电路板布线】(题目+思路+Java&C++&Python解析+在线测试)

在PCB印刷电路板设计中,器件之间的连线需要避免线路的阻抗值增大、而且赛件之间还有别的器件和别的干扰源,在布线时我们希望受到的干扰尽量小。现将电路板简化成一个M×N的矩阵,每个位置(单元格)的值表示其源干扰度。如果单元格的值为0,表示此位置没有干扰源;如果单元格的值为非0,则表示此位置是干扰源,其值为源干扰度。连线经过干扰源或干扰源附近会增加连线的总干扰度。位置Axy的干扰源的源干扰度为dd01、若连线经过位置Axy,则其总干扰度会增加d;2、若连线经过离位置A。

m0_73659489的博客 344

Python时间序列:PaddleTS-时间序列分类

评估的指标采用F1,Precision,Recall,PaddleTS已经基于TSDataset实现了这三个指标的计算,直接调用即可。使用内置的API:get_dataset加载BasicMotions数据集。模型训练完成之后,可以对测试集进行预测并评估。模型保存之后,可以加载模型用于新的数据预测。可以将训练完成的模型保存到指定路径。概率预测 可以返回每个分类的概率。安装paddlets。

斌擎科技 1292

用Delphi制作DLL的方法

转自:http://blog.youkuaiyun.com/FlyHope2005/archive/2004/10/14/136004.aspx用Delphi制作DLL的方法一 Dll的制作一般步骤二 参数传递三 DLL的初始化和退出清理[如果需要初始化和退出清理]四 全局变量的使用五 调用静态载入六 调用动态载入七 在DLL建立一个TForM八 在DLL中建立一个TMDIChildForM九 示例:

CrazyCock的专栏 1534

【Claude Code 源码解析教程】第4章:QueryEngine 查询引擎

本章深入解析 Claude Code 的核心引擎——QueryEngine,它是整个对话系统的"心脏",负责管理会话状态、消息处理流程和多轮对话支持。

rengang66的博客 269

在Delphi中使用Queued 组件

 在Delphi中使用Queued Components队列组件(Queued Components)是一项基于微软消息队列服务(Microsoft Message Queuing Services)的COM+技术。它提供了一种简易的异步引用和执行组件的方法。发送方和接收方都不心考虑对方现在是否可用和能否获得而独立运行。作为一项COM技术。队列指的是用于存储消息以便将来检索的空间。队列

aflash的专栏 1469

【100%通过率】2024华为OD机试真题E卷 C++ 实现【栈数据合并/空栈压数】

向一个空栈压入正整数,每当压入一个整数时,执行以下规则(设: 栈顶至栈底整数依次编号为n1、n2...nx, n1为最新压入的整数)

MISAYAONE的博客 1553

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: 软件设计中的可用性
下一篇: DBGrid排序
softworkman
博客等级 码龄21年 1粉丝 11原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值