OOP question --- theoretically speaking....

S

See_Rock_City

Hello All,

I've decided that this OOP thing is not just a fad. With
that in mind, I'm desparately trying to get rid of my
function-oriented design paradigm and switch to a more
object-centric view of the world. Migrating some aspects
of my antiquated style has been straight-forward. For example:

I used to do this:

<old style>------------------------

public class Widget()
{
public string property1;
public string property2;
}

.... Somewhere in a "Datahandler" class:

public Widget fetchWidget(int widgetid)
{
Widget w = new Widget();
.... do some database spelunking...

w.property1=....
w.property2=....

return w;
}


</old style>---------------------------

But now I do this

<new style>----------------------------

public class Widget()
{
private string _property1;
{
set
{ ... etc.

private string _property2;
{
set
{ ... etc.


public Widget(){}
public Widget(int widgetid)
{
this.fetchMe(widgetid);
}

private void fetchMe(int widgetid)
{
.... do some database spelunking...
.... poulate internal vars. ...

}
}
</new style>--------------------------


But what about collections of Widgets?

Continuing on from the first example above. In the same "Datahanders"
class, I used to have a method like:

<old style>---------------------------------------------------------

public ArrayList callingAllWidgets()
{
ArrayList widgets = new ArrayList();
.... database spelunking....
foreach (whatever)
{
Widget w = new Widget();
w.property1=... etc.
...
widgets.Add(w);
}

return widgets;
}

</old style> -------------------------------------------------------

Obviously, there's no reason I couldn't use the same design using the
more updated version (the new style) of a widget, i.e:

public ArrayList callingAllWidgets()
{
ArrayList widgets = new ArrayList();
.... database spelunking....
foreach (whatever)
{
Widget w = new Widget(foreachvalue);
widgets.Add(w);
}

return widgets;
}

but this seems like cheating ;) Is there a better, more universally
accepted superterrific way? Should i use a corresponding collections
class with an Indexer? Should I create some souped up IList
implemenation? I could certainly see the benefit of a class that
specialized in providing some aggregators (i.e. add all the Widgets
property1 values) but this isn't always necessary.

Thanks in advance..
 
J

Joanna Carter \(TeamB\)

I've decided that this OOP thing is not just a fad.

Well it has stood the test of about 30 years :))
<new style>----------------------------

public class Widget()
{
private string _property1;
{
set
{ ... etc.

private string _property2;
{
set
{ ... etc.


public Widget(){}
public Widget(int widgetid)
{
this.fetchMe(widgetid);
}

private void fetchMe(int widgetid)
{
.... do some database spelunking...
.... poulate internal vars. ...

}
}
</new style>--------------------------

There are some of us who feel that putting database code into a business
object is not really very OO. Doing this means that, should you change
database access components, you have to rewrite your class all over again.

It really is better and more beneficial to have a separate data layer that
knows how to read/write your objects (possibly using reflection), thereby
allowing you to program business objects without any knowledge of the
database you are using.
But what about collections of Widgets?
Obviously, there's no reason I couldn't use the same design using the
more updated version (the new style) of a widget, i.e:

public ArrayList callingAllWidgets()
{
ArrayList widgets = new ArrayList();
.... database spelunking....
foreach (whatever)
{
Widget w = new Widget(foreachvalue);
widgets.Add(w);
}

return widgets;
}

but this seems like cheating ;) Is there a better, more universally
accepted superterrific way? Should i use a corresponding collections
class with an Indexer? Should I create some souped up IList
implemenation? I could certainly see the benefit of a class that
specialized in providing some aggregators (i.e. add all the Widgets
property1 values) but this isn't always necessary.

You should never derive from or use ArrayList or any other general list
class. Instead you need to create typesafe list classes that only know how
to manipulate (e.g.) Widgets. Of course you would use something like
ArrayList inside this class but that is the only place you would have to
cast from object to Widget and back again.

The same principle appplies to lists as to single objects; try to separate
out the database code from the business concepts. But you would possibly
want to implement IList by delegation to the internal list to allow a data
mechanism to return/manipulate a common list type

A simplified mechanism to interface with databases (Object Persistence
Framework) would have an interface like this :

class ObjectBroker
{
bool StoreObject(object obj);
bool DeleteObject(object obj);
bool RetrieveObject(object obj);
IList RetrieveForType(Type type);
}

Joanna
 
C

Cor Ligthert

Joanna,
Well it has stood the test of about 30 years :))

However almost the same time exist the so called relational databases which
for me seems to been build on punchcard methods and are unable in a one to
one way to hold a list structure. Something which was with databases before
that time very easy to do.

Therefore one of those is for me wrong. (My opinion the relational
database).

Just my thought,

Cor
 
S

See_Rock_City

Hey Joanna, thanks for the reply!

There are some of us who feel that putting database code into a business
object is not really very OO. Doing this means that, should you change
database access components, you have to rewrite your class all over again.

It really is better and more beneficial to have a separate data layer that
knows how to read/write your objects (possibly using reflection), thereby
allowing you to program business objects without any knowledge of the
database you are using.

This, I agree with completely. In fact, this was always a big question
in my mind. It doesn't feel right mixing the bl layer with the data
layer. I'm glad to hear you say this ;)

You should never derive from or use ArrayList or any other general list
class.

By this I'm assuming you mean simply not to inherit from any intrinsic
collection implementation?
Instead you need to create typesafe list classes that only know how
to manipulate (e.g.) Widgets. Of course you would use something like
ArrayList inside this class but that is the only place you would have to
cast from object to Widget and back again.

The same principle appplies to lists as to single objects; try to separate
out the database code from the business concepts. But you would possibly
want to implement IList by delegation to the internal list to allow a data
mechanism to return/manipulate a common list type

I have (in the past) created classes that simply wrap a private
ArrayList and implement IList so that they are compatible with the
standard collections nomenclature calling clients would be used to.
This way, I can add class-specific methods blah blah blah.
A simplified mechanism to interface with databases (Object Persistence
Framework) would have an interface like this :

class ObjectBroker
{
bool StoreObject(object obj);
bool DeleteObject(object obj);
bool RetrieveObject(object obj);
IList RetrieveForType(Type type);
}

Ya' lost me here I'm embarrassed to say.
 
S

Steve Walker

"Joanna Carter said:
There are some of us who feel that putting database code into a business
object is not really very OO. Doing this means that, should you change
database access components, you have to rewrite your class all over again.

It really is better and more beneficial to have a separate data layer that
knows how to read/write your objects (possibly using reflection), thereby
allowing you to program business objects without any knowledge of the
database you are using.

Hmm. I've always tried to make the database access tier independent of
the domain model; usually a matter of accepting simple types and
returning objects from the System.Data namespace. In my last job, we
initially hosted each tier as serviced components and serialised chunks
of the domain model out to the web UI layer via a service layer (kind of
a lazy memento pattern :blush:) ). The service layer included code for
mapping domain model objects to calls to database layer methods. Stuff
like:

class FooSL:ServicedComponent
{
public Foo GetFoo(int id)
{
using(FooDB db = new FooDB())
{
DataTable dt = db.GetFooByID(id);
DataRow row = dt.Rows[0];
int id = (int)row["id"];
string name = (string)row["name"];
return new Foo(id, name);
}
}
}

We eventually decided that we were tripping up too much over issues of
object identity, and were writing too much similar code, so I designed a
mapping infrastructure. This was the kind of thing you are talking
about; it made use of a few simple interfaces on classes in the domain
model, and an awful lot of reflection. Despite the often quoted advice
never to write your own object-relational mapping infrastructure, it
worked pretty well, and once people had got their heads round it, it
improved productivity. The important thing, I think, is that the logic
for creating objects and the logic for querying the database were
decoupled.

I've changed jobs since then, and the system I'm now responsible for is
much less transactional than those I used to build; write occasionally,
read frequently. I'm using a much simpler architecture, with all tiers
running in process with the web UI tier and the domain model directly
exposed to the UI code. No COM+ at all. It's simpler, faster, and easier
to update. I've still got a discrete data access tier, but it's
generally accessed from within domain model class constructors.

The point is, I'm now extending my work, which was largely to replace
the presentational side of the legacy system, with code to replace the
administrative tools, and I'm finding problems which would have been
easier to solve with a mapping architecture; issues like wanting to
update an object graph transactionally. I can live with domain model
classes containing dependencies upon the names of columns in datatables,
but passing SqlTransaction objects around is just a bit too icky.

So, I think I'm agreeing with you that some kind of mapper pattern is
desirable, but I'd want to separate the code which knows about the
persistent storage from the code which knows about the domain model.

Steve
 
J

Joanna Carter \(TeamB\)

I can live with domain model
classes containing dependencies upon the names of columns in datatables,
but passing SqlTransaction objects around is just a bit too icky.

That's one way of describing it :))
So, I think I'm agreeing with you that some kind of mapper pattern is
desirable, but I'd want to separate the code which knows about the
persistent storage from the code which knows about the domain model.

I am in the middle of moving my Delphi OPF into C# 2.0. The code saving
using generics is absolutley mind-blowing. And finally I can use operator
overloading to give me a really simple syntax for concatenating Criteria for
submission to the OPF to retrieve lists, etc.

First create your Criteria :

SelectionCriterion<int> age = new GreaterThanCriterion<int>("Age", 21);

SelectionCriterion<string> name = new StartingCriterion("Name", "Jo");

SelectionCriterion<DateTime> startDate = new
GreaterThanOrEqualToCriterion<DateTime>("StartDate", DateTime.Now);

SelectionCriterion allowance = new IsNullCriterion("Allowance");

....then concatenate them using expected logical operators :

SelectionCriterion join = (age | name) & (startDate | allowance);

It just makes life so much easier not to have to think about DB related
stuff when you are designing systems.

Joanna
 
S

Steve Walker

"Joanna Carter said:
That's one way of describing it :))

I was being polite :blush:)
I am in the middle of moving my Delphi OPF into C# 2.0. The code saving
using generics is absolutley mind-blowing. And finally I can use operator
overloading to give me a really simple syntax for concatenating Criteria for
submission to the OPF to retrieve lists, etc.

<- stuff ->

Very neat. I always think of the application to collections when
generics are mentioned, but that's a more better use for them. I've got
rid of a lot of the unpleasantness of SQL parameter building with a very
ugly base parameter wrapper class and a sly implicit cast to
SqlParameter:

public static implicit operator SqlParameter (ParameterBase p)
{
return p.underlyingParameter;
}

Unpalatable way of faking polymorphism because the nice people at
Microsoft made SqlParameter a sealed class, but it lets me pass my
subclasses to a command's parameters collection. I then have a plethora
of subclasses, many of which would be unnecessary with generics.
It just makes life so much easier not to have to think about DB related
stuff when you are designing systems.

Databases are a necessary evil as far as I'm concerned. The system I'm
gradually replacing is basically a monolithic architecture implemented
in TSQL with a thin ASP classic front end. Effectively uses some tables
as shared memory. Utterly terrifying to modify. It's fast, though, I'll
give it that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top