a modular design question

S

Shawn

Hi,

I have a modular design(code-reusage) question. In order to make my
point clear, I have made up the following fake situations:

Last year in a project, I have written a class Person:

class Person
{
private String sName;
private Char cGender; //M: male; F: female
private double dWeight;
private double dHeight;
...

public Person()
{
//some code
}

public String getName()
{
//some code
}

...
//more code

}

Now, I have a new project for the Zoo. I found that I need a class Animal:

class Animal
{
private String sName; //suppose each animal has a name too
private Char cGender; //M: male; F: female
private double dWeight;
private double dHeight;
...

public Animal()
{
//some code
}

public String getName()
{
//some code
}

...
//more code

}

What should I do? Suppose the Animal class has 90% code same as the
Person class. I can think of several answers:
(A) Using Person class as a guide, quickly write Animal class. Because
there is a guide, so writing Animal class won't take as much time as
writing Person class.

Problems: I feel there is no code-reusage at all, strictly speaking.

(B)Using abstract class: write an abstract class which captures the
common features of both Person class and Animal class. Then write the
subclasses of it, which are Person class and Animal class.

Problems: now I have to change the code (Person class) in last year's
project. I have finished and delivered the project already.

I am not sure there is a good way to solve such a problem. I just want
to know normally how experienced programmers handle it.

Thank you very much for all your feedback.
 
R

Robert Klemme

Hi,

I have a modular design(code-reusage) question. In order to make my
point clear, I have made up the following fake situations:

Last year in a project, I have written a class Person:

What should I do? Suppose the Animal class has 90% code same as the
Person class. I can think of several answers:
(A) Using Person class as a guide, quickly write Animal class. Because
there is a guide, so writing Animal class won't take as much time as
writing Person class.

Problems: I feel there is no code-reusage at all, strictly speaking.

(B)Using abstract class: write an abstract class which captures the
common features of both Person class and Animal class. Then write the
subclasses of it, which are Person class and Animal class.

Problems: now I have to change the code (Person class) in last year's
project. I have finished and delivered the project already.

IMHO the choice depends largely on how related those projects are and
how many of these cases you have. If you feel you get frequently into
this situation or these projects are somehow related it might be
reasonable to go with A and refactor Person to inherit from a base class
that you stick into some form of library (which is used by both
projects). However, if it is just these two classes it's probably not
worth while and copy and paste is a better solution. (This is also a
form of code reuse albeit not the one commonly intended.)

Kind regards

robert
 
S

Shawn

Robert Klemme wrote:
If you feel you get frequently into
this situation or these projects are somehow related it might be
reasonable to go with A and refactor Person to inherit from a base class
that you stick into some form of library (which is used by both
projects).

Thank you very much. I assume you mean "go with B and refactor Person to
inherit from a base class ..."

I don't know anything about "refactor". Could you give me a little more
information? a tutorial link? I just want to educate myself. I am not
running into such situations at all. But I think if a programmer CARES
very much about modular design, such scenarios should be very common.

Thank you very much.
 
R

Robert Klemme

Robert Klemme wrote:
If you feel you get frequently into

Thank you very much. I assume you mean "go with B and refactor Person to
inherit from a base class ..."

Oops! Yes, of course.
I don't know anything about "refactor". Could you give me a little more
information? a tutorial link? I just want to educate myself. I am not
running into such situations at all. But I think if a programmer CARES
very much about modular design, such scenarios should be very common.

Just google for "refactoring". There is also Martin Fowler's famous
book (haven't read it myself):
http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672
http://www.refactoring.com/

Kind regards

robert
 
C

Chris Uppal

Shawn said:
private String sName; //suppose each animal has a name too
private Char cGender; //M: male; F: female
private double dWeight;
private double dHeight;

Just as an aside: unless you have an externally applied reason for tagging
names with "type" prefixes (such as a teacher who demands it, or coding
standards your employer requires you to follow), then I'd get out of the habit
fast. It doesn't make a lot of sense in "traditional" languages (just adds
noise), and it makes no sense at all in OO languages. It is also /highly/
unpopular in the Java world...

What should I do? Suppose the Animal class has 90% code same as the
Person class. I can think of several answers:
(A) Using Person class as a guide, quickly write Animal class. Because
there is a guide, so writing Animal class won't take as much time as
writing Person class.

If the two are only accidentally similar then that would be the right thing to
do. In this particular example (made up, as you said) is almost certainly
accidental (unless you happen to be a biologist working in a context where
humans are just one more kind of animal).

Problems: I feel there is no code-reusage at all, strictly speaking.

Correct. If the similarity is accidental, then sharing code between them would
be, at best, misleading.

(B)Using abstract class: write an abstract class which captures the
common features of both Person class and Animal class. Then write the
subclasses of it, which are Person class and Animal class.

That's a possible approach. But you should be very sure that you are actually
gaining something by changing the pre-existing code. If that code is not under
active development, then there is no possible gain from making it share with
something else. If it is, then there is still no apriori reason to suppose
that it might be a benefit -- it /might/ be, but you have to think about what
the benefit would be (something concrete, not just "reducing duplication").
Often there is a real benefit to be obtained, but I'd say that the opposite
case occurs even more often.

Problems: now I have to change the code (Person class) in last year's
project. I have finished and delivered the project already.

Yup.

However -- there is something else you can do here. Just because you haven't
changed the code from last year's project doesn't mean you can't learn from it.
You've seen that (by hypothesis) there is a useful degree of code sharing
possible, and you have experience to say that projects that could share that
code do happen (you are on the second one already); so /this/ time you write
your new project on the assumption that yet a third in the same general pattern
is likely to come along sooner or later. Because you have already seen
another project that /could/ have shared the code, you know rather well how to
write the code incorporating the necessary flexibility this time around.

You could even use last-year's code as test case for your new design. Change
the old code to use the new framework, and see if everything goes smoothly. If
it does then that gives you extra reason to believe the new design is good --
but then throw away your experimental code.

Note that many programmers think it's a mistake to try to abstract out the
potential common stuff /before/ you have seen a few similar projects. On the
whole, I think they are right -- it is better to design for the (known) past
than for the (unknown) future.

-- chris
 
R

Robert Klemme

On 18.09.2006 17:57, Chris Uppal wrote:

Note that many programmers think it's a mistake to try to abstract out the
potential common stuff /before/ you have seen a few similar projects. On the
whole, I think they are right -- it is better to design for the (known) past
than for the (unknown) future.

As a side note: that's probably also the reason why it is considerably
harder to get a library designed well than a single application. Sun
gave us good demonstrations of this with the standard lib. Off the top
of my head I can name several concepts that they redid - sometimes even
more than once.

Kind regards

robert
 
S

su_dang

Robert said:
On 18.09.2006 17:57, Chris Uppal wrote:



As a side note: that's probably also the reason why it is considerably
harder to get a library designed well than a single application. Sun
gave us good demonstrations of this with the standard lib. Off the top
of my head I can name several concepts that they redid - sometimes even
more than once.

Kind regards

robert

Have you considered another approach:

In your Animal class, create a reference to Person. When the behavior
is the same, you just have to call person.doSomething(). Otherwise,
use your own implementation in Animal.
 
G

Greg R. Broderick

(e-mail address removed) wrote in

Have you considered another approach:

In your Animal class, create a reference to Person. When the behavior
is the same, you just have to call person.doSomething(). Otherwise,
use your own implementation in Animal.

But that doesn't model the real-world reality at all well -- it is
considerably less valid to state that "Animal has a Person" than it is to
state "Person is an Animal". There could be an (orthagonal) subclass
(perhaps a decorator to the Animal class?) called "Pet" which would have a
Person (its owner/keeper).

It is also, of course, invalid to state "Animal is a Person" unless you're
speaking of my cat. :)

Cheers!
GRB

--
---------------------------------------------------------------------
Greg R. Broderick (e-mail address removed)

A. Top posters.
Q. What is the most annoying thing on Usenet?
---------------------------------------------------------------------
 
C

Chris Uppal

Robert Klemme wrote:

[me:]
As a side note: that's probably also the reason why it is considerably
harder to get a library designed well than a single application. Sun
gave us good demonstrations of this with the standard lib.

Agreed. And they seem to have settled down to a policy of ruthlessly
over-engineering everything as a result. (And, in all honesty, I can't see
that they have all that much choice).

-- chris
 
C

Chris Uppal

Greg said:
But that doesn't model the real-world reality at all well -- it is
considerably less valid to state that "Animal has a Person" than it is to
state "Person is an Animal".

It might not be appropriate in this case[*], but the OP did say that this was
only an example. I think he was more concerned with the re-use aspects of the
problem that the modelling aspects -- and as far as that goes, it makes little
difference /how/ you express the extra flexibility you've engineered into the
second version, you still have to decide whether to back-port the old stuff to
the new framework.

([*] although it might also be reasonable to say that a Person, in addition to
having a human nature -- bank account number and so on -- also HAS an animal
nature.)

Still, if we are to talk of such things ;-) then this is a good place to
mention that few OO programmers consider "modelling reality" to be an important
part of OO. "Modelling the problem" (or rather, the relevant parts of the
problem) comes closer. Myself, I'm reluctant to use the word "modelling" at
all -- it suggests that there's a "something", independent of the program
structure, against which that structure has to be judged, and I think that's
the wrong approach.

-- chris
 

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

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top