BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Component Design
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
Chris Trueman
Guest





PostPosted: Tue Jan 04, 2005 9:54 pm    Post subject: Component Design Reply with quote



I've built a component that essentially manages a list of objects. In this
case I chose to return a new object each time an item in the list was
retrieved as in:

property Item[ix: Integer]: TService read GetItem;

function TServiceList.GetItem(ix: Integer): TService;
var
s: PEnumServiceStatus;
begin
if (ix < 0) or (ix >= FCount) then
Result := nil
else
begin
{ FItems is just a block of memory containing records }
s := FItems;

while ix > 0 do
begin
Inc(s);
Dec(ix);
end;

{ Calls a private constructor that picks apart the record }
Result := TService.Create(s);
end;
end;

This feels like a design that runs contrary to most list management
components I've seen. Thoughts?



Chris.
Back to top
Peter Morris [Air Softwar
Guest





PostPosted: Tue Jan 04, 2005 10:12 pm    Post subject: Re: Component Design Reply with quote



Quote:
This feels like a design that runs contrary to most list management
components I've seen. Thoughts?

If you were lazy-creating the item and keeping the reference in a list to
pass back the next time it was requested then I wouldn't have an objection,
but that is not what you are doing.

One of my golden-never-break rules is to *never* return a new object from a
function, if you do you are at high risk of introducing memory leaks, for
example.

if list.item[0] <> nil then list.item[0].Caption := 'Hello';

You have just created two different objects, neither of which have been
freed.


--
Pete
====
Audio compression components, DIB graphics controls, FastStrings
http://www.droopyeyes.com

Read or write articles on just about anything
http://www.HowToDoThings.com

My blog
http://blogs.slcdug.org/petermorris/




Back to top
Chris Trueman
Guest





PostPosted: Tue Jan 04, 2005 10:21 pm    Post subject: Re: Component Design Reply with quote



Quote:
if list.item[0] <> nil then list.item[0].Caption := 'Hello';

This is a good observation. Since the TServicesManager.Services also
returns a new object each time - code like:

for iii := 0 to svrMgr.Services.Count - 1 do
if svrMgr.Services[iii].ServiceName = 'blah blah'

presumbely creates the list object Count + 1 times.

Thanks for the comments.



Chris.

Back to top
Bryan Crotaz
Guest





PostPosted: Wed Jan 05, 2005 12:47 pm    Post subject: Re: Component Design Reply with quote

Quote:
One of my golden-never-break rules is to *never* return a new object from
a
function, if you do you are at high risk of introducing memory leaks, for
example.

Actually it's fine, as long as your method is named well

Eg CreateItem: TItem or NewItem: TItem.

Bryan



Back to top
Jim Cooper
Guest





PostPosted: Wed Jan 05, 2005 2:56 pm    Post subject: Re: Component Design Reply with quote


Quote:
One of my golden-never-break rules is to *never* return a new object from a
function

How do you do factory patterns then? :-)

Cheers,
Jim Cooper

_______________________________________________

Jim Cooper [email]jim (AT) falafelsoft (DOT) com[/email]
Falafel Software http://www.falafelsoft.com
_______________________________________________

Back to top
Bob Dawson
Guest





PostPosted: Wed Jan 05, 2005 3:07 pm    Post subject: Re: Component Design Reply with quote

"Jim Cooper" wrote
Quote:

How do you do factory patterns then? Smile

I'm also a bit more relaxed about this, and try to mitigate things via
coding conventions: factory classes are always called T<~>Factory, and other
classes the have object-returning functions tend to name those functions
Create<~> or Provide<~> rather than just Get<~>. This tells the programmer
that the function assumes no responsibily for the provided object, whereas
the result of an Item[x] or GetItem(x) call can safely be walked away from.

bobD



Back to top
Derek Davidson
Guest





PostPosted: Wed Jan 05, 2005 3:27 pm    Post subject: Re: Component Design Reply with quote

Peter Morris [Air Software Ltd] wrote:

Quote:
One of my golden-never-break rules is to never return a new object
from a function

Whoa! That's a severe, self-imposed limitation there.

If everyone followed the rule, here are a few places where significant
re-writes would have to occur:

1. The VCL
2. The FCL
3. Refactoring - Improving the Design of Existing Code
4. Design Patterns

I think, on balance, I'll keep the option open <g>

--
Derek Davidson
http://www.ebsms.com
Send SMS Text messages from your PC. For FREE!

Back to top
Charles McAllister
Guest





PostPosted: Wed Jan 05, 2005 3:34 pm    Post subject: Re: Component Design Reply with quote

Peter Morris [Air Software Ltd] wrote:
Quote:
One of my golden-never-break rules is to *never* return a new object from a
function, if you do you are at high risk of introducing memory leaks, for
example.

if list.item[0] <> nil then list.item[0].Caption := 'Hello';

You have just created two different objects, neither of which have been
freed.

How about just following a naming convention, e.g. CreateItem? or DoCreateItem (looks less like a

constructor call).

if i saw...

if list.CreateItem[0] <> nil then
list.CreateItem[0].Caption := 'Hello';

....be easier to see the red flag

i also follow a naming convention of TryCreateXXX for cases where a function might return nil if
object could not be created.

Back to top
Peter Morris [Air Softwar
Guest





PostPosted: Wed Jan 05, 2005 5:37 pm    Post subject: Re: Component Design Reply with quote

Quote:
Actually it's fine, as long as your method is named well

Eg CreateItem: TItem or NewItem: TItem.

I'd prefer

procedure TMyClass.CreateItem(var NewItem: TItem);

That way it is 100% impossible to cause this problem.



Back to top
Peter Morris [Air Softwar
Guest





PostPosted: Wed Jan 05, 2005 5:44 pm    Post subject: Re: Component Design Reply with quote

Quote:
How do you do factory patterns then? Smile

I always create a procedure with a "var" parameter, like so

............CreateWhatever(var Result: TWhatever)

This way it is enforced that there must be a variable to hold the instance
reference. The only time I would have a function returning a new object is
when there is a parent object which holds a reference to it automatically,
such as

Person.Children.AddNew


--
Pete
====
Audio compression components, DIB graphics controls, FastStrings
http://www.droopyeyes.com

Read or write articles on just about anything
http://www.HowToDoThings.com

My blog
http://blogs.slcdug.org/petermorris/



Back to top
Joanna Carter (TeamB)
Guest





PostPosted: Wed Jan 05, 2005 5:54 pm    Post subject: Re: Component Design Reply with quote

"Peter Morris [Air Software Ltd]"
<peter.morris (AT) remove (DOT) this.airsoftware.co.uk> a écrit dans le message de
news: 41dc2786$1 (AT) newsgroups (DOT) borland.com...

Quote:
I always create a procedure with a "var" parameter, like so

...........CreateWhatever(var Result: TWhatever)

This way it is enforced that there must be a variable to hold the instance
reference. The only time I would have a function returning a new object
is
when there is a parent object which holds a reference to it automatically,
such as

In that case, you might like to consider using the 'out' modifier as this
guarantees that you get nil if it fails, rather than accidentally passing in
a valid object and getting the same object back instead of a replacement ??

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker



Back to top
Bryan Crotaz
Guest





PostPosted: Wed Jan 05, 2005 5:55 pm    Post subject: Re: Component Design Reply with quote


"Peter Morris [Air Software Ltd]"
<peter.morris (AT) remove (DOT) this.airsoftware.co.uk> wrote

Quote:
Actually it's fine, as long as your method is named well

Eg CreateItem: TItem or NewItem: TItem.

I'd prefer

procedure TMyClass.CreateItem(var NewItem: TItem);

That way it is 100% impossible to cause this problem.

That's horrible to use though.

I do a lot of this:

ProcessHandler.Create(MyObject.CreateClone);
or MyProcess.DataObject := MyObject.CreateClone;

The Process owns the object, so all is hunkydory.

Bryan



Back to top
Derek Davidson
Guest





PostPosted: Wed Jan 05, 2005 6:13 pm    Post subject: Re: Component Design Reply with quote

Chris Trueman wrote:

Quote:
In this
case I chose to return a new object each time an item in the list was
retrieved as in:

In the first case, I'm assuming that you're using Delphi (Win32) as
this is a 'freeing the memory' issue and with .NET you get GC (and
hence no issue)

If you have control over the objects that you return how about
returning an object that implements interfaces and thus get the objects
reference counted and freed automatically?

--
Derek Davidson
http://www.ebsms.com
Send SMS Text messages from your PC. For FREE!

Back to top
Bob Dawson
Guest





PostPosted: Wed Jan 05, 2005 6:17 pm    Post subject: Re: Component Design Reply with quote

"Bryan Crotaz" wrote
Quote:

ProcessHandler.Create(MyObject.CreateClone);

hmmm--rather the opposite of Peter's original case (you're passing an
unreferenced new object to a function rather than out of one). If
ProcessHandler.Create fails, what happens to MyObject?

Rather than
IntendedOwner.AddItem(TSomeObject.Create);
-- what happens if the AddItem fails?

I tend to do things like

var
sobj : TSomeObject;
begin
sobj := TSomeObject.Create;
try
IntendedOwner.AddItem(sobj);
except
sobj.Free;
raise;
end;

bobD



Back to top
Jim Cooper
Guest





PostPosted: Wed Jan 05, 2005 6:32 pm    Post subject: Re: Component Design Reply with quote



Quote:
I always create a procedure with a "var" parameter, like so

I find that a bit of an issue with factories, since you cannot have
allocated Result yet. Dealing with failure gets a bit ugly. (I'm also
not keen on Result as a parameter name Smile, but that's a spearate problem)

Cheers,
Jim Cooper

_______________________________________________

Jim Cooper [email]jim (AT) falafelsoft (DOT) com[/email]
Falafel Software http://www.falafelsoft.com
_______________________________________________

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.