C# OO problem

  • Thread starter Thread starter sklett
  • Start date Start date
S

sklett

I have created a series of classes for my business layer, data retrieval is
working fine and things seem good.

However I have quickly discovered a design flaw in my system in that my
objects aren't aware of siblings and parents.
In other words, if I have a Customer object and Customer objects have
CustomerSettings objects - Let's say I want to create a new Customer, then
add a set of CustomerSettings to the new customer based on CustomerSettings
from another Customer. I can't, not gracefully at least.

I need to re-design so that my objects have a common member that will expose
all the other data they need.

Since Customers are the theoretical top level node in my BOL hierarchy,
there is nothing else tying them together.

I have tried to decide how to solve this, but am coming up short. I thought
that a new, top level object called BOLDataManager that would hold Customers
and their children would be a good solution, but then I'm still faced with
the issue of the Customer objects knowing about BOLDataManager. Do I pass a
reference to it's instance everytime I add a Customer? That doesn't seem
correct.

I hope this makes sense to someone, I'm pretty stuck and I would love to
find a good solution and move on!

Thanks,
Steve
 
Steve,

I am curious, why not just expose a collection of sub-business objects
from Customer? You would have a property on Customer called Settings which
would expose the CustomerSettings object collection.

Of course, this would require you to walk the heiarchy in your data
layer, but it shouldn't be that much of a problem.

Hope this helps.
 
Hi Nicholas,

I think I was unclear. I do have properties on my Customer objects exposing
the nesting objects and collections, but the problem is that 2 Customer
objects aren't aware of each other.

If I'm in a method of Customer called AddSettingsFromTemplateCustomer(string
templateName) (long name, huh?)
and I wanted to find the customer that had the name [templateName] I can't,
because my customer object is isolated from the others.


I hope that makes more sense. Thanks for replying, I get excited when I see
a reply show up ;)
Steve



Nicholas Paldino said:
Steve,

I am curious, why not just expose a collection of sub-business objects
from Customer? You would have a property on Customer called Settings
which would expose the CustomerSettings object collection.

Of course, this would require you to walk the heiarchy in your data
layer, but it shouldn't be that much of a problem.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

sklett said:
I have created a series of classes for my business layer, data retrieval
is working fine and things seem good.

However I have quickly discovered a design flaw in my system in that my
objects aren't aware of siblings and parents.
In other words, if I have a Customer object and Customer objects have
CustomerSettings objects - Let's say I want to create a new Customer,
then add a set of CustomerSettings to the new customer based on
CustomerSettings from another Customer. I can't, not gracefully at
least.

I need to re-design so that my objects have a common member that will
expose all the other data they need.

Since Customers are the theoretical top level node in my BOL hierarchy,
there is nothing else tying them together.

I have tried to decide how to solve this, but am coming up short. I
thought that a new, top level object called BOLDataManager that would
hold Customers and their children would be a good solution, but then I'm
still faced with the issue of the Customer objects knowing about
BOLDataManager. Do I pass a reference to it's instance everytime I add a
Customer? That doesn't seem correct.

I hope this makes sense to someone, I'm pretty stuck and I would love to
find a good solution and move on!

Thanks,
Steve
 
Steve,

In that case, you would have to have a manager of some sort (I would
make it private) which would have a mapping between the name and the
instance itself.

The problem with this is that the manager would extend the lifetime of
the object. You would have to add extra code to indicate when the object
was done being used, so that the manager could release it.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

sklett said:
Hi Nicholas,

I think I was unclear. I do have properties on my Customer objects
exposing the nesting objects and collections, but the problem is that 2
Customer objects aren't aware of each other.

If I'm in a method of Customer called
AddSettingsFromTemplateCustomer(string templateName) (long name, huh?)
and I wanted to find the customer that had the name [templateName] I
can't, because my customer object is isolated from the others.


I hope that makes more sense. Thanks for replying, I get excited when I
see a reply show up ;)
Steve



Nicholas Paldino said:
Steve,

I am curious, why not just expose a collection of sub-business objects
from Customer? You would have a property on Customer called Settings
which would expose the CustomerSettings object collection.

Of course, this would require you to walk the heiarchy in your data
layer, but it shouldn't be that much of a problem.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

sklett said:
I have created a series of classes for my business layer, data retrieval
is working fine and things seem good.

However I have quickly discovered a design flaw in my system in that my
objects aren't aware of siblings and parents.
In other words, if I have a Customer object and Customer objects have
CustomerSettings objects - Let's say I want to create a new Customer,
then add a set of CustomerSettings to the new customer based on
CustomerSettings from another Customer. I can't, not gracefully at
least.

I need to re-design so that my objects have a common member that will
expose all the other data they need.

Since Customers are the theoretical top level node in my BOL hierarchy,
there is nothing else tying them together.

I have tried to decide how to solve this, but am coming up short. I
thought that a new, top level object called BOLDataManager that would
hold Customers and their children would be a good solution, but then I'm
still faced with the issue of the Customer objects knowing about
BOLDataManager. Do I pass a reference to it's instance everytime I add a
Customer? That doesn't seem correct.

I hope this makes sense to someone, I'm pretty stuck and I would love to
find a good solution and move on!

Thanks,
Steve
 
Nicholas Paldino said:
Steve,

In that case, you would have to have a manager of some sort (I would
make it private) which would have a mapping between the name and the
instance itself.

The problem with this is that the manager would extend the lifetime of
the object. You would have to add extra code to indicate when the object
was done being used, so that the manager could release it.
<snip>

Nicholas,
That is what I've started to implement. Customer is my logical top most
node. I have created a class that has a static collection of Customer
objects and I will add a reference to this "Manager" class for each customer
that I add. This bridges the gap allowing a Customer object to navigate to
the collection of customers. It seems ugly though.

I don't like the idea of passing references to every Customer object that I
create. This seems like a problem where careful OO design could solve, but
I'm not seeing it. I suppose I could try to have Customer inherit Manager,
that would be interesting...

In my particular application, ALL the data is represented in a tree view and
is fetched once at startup so I am not too concerned with object
lifetimes(yet).

Thanks again for another replay, I will chew on it and keep thinking about
this,
Steve
 
Steve,

The base case in this scenario (and I was wrong when I said make the
manager private) would be to expose the mananger. Instead of creating new
customer objects, the manager would be a class factory as well, returning
the object to you when you need it. Also, you can have a method that would
release the reference in the manager as well.

Then, in general, everything would go to the mananger to get the
customer object, you wouldn't create an instance yourself. When you expose
other customers (siblings) through your customer object, you would refer to
the manager in the internal implementation.
 
Nicholas,
Interesting, so treat it like a true "Manager" ;)

I have a weird, mutt implementation right now when my objects inherit
BOLBase and BOLBase inherits BOLMananger

This has afforded me what I want, but I don't like the design, I like what
you are saying. I will reread this and take a swing at it later, I need to
go to my real job now. Thanks for your help, the quick replies are really
appreciated!

Have a good one, I'll let you know how I do,
Steve



Nicholas Paldino said:
Steve,

The base case in this scenario (and I was wrong when I said make the
manager private) would be to expose the mananger. Instead of creating new
customer objects, the manager would be a class factory as well, returning
the object to you when you need it. Also, you can have a method that
would release the reference in the manager as well.

Then, in general, everything would go to the mananger to get the
customer object, you wouldn't create an instance yourself. When you
expose other customers (siblings) through your customer object, you would
refer to the manager in the internal implementation.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

sklett said:
<snip>

Nicholas,
That is what I've started to implement. Customer is my logical top most
node. I have created a class that has a static collection of Customer
objects and I will add a reference to this "Manager" class for each
customer that I add. This bridges the gap allowing a Customer object to
navigate to the collection of customers. It seems ugly though.

I don't like the idea of passing references to every Customer object that
I create. This seems like a problem where careful OO design could solve,
but I'm not seeing it. I suppose I could try to have Customer inherit
Manager, that would be interesting...

In my particular application, ALL the data is represented in a tree view
and is fetched once at startup so I am not too concerned with object
lifetimes(yet).

Thanks again for another replay, I will chew on it and keep thinking
about this,
Steve
 
sklett said:
Hi Nicholas,

I think I was unclear. I do have properties on my Customer objects exposing
the nesting objects and collections, but the problem is that 2 Customer
objects aren't aware of each other.

If I'm in a method of Customer called AddSettingsFromTemplateCustomer(string
templateName) (long name, huh?)
and I wanted to find the customer that had the name [templateName] I can't,
because my customer object is isolated from the others.

There are two decent ways I can think of to work around this problem:

1. Pass a Customer object to AddSettingsFromTemplateCustomer. Get the
other Customer object from BOLDataManager in other code.

2. Give some other object responsibility for copying the settings to one
Customer from another.

Rik
 
Skelt,

I also find myself in OO hicups sometimes.
I don't really understand your design without looking at the code.
The only advice I can give you is try taking the OO out of it.
I tried this myself and it worked perfectly for me, it's a little more
time consuming, but you will always come up with a good design.

I always start by designing my design so to speak in a non OO language,
there are many languages our there that do not support OO. How would
these developers design their apps? Ok, this might seem a bit extreme
because you would think that you couldn't really compare it, but try
it, you may be surprised, you will then realise why you need OO in the
first place and the design will be presented to you almost
automatically, especially the hierarchy and the implementation of
inheritance. Sometimes we take OO for granted.

Anyhow you might think I'm a bit crazy and tell me to shutup at which
point I'll gracefully bow out.
 
Shut up.

j/k

Kevin, I know what your saying, it's like that old saying "can't see the
forest for the trees" or whatever. It's true. I have been focusing so hard
on OO that I have at times lost sight of the objectives. I will think about
what you've wrote. Although my design is limping along, I'm very unhappy
with the design and might do a full re-write, at which point I would give
your approach a whirl.

Take it easy,
Steve
 
sklett said:
Hi Nicholas,

I think I was unclear. I do have properties on my Customer objects
exposing the nesting objects and collections, but the problem is that 2
Customer objects aren't aware of each other.

If I'm in a method of Customer called
AddSettingsFromTemplateCustomer(string templateName) (long name, huh?)
and I wanted to find the customer that had the name [templateName] I
can't, because my customer object is isolated from the others.

As Nicholas suggest you need some kind of Manager. Martin Fowler call this a
Registry in his PoEAA book. When you want an object you ask the Registry for
it. It keeps track of whether it has the requested object or not in an
identity map (typically a hashtable). If it already has the object it
returns it otherwise if the object is not in the identity map then it gets
it from the appropriate builder. As Nicholas said you do have to make sure
you release the object else the Registry eventually has all the customers
with all their information.

SP
 
One cannot dismiss as useless what one does not understand.

Object-orientation is logical, elegant, and extremely helpful, if you
understand it and know how to use it. If you think otherwise, you don't
understand it.

Human beings are in many ways just like computers. And guess what? Human
beings are object-oriented. We think in terms of objects, and act as if the
world was composed of objects. We make logical divisions between aggregate
groups of process and data, and treat those aggregate groups as objects. It
makes the world manageable to us. The world is far more complex than we
realize. Do you know, for example, the sequence of operations that your
brain performs when you throw a ball? There was a time in your life when you
didn't even know how to lift your arm, or what an "arm" was. Watch a newborn
baby sometime.

In fact, you don't have arms. Where does an "arm" begin? At the cellular
level, it is impossible to say. The human body is actually a colony of
cells, all with the same basic characteristics, and each with a unique life
of its own. An "arm" is simply an object-oriented convenience we have
manufactured to make it easier to perform certain types of operations which
involve certain cells working in cooperation, one with another, and for the
purpose of communicating information between humans regarding these
operations.

To throw a ball, the brain (an object-oriented concept regarding an
aggregate group of certain types of cells located in a certain area of the
body, and performing certain tasks) performs a complex sequence of
instructions to various parts of the nervous system (another object-oriented
concept along the same lines), a sequence learned at a very early age,
modified and tweaked with each iteration, and memorized at a time when we
were unable to form the word-thought processes that enable us to think
consciously about it.

The language we use to communicate is object-oriented out of necessity.
Imagine having to continuously describe in detail anything about the
operations our brain and peripheral hardware execute with regards to our
"arms." Instead, we refer to "thowing a ball," "shaking hands," etc.

The purpose of human language is to communicate efficiently while hiding the
underlying complexity of things. We encapsulate. We inherit. We abstract.
And our language is polymorphic.

Perhaps object-orientation is not needed when we are infants. Perhaps
object-orientation isn't needed to learn how to walk, for example. But to
dance, to philosophize, to drive a car, to fly an airplane, and to program a
computer, we could not do these things without it.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
Big things are made up of
lots of little things.
 

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

Similar Threads


Back
Top