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 

object 'reparenting' best practices

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi OO design
View previous topic :: View next topic  
Author Message
Lee_Nover
Guest





PostPosted: Mon Feb 21, 2005 8:54 am    Post subject: object 'reparenting' best practices Reply with quote



a Product can be in one Group
a Group has a list of Products
the Product's group can be changed

Q: who should handle this change ?
a) the product removes itself from the previous group and adds itself to
the new group
(OldGroup.RemoveProduct(Self); NewGroup.AddProduct(Self);
b) have the Product.Group property read-only and move the object from one
group to another manually

I like the first method better but would like other's opinions
Back to top
Joanna Carter (TeamB)
Guest





PostPosted: Mon Feb 21, 2005 10:00 am    Post subject: Re: object 'reparenting' best practices Reply with quote



"Lee_Nover" <Lee_Nover[nospam]@delphi-si.com> a écrit dans le message de
news: [email]opsmjho7gcignj8p (AT) istvangx270 (DOT) vasco.si[/email]...

a Product can be in one Group
a Group has a list of Products
the Product's group can be changed

Q: who should handle this change ?
a) the product removes itself from the previous group and adds itself to
the new group
(OldGroup.RemoveProduct(Self); NewGroup.AddProduct(Self);
b) have the Product.Group property read-only and move the object from one
group to another manually

Hi Lee

Let me start by asking you a question :-)

Is it a responsibility of the Product to know which Group it belongs to ?

If not, then you should not put any reference to the Group in the Product.

In situations like this, you have to ask yourself what would happen in real
life. Would a Product really have any responsibilities outside of itself?
Would a Group really have any behaviour or is it just a sophisticated enum
or value?

I get the feeling that you should have a Product Catalogue (manager) that is
responsible for the 'doing' of actions on the Products and/or Groups.
Assuming you only have one product range per program execution, then this
can be a Singleton class that can be called from anywhere in code.

Assuming that the Product does not need to know about its Group :

ProductManager
function GetProductsForGroup(aGroup: Group): ProductList;
function GetGroupForProduct; Group;
function GetGroupList: GroupList;
procedure AddProductToGroup(aProduct: Product; aGroup: Group);
procedure RemoveProductFromGroup(aProduct: Product);
procedure MoveProductToGroup(aProduict: Product; newGroup: Group);
...
end;

The AddProductToGroup method would, of course call Group.AddProduct; whilst
the MoveProductToGroup would use GetGroupForProduct, RemoveProductFromGroup
and AddProductToGroup.

Now you have a 'library' of methods that can manipulate Products and Groups
as well as providing a set of operations that can be re-used without
altering the internals of either the Product or Group classes.

Of course, the above methods will only work if a Product can only belong to
one Group, but there is no reason why such a manager should not be able to
cope with many-to-many relationships, but that would also mean maintaining a
GroupMembership association class that describes the link between the
Product and Group classes

Joanna

--
Joanna Carter (TeamB)

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


Back to top
Lee_Nover
Guest





PostPosted: Mon Feb 21, 2005 11:09 am    Post subject: Re: object 'reparenting' best practices Reply with quote



Quote:
Is it a responsibility of the Product to know which Group it belongs to ?
I believe so

a bit more background:
in the editor form for a Product I need to be able to select which group
it belongs to (combobox - just a few groups)
and it's a Product.(0..1)Group relation
for now my Group object doesn't have a Products list property
setting Product.Group instead of (suggestion a)) add/remove itself from
the list.. it adds/removes itself from the subject list
the list form displaying Products also shows the linked Group's name
(that's why the Observer)

so in this case is it still ok or should I change it


Quote:
In situations like this, you have to ask yourself what would happen in
real
life. Would a Product really have any responsibilities outside of itself?
not really Smile



Quote:
Would a Group really have any behaviour or is it just a sophisticated
enum or value?
something like that yes (at least for now)

as I see it this will stay like it is
if I need to display some kind of hieararchy like Group.ProductList I can
still create a manager like you mentioned


Quote:
I get the feeling that you should have a Product Catalogue (manager)
I did think of that but didn't find it necessary for Product<>Group

but will (have to) use this approach for some other BOs

about this second case that will need this Manager approach

it's a list of Payments .. a Payment document can have 1..* Payments
Payment has a property Document: string
so this catalogue should return a list of Payments for a particular
Document
- GetPayments(Document: string): PaymentList

should it maintain an internal list for each document or find them when
asked for
going for internal lists for performance sake :)

tnx :)

Back to top
Joanna Carter (TeamB)
Guest





PostPosted: Mon Feb 21, 2005 11:24 am    Post subject: Re: object 'reparenting' best practices Reply with quote

"Lee_Nover" <Lee_Nover[nospam]@delphi-si.com> a écrit dans le message de
news: [email]opsmjnx6qcignj8p (AT) istvangx270 (DOT) vasco.si[/email]...

Quote:
Is it a responsibility of the Product to know which Group it belongs to
?

I believe so
a bit more background:
in the editor form for a Product I need to be able to select which group
it belongs to (combobox - just a few groups)
and it's a Product.(0..1)Group relation
for now my Group object doesn't have a Products list property
setting Product.Group instead of (suggestion a)) add/remove itself from
the list.. it adds/removes itself from the subject list
the list form displaying Products also shows the linked Group's name
(that's why the Observer)

so in this case is it still ok or should I change it

You are confusing what is happening in a form with what is happening in a
BO. Forms very often don't map one-one to a storable BO like Product or
Group, but they can map onto a 'manager' class.

Quote:
I get the feeling that you should have a Product Catalogue (manager)

I did think of that but didn't find it necessary for Product<>Group
but will (have to) use this approach for some other BOs

If the only reason you are including the Group in the Product is because of
the desired UI behaviour, then you need to revise your design.

Quote:
it's a list of Payments .. a Payment document can have 1..* Payments
Payment has a property Document: string

If you can have more than one Payment per Document and a Payment can be for
more than one Document, then you need an association class to handle that
relationship.

Quote:
so this catalogue should return a list of Payments for a particular
Document
- GetPayments(Document: string): PaymentList

Yes, but you would not pass in a string for the Document, you would pass in
the Document itself.

Quote:
should it maintain an internal list for each document or find them when
asked for
going for internal lists for performance sake Smile

Most modern databases are fast enough to retrieve lists on demand, unless
the query becomes very complex; in which case you could cache small result
sets to save time.

Joanna

--
Joanna Carter (TeamB)

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



Back to top
Lee_Nover
Guest





PostPosted: Mon Feb 21, 2005 12:04 pm    Post subject: Re: object 'reparenting' best practices Reply with quote

Quote:
You are confusing what is happening in a form with what is happening in
a BO
that's why these questions Very Happy


Quote:
Forms very often don't map one-one to a storable BO like Product or
Group, but they can map onto a 'manager' class.
but in this case where the Group is like a simple enum .. should be ok to

leave it as it is right ? :)


Quote:
If you can have more than one Payment per Document and a Payment can be
for more than one Document, then you need an association class to handle
that
relationship.
I know .. but one Payment can only be on one Document


Quote:
Yes, but you would not pass in a string for the Document, you would pass
in the Document itself.
but .. there's no document object .. you can think of it as a grouping

criterion Smile
should I instead create Document objects that hold these Payments ?
at loading time I'd have to sort those payments into documents
would be faster .. seems best this way :)

Quote:
Most modern databases are fast enough to retrieve lists on demand, unless
DB's yes .. but this is on the client .. I get these objects from a

webservice so some caching is necessary

cheers

Back to top
Joanna Carter (TeamB)
Guest





PostPosted: Mon Feb 21, 2005 1:15 pm    Post subject: Re: object 'reparenting' best practices Reply with quote

"Lee_Nover" <Lee_Nover[nospam]@delphi-si.com> a écrit dans le message de
news: [email]opsmjqg2drignj8p (AT) istvangx270 (DOT) vasco.si[/email]...

Quote:
Forms very often don't map one-one to a storable BO like Product or
Group, but they can map onto a 'manager' class.

but in this case where the Group is like a simple enum .. should be ok to
leave it as it is right ? Smile

So are you saying that you don't want to have any more information kept in a
Group apart from its enumerated value ? Surely, restricting your Groups to
an enum will mean that you cannot add/remove Groups without modifying your
code ? By using a separate entity for Group, you can then ensure that when
you remove a Group, all Products that belong to that Group are updated to
either be unallocated or changed to another Group. Also things like a Name
property could be very useful when displaying a list of Grouops to choose
from.

Quote:
If you can have more than one Payment per Document and a Payment can be
for more than one Document, then you need an association class to handle
that relationship.

I know .. but one Payment can only be on one Document

In that case, you don't need an association class as you can simply add a
Document property to your Payment class.

Quote:
Yes, but you would not pass in a string for the Document, you would pass
in the Document itself.

but .. there's no document object .. you can think of it as a grouping
criterion Smile

So you don't need any more information about a Document apart from an
enumerated value?? This does not sound like a very OO system.... yet :-)

Quote:
should I instead create Document objects that hold these Payments ?
at loading time I'd have to sort those payments into documents
would be faster .. seems best this way Smile

If a Payment knows which Document it is for, does a Document really have to
know about all the Payments made against it ? Or is this a candidate for a
'manager'? I am not saying which way is right, just causing you to think
very carefully about the responsibilities involved before jumping to a
conclusion.

Quote:
DB's yes .. but this is on the client .. I get these objects from a
webservice so some caching is necessary

Designing an OO web service usually involves HTML being created on the
server and then being dispatched in response to a request. If that is the
case, then it really doesn't matter because the objects can be created on
the same server as the database. After all, it is the objects that are being
streamed as html.

Joanna

--
Joanna Carter (TeamB)

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




Back to top
Lee_Nover
Guest





PostPosted: Mon Feb 21, 2005 2:12 pm    Post subject: Re: object 'reparenting' best practices Reply with quote

Quote:
So are you saying that you don't want to have any more information kept
in a
Group apart from its enumerated value ? Surely, restricting your Groups
to
an enum will mean that you cannot add/remove Groups without modifying
your code ?
it has an ID and a Name ofcourse Smile


Quote:
you remove a Group, all Products that belong to that Group are updatedto
that's actually forbidden (removing objects that have 1+ references)


Quote:
In that case, you don't need an association class as you can simply add a
Document property to your Payment class.
it has it .. and it's a string


Quote:
So you don't need any more information about a Document apart from an
enumerated value?? This does not sound like a very OO system.... yet Smile
Document is just a string that groups several Payments together

I can change it to a class

Quote:
If a Payment knows which Document it is for, does a Document really have
to
know about all the Payments made against it ? Or is this a candidate for
a
'manager'? I am not saying which way is right, just causing you to think
very carefully about the responsibilities involved before jumping to a
conclusion.
there's a candidate for a manager .. that's why I mentioned it

Payment, Document, PaymentManager
this is purely a presentation issue .. no business logic to it
I think I'm gonna go for the manager
smtn like your earlier example for the ProductManager where the Document
will be a PaymentList


Quote:
Designing an OO web service usually involves HTML being created on the
server and then being dispatched in response to a request. If that is the
case, then it really doesn't matter because the objects can be createdon
the same server as the database. After all, it is the objects that are
being
streamed as html.
yes but I wouldn't want to retrieve the objects each time I call

DocumentManager.GetDocument :)

lots of input .. need to process now :D

Back to top
Joanna Carter (TeamB)
Guest





PostPosted: Mon Feb 21, 2005 3:59 pm    Post subject: Re: object 'reparenting' best practices Reply with quote

"Lee_Nover" <Lee_Nover[nospam]@delphi-si.com> a écrit dans le message de
news: [email]opsmjwepzzignj8p (AT) istvangx270 (DOT) vasco.si[/email]...

Quote:
it has an ID and a Name ofcourse Smile

In which case it is a class and not an enum.

Quote:
that's actually forbidden (removing objects that have 1+ references)

So, in which class do you write the logic that enforces this rule ?

Document is just a string that groups several Payments together
I can change it to a class

I certainly would change it, to allow for future changes.

Quote:
there's a candidate for a manager .. that's why I mentioned it
Payment, Document, PaymentManager
this is purely a presentation issue .. no business logic to it

But there is logic to it; you just said there was a rule that prohibited the
removal of an object with 1+ references. Where do you put that code ?

Quote:
I think I'm gonna go for the manager
smtn like your earlier example for the ProductManager where the Document
will be a PaymentList

If, as you said, the Document is 'just a string' then it can't be a Payment
List. The Document would have to be a class that possibly possesses a
Payment List, but that would then involve declaring both classes in the same
unit to avoid circular references problems. That, in turn, ties the Document
and Payment classes inextricably together.

If a Payment is for one Document only, then it is best to put a Document
property in the Payment class, but don't try to do the reverse as well;
possibly you could use a Ledger class whose responsibility is to hold a list
of Payments made and therefore can be have a method that returns all
Payments, given a Document parameter.

Quote:
yes but I wouldn't want to retrieve the objects each time I call
DocumentManager.GetDocument Smile

Why not? This kind of Query takes milliseconds.

Joanna

--
Joanna Carter (TeamB)

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



Back to top
Lee_Nover
Guest





PostPosted: Mon Feb 21, 2005 6:21 pm    Post subject: Re: object 'reparenting' best practices Reply with quote

Quote:
So, in which class do you write the logic that enforces this rule ?
in the base: TOsnova .. it checks ReferenceCount (which is not FRefCount)


Quote:
I certainly would change it, to allow for future changes.
and I will too Smile


Quote:
But there is logic to it; you just said there was a rule that prohibited the
removal of an object with 1+ references. Where do you put that code ?
Document won't be a storable object


Quote:
If a Payment is for one Document only, then it is best to put a Document
property in the Payment class, but don't try to do the reverse as well;
possibly you could use a Ledger class whose responsibility is to hold a list
of Payments made and therefore can be have a method that returns all
Payments, given a Document parameter.
exactly ! Smile


Quote:
yes but I wouldn't want to retrieve the objects each time I call
DocumentManager.GetDocument Smile
Why not? This kind of Query takes milliseconds.
again it does on the server .. but not from the client

this would mean: client.RPC > server.fetchdata + create objects > send back to client + client remap objects :)

I think I've cleared my head a bit and will have a straight picture onceI sleep over it Smile
tnx !

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

 
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.