<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:st1="urn:schemas-microsoft-com:office:smarttags" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 11 (filtered medium)">
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]--><o:SmartTagType
namespaceuri="urn:schemas-microsoft-com:office:smarttags" name="place"/>
<o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
name="PersonName"/>
<!--[if !mso]>
<style>
st1\:*{behavior:url(#default#ieooui) }
</style>
<![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
        {font-family:SimSun;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:"\@SimSun";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman";}
a:link, span.MsoHyperlink
        {color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {color:purple;
        text-decoration:underline;}
p
        {mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:12.0pt;
        font-family:"Times New Roman";}
span.EmailStyle17
        {mso-style-type:personal;
        font-family:Arial;
        color:windowtext;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:Arial;
        color:navy;}
@page Section1
        {size:612.0pt 792.0pt;
        margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body bgcolor=white lang=EN-US link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Thank.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Point 1/ Fair enough<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Point 2/ correct . I had written that bit
early on before I realized I could break it down correctly with TMethdo.code
and TMethod.Data and I haven’t fully refactored it yet. I’ve
removed it now.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Point 3/ Because you cant do anything with
a bunch of procedures. Ie it is not portable. Class functions can be
overridden. You don’t need to use TNotifier.AddListener,<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'> You could have for example add a
meta class and a classvariable to the global, Var NotifierClass:TNotiferClass =
TNotifer. I then use this for accessing the functions and down the track in
some cases or applications you may wish to modify how it works, without
effecting All the other apps by simply changing the class pointer. static procedures
do not lend themselves to upgrading software without breaking old software and
this is one of the most powerful uses of static classes as libraries that many
people in <st1:place w:st="on">Delphi</st1:place> don’t take advantage of.
<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Point 4. I use constants, so I don’t
have typos in message names (except for demos). And I use SameText, so they are
not case-sensitve. I do this purely because I prefer debugging meaningful
strings rather than integers. It also makes It easier when dealing with storage
of types etc in human readable XML. So that’s why I do it. Many books use
integers. I just don’t like it. Also. A lot of my infrastructor permits
streaming of the entire message, and the data object over TCP as part of the
notification. I prefer unknown apps receiving this to get a meaningful ‘CLIENT_OBJECT_UPDATED’
rather than 3 ;)<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>The StringList is indexed, and its very
fast, I’ve tested with thousands of binds with no real time effect. The
work done by listeners is the time issue. Not the lookup.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>I used to have an observer and observed
class system too. And it was really annoying when you had to make changes. I
even wrote a plugin for the IDE to convert an object into a listener etc by
inserting all the code for me. So that took the hassle out. But I prefer the
decoupled method. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'>Thanks for the feedback. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 color=navy face=Arial><span style='font-size:
10.0pt;font-family:Arial;color:navy'><o:p> </o:p></span></font></p>
<div>
<div class=MsoNormal align=center style='text-align:center'><font size=3
face="Times New Roman"><span style='font-size:12.0pt'>
<hr size=2 width="100%" align=center tabindex=-1>
</span></font></div>
<p class=MsoNormal><b><font size=2 face=Tahoma><span style='font-size:10.0pt;
font-family:Tahoma;font-weight:bold'>From:</span></font></b><font size=2
face=Tahoma><span style='font-size:10.0pt;font-family:Tahoma'>
delphi-bounces@ns3.123.co.nz [mailto:delphi-bounces@ns3.123.co.nz] <b><span
style='font-weight:bold'>On Behalf Of </span></b>Todd Martin<br>
<b><span style='font-weight:bold'>Sent:</span></b> Monday, 15 May 2006 10:38
a.m.<br>
<b><span style='font-weight:bold'>To:</span></b> <st1:PersonName w:st="on">NZ
Borland Developers Group - <st1:place w:st="on">Delphi</st1:place> List</st1:PersonName><br>
<b><span style='font-weight:bold'>Subject:</span></b> Re: [DUG] Discussion
& Donation</span></font><o:p></o:p></p>
</div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'><o:p> </o:p></span></font></p>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Well you said you wanted feedback, so I hope this isn't too
picky.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>1) I find the inconsistent use of variable prefixes a bit
annoying. I tend to stick with</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>F- class field</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>A - method parameter</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>P - pointer</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>and no prefixes for class properties or local variables.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>2) TListenerItem.FListener is redundant, since the
information it contains is already held in TListenerItem.FBindMethod</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>It could have been implemented as a function, but I don't
see why it is needed.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>As usual, redundancy leads to complication elsewhere</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>eg. if (MethodEquals(TMethod(Items[i].FBindMethod)
,TMethod(ABinder))) and (Items[i].FListener = AListener) then</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>the second condition is automatically satisfied by the
first condition.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>3) Why define a TNotifier class when all its methods are
static? They could be defined as simple procedures/functions in the unit.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>4) I'm not keen on the idea of passing a string parameter to
identify the message type, for the simple reason that spelling mistakes can
arise and you're never really sure at compile time what
"messages" are being broadcast/handled. This problem can of
course be ameliorated through the use of constants, but I prefer the use of an
enumerated type.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Having said all that. I like the loose coupling of your
solution. I have implemented the observer pattern previously with the lists
maintained internally by the objects involved, so removing the need to inherit
from a particular class is a great improvement. I hadn't considered that option
before. Of course you do pay a miniscule performance penalty in having to find
the correct list for the object. Perhaps the use of THashedstringlist
could mitigate this further.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Todd.</span></font><o:p></o:p></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'> <o:p></o:p></span></font></p>
</div>
<blockquote style='border:none;border-left:solid black 1.5pt;padding:0cm 0cm 0cm 4.0pt;
margin-left:3.75pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt'>
<div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>----- Original Message ----- <o:p></o:p></span></font></p>
</div>
<div style='font-color:black'>
<p class=MsoNormal style='background:#E4E4E4'><b><font size=2 face=Arial><span
style='font-size:10.0pt;font-family:Arial;font-weight:bold'>From:</span></font></b><font
size=2 face=Arial><span style='font-size:10.0pt;font-family:Arial'> <a
href="mailto:kyley@harrissoftware.com" title="kyley@harrissoftware.com">Kyley
Harris</a> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><b><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial;font-weight:bold'>To:</span></font></b><font size=2
face=Arial><span style='font-size:10.0pt;font-family:Arial'> <a
href="mailto:delphi@ns3.123.co.nz" title="delphi@ns3.123.co.nz">NZ Borland
Developers Group - Delphi List</a> <o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><b><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial;font-weight:bold'>Sent:</span></font></b><font size=2
face=Arial><span style='font-size:10.0pt;font-family:Arial'> Wednesday, May 10,
2006 3:36 PM<o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><b><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial;font-weight:bold'>Subject:</span></font></b><font size=2
face=Arial><span style='font-size:10.0pt;font-family:Arial'> [DUG] Discussion
& Donation<o:p></o:p></span></font></p>
</div>
<div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'><o:p> </o:p></span></font></p>
</div>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>In an attempt to create some more interesting discussion,
other than talking about the crud IDE issues, I am donating some useful code
for discussion, rather than for help. Feel free to keep/use the code if you
want to. Be mean if you feel the need (but if your personal then watch out ;) Hopefully
this may introduce a discussion where people learn something, or are able to
contribute some interesting ideas/information about the topic (which is object
notification and observation).<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>In the attached zip is a sample application showing a basic,
but horrible use of the class in uNotifier.pas. TNotifer is a class I wrote a
long while back which loosely follows an observer pattern for allowing
one-to-many observations between an object, and a bunch of interested object. <o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>The main difference this class has between many observer
patterns is that you do not have to modify existing classes, or sub-class
anything, or instantiate anything in your existing objects. The TNotifier
handles all the bindings, you just need to implement one listening event on each
listening object.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>The sample app is a corny app that makes child forms (button
click) update a memo based on changes to the memo on the main form. God help me
if I ever did anything as potentially unthread safe as that in a real app.<o:p></o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'><o:p> </o:p></span></font></p>
<p class=MsoNormal><font size=2 face=Arial><span style='font-size:10.0pt;
font-family:Arial'>Fun fun fun…. (I hope the app compiles. You never know
with these tricky little sample apps)<o:p></o:p></span></font></p>
<div class=MsoNormal align=center style='text-align:center'><font size=3
face="Times New Roman"><span style='font-size:12.0pt'>
<hr size=2 width="100%" align=center>
</span></font></div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'>_______________________________________________<br>
<st1:place w:st="on">Delphi</st1:place> mailing list<br>
Delphi@ns3.123.co.nz<br>
http://ns3.123.co.nz/mailman/listinfo/delphi<o:p></o:p></span></font></p>
<div class=MsoNormal align=center style='text-align:center'><font size=3
face="Times New Roman"><span style='font-size:12.0pt'>
<hr size=2 width="100%" align=center>
</span></font></div>
<p class=MsoNormal><font size=3 face="Times New Roman"><span style='font-size:
12.0pt'>Internal Virus Database is out-of-date.<br>
Checked by AVG Free Edition.<br>
Version: 7.1.385 / Virus Database: 268.5.1/327 - Release Date: 28/04/2006<o:p></o:p></span></font></p>
</blockquote>
</div>
</body>
</html>