Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Understanding question - duplicated logic

3 views
Skip to first unread message

M.Pannier

unread,
Jul 23, 2008, 8:07:14 AM7/23/08
to
Hello,

I have some questions about OO and some patterns. First I will describe the
"problem" to solve with my application. Than I describe the way I solved
this in the past. My question lays in "future" of developing OO.

1.)
I have a simple database with a table called

"partslist"
- ID
- partnr (string[50])
- single_price (Currency)
- amount (Integer)
- ...

I have to write an application to show and edit the partslist.

2.)
If I started developing (with Delphi) I created a Form which contains data
sensitive controls and a DataModul which contains a Database and a Query or
Dataset. I linked the two components together and everything was fine. The
DataSet creates Dataset-Fields who get the "rules" from Database (not null
fields, the datatype and so on). The controls get the rules from the
Dataset. The user of the software did not have a chance to input a character
in the fields amount or single_price. I also have a calculated field "price"
which automatically calculated the whole price of single_price * amount.

3.)
In the last time I read a lot of application tiers and separation of data,
model and gui. I've startet with an example of MVC and domain model for my
problem described under 1.) (database, data access, some objects - domain
modell - and a gui - Win32 Form)

I use the same database like in 1.)
I use a DataModul for dataccess.
I use a class called TPart and a list called TPartList.
I write some code to read data from the database and writing to database
(using a DataMapper).
I create a Form and a controller with the functions ReadFromModel and
WriteToModel. This functions take the data from the model and write it to
the gui or take the data from the gui and write it back to the model.

Now my questions to this scenario:

a.)
I think there is a lot of duplicated logic. The database has triggers,
foreign keys, datatypes and a lot of other informatioen (not null...).
The created class must "copy" this logic. The property partnr must be at
least 50 character and must have a value...
The Form/Controls must "copy" logic, too. EditPartNr must have MaxLength =
50, EditSingle_Price is only for numeric values ...
Is this right or is there a mistake in my considerations?

b.)
who does the calulation? I know that my class TPart can have a read only
property "price" with a get method. But who does the actualization if
the user changes something in the "amount_edit"? Must I assign onChange of
the edit and write the new amount to the model, the model does the
calculation and have a OnChangeAmount event?

c.)
Is there a good real life example for download which contains many pattern?
I'm reading the book from M. Fowler and I have looked to
the Microsoft "Adventure works Cinema" example application. Everything is
fine and the main concept is clear, but the details...


I know/realized, that I don't need "large pattern" and a domain model for
this kind of simple application, but I would use this
simple app for learning and understanding. I also know that an object is
more powerfull, performant and flexible than a Dataset, but as a "normal old
Delphi database programmer" it is a big changeover.


I hope it is not too hard while reading my text and there is someone who can
help me.
Regards

M.Pannier

Andreas Dorn

unread,
Jul 23, 2008, 5:00:02 PM7/23/08
to
M.Pannier wrote:
> Now my questions to this scenario:
>
> a.)
> I think there is a lot of duplicated logic. The database has triggers,
> foreign keys, datatypes and a lot of other informatioen (not null...).
> The created class must "copy" this logic. The property partnr must be at
> least 50 character and must have a value...
> The Form/Controls must "copy" logic, too. EditPartNr must have MaxLength =
> 50, EditSingle_Price is only for numeric values ...
> Is this right or is there a mistake in my considerations?

Although things look similar, there are some subtle differences.
Simple example:
- In the Database some fields mustn't be NULL
- In the GUI-Client data-entry might start with all those fields NULL.

Putting MaxLength = 50 somewhere into the Model is surely a good idea,
but enforcing the limit in the GUI-component isn't always the best
solution.
E.g. if I cut'n'paste some Text into a Memo. Instead of having the text
automatically trimmed I'd rather want to see the Memo turn red and get
some Command-Buttons disabled. So I myself get the chance to trim the
text in a useful way.

Only one thing is for sure: In the end the command that performs a
Database Transaction has to respect the rules of the Database...

> b.)
> who does the calulation? I know that my class TPart can have a read only
> property "price" with a get method. But who does the actualization if
> the user changes something in the "amount_edit"? Must I assign onChange of
> the edit and write the new amount to the model, the model does the
> calculation and have a OnChangeAmount event?

All data goes to the Model and everyone who is interested in the data of
the Model gets a Notification when something of interest changes.

For a start I'd keep it simple. Something like:

TTestModel = class(TGUIModel)
public
OrigList: TPartList; // List of parts when read from the Database
EditList: TPartList; // List after user changes

SelectedIndex_EditList: Integer;
ChangesValid: Boolean;

MaxLength_partnr: Integer; // for example

procedure Command_Load(Query: IQuery);
procedure Command_SaveChanges(Transaktion: ITransaktion);
procedure ValidateChanges;
...
end;

TTestView = class(TGUIView)
public
// ... some Controls of the GUI
end;

TTestController = class(TGUIController)
public
...
property MyModel: TTestModel; // Model
property MyView: TTestView; // View

procedure OnNotify;
// update the ViewComponents when the Model sends a Notification

procedure OnEditChange(Sender: TObject);
// Handling of OnChange-Events from some Edit-Controls
...
end;

> c.)
> Is there a good real life example for download which contains many pattern?
> I'm reading the book from M. Fowler and I have looked to
> the Microsoft "Adventure works Cinema" example application. Everything is
> fine and the main concept is clear, but the details...
>

Sadly we're living in some kind of IT-Stone-Age. Everything I've seen on
the internet so far is either incomplete, contains some major blunders
(like performance sinks) or doesn't scale well. Every man for himself...

...but some things still were actually useful to me:
- Some Taligent papers
- Joanna Carters postings
- Fowlers "Patterns of Enterprise Application Architecture"

> I know/realized, that I don't need "large pattern" and a domain model for
> this kind of simple application, but I would use this
> simple app for learning and understanding. I also know that an object is
> more powerfull, performant and flexible than a Dataset, but as a "normal old
> Delphi database programmer" it is a big changeover.
>

Definitely. But I'd never go back. With the traditional Delphi Way
complexity often rises exponentially with the number of controls.
A MVC/MVP-Architecture can help greatly to reduce that complexity
growth.

Joanna Carter

unread,
Jul 23, 2008, 6:22:59 PM7/23/08
to
M.Pannier a écrit :

> I think there is a lot of duplicated logic. The database has triggers,
> foreign keys, datatypes and a lot of other informatioen (not null...).
> The created class must "copy" this logic. The property partnr must be at
> least 50 character and must have a value...

Unless the database is legacy and already contains this logic, then
there is no need to put anything like triggers, or stored procs in it.

We have fairly comprehensive MVP and OPF frameworks where all the
business logic is in business classes, the database is simply dumb
storage with standard relationships (e.g.orderline/order) defined by a
FK/PK column pair. However, the business classes do not reflect that
FK/PK relationship as that is not necessary in the world of objects.

e.g.

(classes)
Invoice
Date
Customer
Lines (InvoiceLine)
Total

InvoiceLine
Quantity
Product
UnitPrice
Total

(tables)
Invoice
ID
Date
Customer
Total

InvoiceLine
ID
InvoiceID
Quantity
Product
UnitPrice
Total

Note two things :

1. There are no IDs in the classes, these are managed in the OPF, out of
site of the business classes.

2. There is no reference to the Invoice in the InvoiceLine class;
rather, the Invoice holds a list of InvoiceLine objects and is
responsible for managing them; store the Invoice and the lines get
stored as a consquence.

This mapping is managed in the OPF and need play no part in the business
domain.

> The Form/Controls must "copy" logic, too. EditPartNr must have MaxLength =
> 50, EditSingle_Price is only for numeric values ...
> Is this right or is there a mistake in my considerations?

We use strictly typed string classes to limit length of strings in
properties of business classes. e.g. TName represents a string of 15
chars, whereas AddressLine could be set at 30 chars. Now we use operator
overloading in C# to achieve reading/writing these properties without
casting but similar ideas should be possible in Delphi.

> b.)
> who does the calulation? I know that my class TPart can have a read only
> property "price" with a get method. But who does the actualization if
> the user changes something in the "amount_edit"? Must I assign onChange of
> the edit and write the new amount to the model, the model does the
> calculation and have a OnChangeAmount event?

If changing one property affects others, then it is a function of the
setter of the first property to set the fields behind the other
properties to be affected.

We use a list of "TProperty" or "TValue" objects as fields behind
properties of business classes, this allows us to hook up to validation,
change events, etc.

> c.)
> Is there a good real life example for download which contains many pattern?
> I'm reading the book from M. Fowler and I have looked to
> the Microsoft "Adventure works Cinema" example application. Everything is
> fine and the main concept is clear, but the details...

As others have said, there are a few sources out there, mine included,
although I mostly work in C# now as it gives me more functionality like
reflection, generics and a massive OO library.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer

M.Pannier

unread,
Jul 24, 2008, 6:18:10 AM7/24/08
to
Big thank You for the post...

> Although things look similar, there are some subtle differences.
> Simple example:
> - In the Database some fields mustn't be NULL
> - In the GUI-Client data-entry might start with all those fields NULL.

Not null fields are simple to handle, because I could use a default value or
check EditForm.OnButtonOK.Click if there is a value. But there are more
restrictions/logic in database that I have to "duplicate". But it is right:
"The database is the holy master of all."

> Putting MaxLength = 50 somewhere into the Model is surely a good idea,
> but enforcing the limit in the GUI-component isn't always the best
> solution.
> E.g. if I cut'n'paste some Text into a Memo. Instead of having the text
> automatically trimmed I'd rather want to see the Memo turn red and get
> some Command-Buttons disabled. So I myself get the chance to trim the
> text in a useful way.

But where I have to put this kind of logic? I must acces the onChange Event
of each component, and the model or gui must know the right length and must
give an information. I think it's very hard to implement, but in some cases
a good idea.

> Only one thing is for sure: In the end the command that performs a
> Database Transaction has to respect the rules of the Database...

Definitely.

Ok. I want to interpret it. I have a edit form. If I want to edit a part
object, I open that form and copy my actual object "into" the form. The
controller writes the modell to the gui. If the user changes my amount field
the OnChange of the edit fires. In that event the controller modifies the
model and the model fires an OnAmountChange event which induce the
Controller to update the EditWholePrice?

> Sadly we're living in some kind of IT-Stone-Age. Everything I've seen on
> the internet so far is either incomplete, contains some major blunders
> (like performance sinks) or doesn't scale well. Every man for himself...
>
> ...but some things still were actually useful to me:
> - Some Taligent papers
> - Joanna Carters postings
> - Fowlers "Patterns of Enterprise Application Architecture"

I think the same. The most examples or articles in magazin scratches at the
surface...

> Definitely. But I'd never go back. With the traditional Delphi Way
> complexity often rises exponentially with the number of controls.
> A MVC/MVP-Architecture can help greatly to reduce that complexity
> growth.

OK. I must learn with a simple application. And I have to check for every
project which kind of "developement" I have to use.

Thanks again for Your post.

M.Pannier


M.Pannier

unread,
Jul 25, 2008, 4:43:07 AM7/25/08
to
Hello and thanks for your replay.


> Unless the database is legacy and already contains this logic, then there
> is no need to put anything like triggers, or stored procs in it.

Yes and no. There are some performance issues and I have to ensure the data
integrity with datatypes, PK/FK and some triggers.

OK. I've understand. Is it right to say there is an abstract class in the
OPF with a property "ID" and each business object inherited from this OPF
class?


> We use strictly typed string classes to limit length of strings in
> properties of business classes. e.g. TName represents a string of 15
> chars, whereas AddressLine could be set at 30 chars. Now we use operator
> overloading in C# to achieve reading/writing these properties without
> casting but similar ideas should be possible in Delphi.

Do You mean this:

type
TName = string[15];
TStreet = string[30];
TPrice = Currency;

property
FName : TName;
FStreet : TStreet;
FSingle_Price : TPrice;

I can use my database domains (Interbase/Firebird) for this.


> If changing one property affects others, then it is a function of the
> setter of the first property to set the fields behind the other properties
> to be affected.

Thats clear. For my example that means, that I have to handle OnChange of
the Edit_amount and Edit_SinglePrice. Than I have to change my business
class (MyClass.Amount := IntToStr(Edit_amount.Text);) Than my business class
must fire an OnChange event which is handled by the Form (Controller) which
updates the Edit_WholePrice. Is it right.

> We use a list of "TProperty" or "TValue" objects as fields behind
> properties of business classes, this allows us to hook up to validation,
> change events, etc.

Any examples?


> As others have said, there are a few sources out there, mine included,
> although I mostly work in C# now as it gives me more functionality like
> reflection, generics and a massive OO library.

OK.


0 new messages