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 

Re: Advise right design please

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





PostPosted: Fri Oct 17, 2003 1:00 pm    Post subject: Re: Advise right design please Reply with quote



Hi!

I'm newbie to OOD, so if my question is too stupid or obscure, just let me
know.

How to rewright such procedural code of filling class properties of obejct
in OOD way:

pseudocode:

propedure TAWizard.AddProcedure(Object: TSomeClass);
begin
If Object.Property1 Is UnAssigned then
Object.Property1 := Dialog1.GetProperty1;
If Object.Property2 Is UnAssigned then
Object.Property2 := Dialog2.GetProperty2;
etc
ObjectCollection.Add(Object)
end

Thanks, Andrew


Back to top
Marc Rohloff
Guest





PostPosted: Fri Oct 17, 2003 1:34 pm    Post subject: Re: Advise right design please Reply with quote



Quote:
How to rewright such procedural code of filling class properties of obejct
in OOD way:

pseudocode:

propedure TAWizard.AddProcedure(Object: TSomeClass);
begin
If Object.Property1 Is UnAssigned then
Object.Property1 := Dialog1.GetProperty1;
If Object.Property2 Is UnAssigned then
Object.Property2 := Dialog2.GetProperty2;
etc
ObjectCollection.Add(Object)
end

Andrew,

Isee this is not the first time that you have posted this question. I
think if you tell us what you are trying to achieve you might get better
answers and a better solution.

For starters, you probably wouldn't want to display a bunch of dialogs to
the user but one single one.

Marc

Back to top
Andrew Gorda
Guest





PostPosted: Fri Oct 17, 2003 3:25 pm    Post subject: Re: Advise right design please Reply with quote



Hi!

First of all, Marc, thanks for the quick answer.

Quote:
Isee this is not the first time that you have posted this question. I
think if you tell us what you are trying to achieve you might get better
answers and a better solution.

You're right, Marc. English isn't my native, so it's rather difficult to
make my questions more clear.

The questions are:
1. If i have hierarchy of classes TBaseClass <-
TDerivedClass1<-TDerivedClass2 then do I have to provide the same hierarchy
for filling wizards TBaseClassWizard<-TDerivedClass1Wizard<-TDerivedWizard2?
2. And what's the common OOD design for such wizards at all?
3. Maybe I could use getters:

Function TTest.GetProperty1: SomeType;
begin
if FProperty1 Is Unassigned then
FProperty1 := Dialog1.GetProperty1;
Result := FProperty1
end
Quote:

For starters, you probably wouldn't want to display a bunch of dialogs to
the user but one single one.

Marc

We have legacy code written in procedural way with data-aware objects. Those
dialogs are also part of this legacy code and we can't modify it right now
'cause of our customer, I hope we'll do this step by step.

Now I'm trying ro rewrite it in OOD way, 'cause we have to constantly modify
code in order to add new features.

Thanks for your help,
Andrew Gorda, software developer



Back to top
Marc Rohloff
Guest





PostPosted: Fri Oct 17, 2003 4:21 pm    Post subject: Re: Advise right design please Reply with quote

Quote:
3. Maybe I could use getters:
This doesn't sound like a good idea.


Tell me
1) How do you decide if a property is unassigned or not?

2) Are these real properties or just fields? Are they (or can they be
made) published?

3) Where does ObjectCollection come from?

Marc

Back to top
Brad White
Guest





PostPosted: Fri Oct 17, 2003 7:14 pm    Post subject: Re: Advise right design please Reply with quote

Andrew,

This is definite progress.

I have a few thoughts.

"Andrew Gorda" <a_gorda (AT) yahoo (DOT) com> wrote

Quote:
The questions are:
1. If i have hierarchy of classes TBaseClass <-
TDerivedClass1<-TDerivedClass2 then do I have to provide the same
hierarchy
for filling wizards
TBaseClassWizard<-TDerivedClass1Wizard<-TDerivedWizard2?

That could work.

Quote:
2. And what's the common OOD design for such wizards at all?
Good question. The wizard should know about the object,

but the target object shouldn't know about the wizard.

Quote:
3. Maybe I could use getters:
Probably not.


Quote:

Function TTest.GetProperty1: SomeType;
Sorry, I don't see TTest in your heirarchy above, so

I can't tell what this does.

Quote:
begin
if FProperty1 Is Unassigned then
FProperty1 := Dialog1.GetProperty1;
Result := FProperty1
end

For starters, you probably wouldn't want to display a bunch of dialogs
to
the user but one single one.

Marc

We have legacy code written in procedural way with data-aware objects.
Those
dialogs are also part of this legacy code and we can't modify it right now
'cause of our customer, I hope we'll do this step by step.

Now I'm trying ro rewrite it in OOD way, 'cause we have to constantly
modify
code in order to add new features.

1) Get "Refactoring" by Martin Fowler.

I tried to do this without the book and had to get it half-way through.
2) Read 'Refactoring To Patterns' at
http://www.industriallogic.com/xp/refactoring/
3) Get a testing framework, like DUnit.
http://dunit.sourceforge.net/
4) If you have a lot of 'loose' procedures and data that
are not elements of an object or form, create a new object,
in that unit and move all the loose items into it.
5) Resolve all references to those methods and data.
6) Repeat for all units.

These are only interim objects.
You will know you are done with your conversion when
every object has one specific purpose and every method
in that object relates to that purpose.
Your new objects don't have any of that since they were
just thrown together by circumstance.

Now you need to decide on what some of your objects
will be. A good place to start is one object for each table.
With some, I have one object for a group of tables. Detail
tables are encapsulated. With others, I have one object for
a table and a series of child objects, one for each of the records.
It all depends on how the rest of the program is going to
interact with the data.
Pick an easy one to start with where you are going to have
one object for the table. Now you will encapsulate that
table in an object that the rest of the program can interact with.
Introducing the TClientDataSet.
You can download the demo project to see how it works.
http://codecentral.borland.com/codecentral/ccweb.exe/download?id=18306

8) In your datamodule, create a ClientDataSet and a
DataSetProvider for one of your tables or queries.
Connect the CDS to the Provider, the Provider to the
existing dataset. Then replace references to the original
table with references to the CDS.
Note that you don't set the underlying dataset to active.
You set the CDS to active and it handles getting data
and putting it back.
See Cary Jensen's series on CD for more details:
http://bdn.borland.com/soapbox/professionaldeveloper/
Now you have a placeholder for an object that will contain
your data and give you a lot of flexibility.

Now it is time to create that object.

9) Start a new unit. Create a CDS descendent.
You will use this to replace the temp.
10) Start a new project. This is your test project.
Create some simple tests for your new CDS.
11) If you want to drop the new client on the DM,
create a package for the new component.
12) Replace your temp CDS with your new CDS
descendent, either by dropping it on the form, or by
creating it in code.
13) Have the owner that creates it set the Provider,
either at design time or by calling SetProvider.

Now DA controls can be connected directly to the
CDS. But everything else should interact with the
object itself, not with individual fields of the object.

14) Create properties for each of the fields.
15) Move form routines that only operate on data, and don't
really have anything to do with the display, down into
the object.
16) Look for routines that have data envy. They spend
most of their effort on data that belongs to another object.
Move those into the proper object.

Good luck.
--
HTH,
Brad White



Back to top
Andrew Gorda
Guest





PostPosted: Wed Oct 22, 2003 3:19 pm    Post subject: Re: Advise right design please Reply with quote

Thanks Brad, for this complete refactoring guide and very useful link.

Andrew

"Brad White" <bwhite at inebraska.com> wrote

Quote:
Andrew,

This is definite progress.

I have a few thoughts.

"Andrew Gorda" <a_gorda (AT) yahoo (DOT) com> wrote in message
news:3f9009ab (AT) newsgroups (DOT) borland.com...
The questions are:
1. If i have hierarchy of classes TBaseClass <-
TDerivedClass1<-TDerivedClass2 then do I have to provide the same
hierarchy
for filling wizards
TBaseClassWizard<-TDerivedClass1Wizard<-TDerivedWizard2?
That could work.

2. And what's the common OOD design for such wizards at all?
Good question. The wizard should know about the object,
but the target object shouldn't know about the wizard.

3. Maybe I could use getters:
Probably not.


Function TTest.GetProperty1: SomeType;
Sorry, I don't see TTest in your heirarchy above, so
I can't tell what this does.

begin
if FProperty1 Is Unassigned then
FProperty1 := Dialog1.GetProperty1;
Result := FProperty1
end

For starters, you probably wouldn't want to display a bunch of dialogs
to
the user but one single one.

Marc

We have legacy code written in procedural way with data-aware objects.
Those
dialogs are also part of this legacy code and we can't modify it right
now
'cause of our customer, I hope we'll do this step by step.

Now I'm trying ro rewrite it in OOD way, 'cause we have to constantly
modify
code in order to add new features.

1) Get "Refactoring" by Martin Fowler.
I tried to do this without the book and had to get it half-way through.
2) Read 'Refactoring To Patterns' at
http://www.industriallogic.com/xp/refactoring/
3) Get a testing framework, like DUnit.
http://dunit.sourceforge.net/
4) If you have a lot of 'loose' procedures and data that
are not elements of an object or form, create a new object,
in that unit and move all the loose items into it.
5) Resolve all references to those methods and data.
6) Repeat for all units.

These are only interim objects.
You will know you are done with your conversion when
every object has one specific purpose and every method
in that object relates to that purpose.
Your new objects don't have any of that since they were
just thrown together by circumstance.

Now you need to decide on what some of your objects
will be. A good place to start is one object for each table.
With some, I have one object for a group of tables. Detail
tables are encapsulated. With others, I have one object for
a table and a series of child objects, one for each of the records.
It all depends on how the rest of the program is going to
interact with the data.
Pick an easy one to start with where you are going to have
one object for the table. Now you will encapsulate that
table in an object that the rest of the program can interact with.
Introducing the TClientDataSet.
You can download the demo project to see how it works.
http://codecentral.borland.com/codecentral/ccweb.exe/download?id=18306

8) In your datamodule, create a ClientDataSet and a
DataSetProvider for one of your tables or queries.
Connect the CDS to the Provider, the Provider to the
existing dataset. Then replace references to the original
table with references to the CDS.
Note that you don't set the underlying dataset to active.
You set the CDS to active and it handles getting data
and putting it back.
See Cary Jensen's series on CD for more details:
http://bdn.borland.com/soapbox/professionaldeveloper/
Now you have a placeholder for an object that will contain
your data and give you a lot of flexibility.

Now it is time to create that object.

9) Start a new unit. Create a CDS descendent.
You will use this to replace the temp.
10) Start a new project. This is your test project.
Create some simple tests for your new CDS.
11) If you want to drop the new client on the DM,
create a package for the new component.
12) Replace your temp CDS with your new CDS
descendent, either by dropping it on the form, or by
creating it in code.
13) Have the owner that creates it set the Provider,
either at design time or by calling SetProvider.

Now DA controls can be connected directly to the
CDS. But everything else should interact with the
object itself, not with individual fields of the object.

14) Create properties for each of the fields.
15) Move form routines that only operate on data, and don't
really have anything to do with the display, down into
the object.
16) Look for routines that have data envy. They spend
most of their effort on data that belongs to another object.
Move those into the proper object.

Good luck.
--
HTH,
Brad White





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.