如何设计?高手请进!内详。 ( 积分: 200 )

  • 主题发起人 主题发起人 lichaogang
  • 开始时间 开始时间
L

lichaogang

Unregistered / Unconfirmed
GUEST, unregistred user!
现有一小系统,要求如下:
设计一个预警系统,可以定时运行,能够找出一些问题,并自动发送EMail给相应的用户以提醒。如,某一个定单就要开始生产了,但物料还没有到齐,这时就要发一个预警给相应的用户。
现在公司提出了三种预警的要求,分别称为AlertA,AlertB,AlertC吧。
分析:
1.对于这三种预警而言,它们的运行逻辑都是相同的,可以分为三步,即 检查数据,产生预警-->保存相应预警并设置状态--->发送Email(格式不同)给相关用户。
2.公司以后可能会扩充预警的种类。
不知这种情况下各位高人会用什么方法来开发??
-------------------------------------------------------------
基于以上两点,我想先写一些基础的类以实现它的宏观上的行为。
大致如下:
1>写三个类(接口),分别体现以上三步的功能。
2>具体的预警再实现具体的类再写具体的计算方法。
3>因为三步中每一个类都是对应的(配套的),所以准备采用工厂方法模式将三个类实例的创建封装起来。
问题:
在系统中要分别运行三种预警(也可能是N种),这就要求用工厂一一创建类实例并运行之,为此,我在工厂的构造函数上加入了一个参数以标识需要创建哪三个类的实例,这样就要求将预警的“类别”作为参数来创建工厂类的实例并要将它硬编码到系统中!!
不知各位虾可有更好的方法或是可以解决以上之问题,就不吝赐教,3ks.
 
现有一小系统,要求如下:
设计一个预警系统,可以定时运行,能够找出一些问题,并自动发送EMail给相应的用户以提醒。如,某一个定单就要开始生产了,但物料还没有到齐,这时就要发一个预警给相应的用户。
现在公司提出了三种预警的要求,分别称为AlertA,AlertB,AlertC吧。
分析:
1.对于这三种预警而言,它们的运行逻辑都是相同的,可以分为三步,即 检查数据,产生预警-->保存相应预警并设置状态--->发送Email(格式不同)给相关用户。
2.公司以后可能会扩充预警的种类。
不知这种情况下各位高人会用什么方法来开发??
-------------------------------------------------------------
基于以上两点,我想先写一些基础的类以实现它的宏观上的行为。
大致如下:
1>写三个类(接口),分别体现以上三步的功能。
2>具体的预警再实现具体的类再写具体的计算方法。
3>因为三步中每一个类都是对应的(配套的),所以准备采用工厂方法模式将三个类实例的创建封装起来。
问题:
在系统中要分别运行三种预警(也可能是N种),这就要求用工厂一一创建类实例并运行之,为此,我在工厂的构造函数上加入了一个参数以标识需要创建哪三个类的实例,这样就要求将预警的“类别”作为参数来创建工厂类的实例并要将它硬编码到系统中!!
不知各位虾可有更好的方法或是可以解决以上之问题,就不吝赐教,3ks.
 
这样设计挺好的啊,有问题吗?
每个新的类都要重新定义,又何必不硬编码工厂参数?
 
如果为了便于扩充那么做成插件
所谓插件其实很简单
其本质就是一个DLL文件
只不过是定义了一些公共方法而已
其他的设计你已经不错的了。加油
 
多谢楼上两位,其实我感觉我的设计还是非常粗糙的。
各位请踊跃发表见解。
 
It is easy,not to be too complex!
 
to hardware007:
I know.The system is so easy.
But i think if you just code for current alert type,it is difficult when company request extending the system.
Maybe,i paid attention to design too much.Thank you for answering my question in any case.
 
每种预警做成一个Dll,遵循相同的接口
主程序从配置文件中读取有几个预警类别,分别对应的Dll
这样不就可以了?
 
是啊,看看delphi高手突破,上面的飛機類就是這樣設計的。
 
预警真的这么复杂吗?
要我说主要在数据库上下功夫就行了。
WarnType (
[sId] [varchar] ,
[sName] [varchar] ,
[iTime] [int] ,
[sNote] [varchar]
)
WarnDefine(
[sId] [varchar] ,
[sViewId] [varchar] ,
[sWhere] [varchar] ,
[sFilter] [varchar] ,
[sFieldDate] [varchar] ,
[iType] [int] ,
[sTitle] [varchar] ,
[sContain] [varchar] ,
[sServer] [varchar] ,
[sFunc] [varchar] ,
[sParam] [varchar] ,
[sKeyField] [varchar]
)
................................如此等等
程序只要做好衔接处理就行了。
 
楼主在谈设计,根帖主要谈实现
楼主是否感到吃力了^-^
 
基本思路:
定义工厂生产预警接口,定义你所说的想同的处理过程。
每种预警使用Package存储,实现上诉接口。
保存预警文件列表(bpl文件列表)到数据库或文本文件。
主程序在合适的时机使用LoadPackage载入预警包。
使用强制类型转换(转换为IProduceAlarm)调用相关接口方法。
定义接口
IProduceAlarm = interfase
public
procedure 检查数据;
procedure 产生预警;
procedure 保存相应预警并设置状态;
procedure 发送Email
end;

没用到设计模式,不知道是否合题。
 
to 张鸿林:
当然,每增加一种预警就要重新定义一个具体子类以实现相应的算法,我想这是很难避免的,至少不同的预警所取的资料不同,所对应数据表也是不同的(复杂!)。
在我看来最大的问题是将类别进行了硬编码,如字符串“MA”是指物料预警等,这样无论"MA"这个资料存于何处(数据库或是文本文件中)都可能会被不小心修改而导致预警不能正常进行!当然了,硬编码本身也不是一个非常好的设计!
to cnsandboy:
我基本上没用过package,用dll比较多,不过我想你的回答同楼上有些朋友的想法是大致相同的,更多的它只是实现的一种方法选择而已。最关键的是,无论如何,主程序总要决定来调用哪一个package(Dll),如何根据一类预警找到一个对应的package(Dll)
无论如何谢谢大家的关注!
 
----
在我看来最大的问题是将类别进行了硬编码,如字符串“MA”是指物料预警等,这样无论"MA"这个资料存于何处(数据库或是文本文件中)都可能会被不小心修改而导致预警不能正常进行!当然了,硬编码本身也不是一个非常好的设计!
----
既然要实现扩展,这种问题是避免不了的,除非是真的“硬”编码,所调用的所有子类名称都写到程序中,否则总是会有可能修改而不能调用的,包括IE或者Office的插件,如果dll名称被修改了一样无法正常调用。
如果这样说,是不是没有讨论的必要了呢?
 
cnsandboy的方法确实实现了自动工厂,我觉得,如果你对产生对象自动化要求高,这确实
是个不错的方法。模式中的抽象工厂,好象也没办法如此智能化
 
最关键的是,无论如何,主程序总要决定来调用哪一个package(Dll),如何根据一类预警找到一个对应的package(Dll)
==============
想了一下,确实也没有“自动”
最后我想,还是用抽象工厂吧
 
使用Bulder模式:即
将预警三个步骤抽象成三个对象;
再分别实现各个具体对象。
T检查数据=class
create();

proceduredo
;
end;

T产生预警=class
create();

proceduredo
;
end;

....
TAlarm = class(TObject)
public
T检查数据 :T1;
T产生预警 :T2;
T保存相应预警并设置状态: T3;
T发送Email :T4;

procedure bulder
end;

TAlarm.bulder;
begin
T1.do;
T2.do;
t3.do;
end;

扩展时,只要扩展或增加新的具体类,即具体步骤实现,则可。
 
随便写了点,不是很详细,只是说一下想法,仅供参考
IAlarm =interface
Execute;
end;
IAlarmManager =interface
get(index):IAlarm;
getcount:integer;
register(IAlarm)
unregister(IAlarm);
end;

定时触发时遍历IAlarmManager,调用每个alarm的execute;
实现IAlarm 时可以使templatemethod模式。实现一个抽象基类,不同的警报从基类派生,重新实现虚函数。
TAlarm=class(tobject,Ialarm)
protect
check;virtual
alarm;virtual
saveData;virtual;
SendMail;virtual;
Execute;
begin
if check then
begin
alarm;
savedata;
sendmail;
end;

end;

end;
 
后退
顶部