when to use component-based design vs. stayign with traditional OOPOptions

O

Ojas

First, I can understand component-based design when it is obvious that
components will likely be reused, or when we want to leverage existing
components.

Does anyone know of a good web page that nicely summarizes best
practices for when, and when not to, follow component design versus
traditional OOP? And are there different implementation levels that
one can follow when implementing a component?

Is there a web page anywhere that explains how to properly implement a
component? For example, should it thoroughly check all input
parameters, should it gracefully throw a published exception when
methods are called out of sequence, etc. To what extent should the
component be made idiot proof? I'm asking because this comes at a
cost in terms of development time, QA time, and processing overhead
(impacts performance).

Why:

I am working on a new product, and it is a product where nobody will
ever want to reuse any of our classes for other products.

In Visual Studio we've broken the product up into multiple projects
that use each other to simplify development on it given we have a half
dozen developers working on it.

This is a non-UI product, and it is highly specialized.

Assuming we do not need reuse of our large-grain components, for
example a component could be an adapter for reading and writing data
to a specific data source type (SQL Server), it seems like over-
engineering to have the main classes in these project files conform to
strict component contracts.

The public methods on our classes will never be used by anyone other
than the immediate small development team.

For example:

* do we need to have the component handle any invalid input values by
throwing an exception? For example, if someone passes a list, throw
an exception if any list element is null.

* do we need to have the component gracefully throw exceptions anytime
a dev makes an incorrect call sequence?

* should we add unit tests for every invalid and valid input parameter
combination we can think of? And of course add and test the software
to make all of these unit tests pass.

* etc.
 
R

Registered User

First, I can understand component-based design when it is obvious that
components will likely be reused, or when we want to leverage existing
components.

Does anyone know of a good web page that nicely summarizes best
practices for when, and when not to, follow component design versus
traditional OOP? And are there different implementation levels that
one can follow when implementing a component?
What are the perceived differences between component-based design and
traditional OOP? Reusability and inheritance are both tenets of
OOA/D/P.
Is there a web page anywhere that explains how to properly implement a
component? For example, should it thoroughly check all input
parameters, should it gracefully throw a published exception when
methods are called out of sequence, etc. To what extent should the
component be made idiot proof? I'm asking because this comes at a
cost in terms of development time, QA time, and processing overhead
(impacts performance).
Much depends upon how the type will be used and what behavior the type
should exhibit. Validating parameters is never a bad idea, exceptions
can be expensive. AFA calling methods in a particular sequence I
dunno, it depends upon what the task is. You might consider
encapsulating a sequence of private/protected methods with a public
method. Once again, depending upon the task, WWF might be a suitable
tool.

Design is a key factor in development time, QA time, and processing
overhead. A poorly thought-out design can slow production down and
sometimes even put it reverse. One thing that is not mentioned is an
eye towards future maintenance. This too is influenced by the design.
Maintenance shouldn't include excessive time spent figuring out "what
the f*ck was this supposed to do?"
Why:

I am working on a new product, and it is a product where nobody will
ever want to reuse any of our classes for other products.
Never say never.
In Visual Studio we've broken the product up into multiple projects
that use each other to simplify development on it given we have a half
dozen developers working on it.
Here is a point where reusability and inheritance probably will be
useful. At some level of abstraction pieces of the projects'
functionality will be more the same than different.
This is a non-UI product, and it is highly specialized.

Assuming we do not need reuse of our large-grain components, for
example a component could be an adapter for reading and writing data
to a specific data source type (SQL Server), it seems like over-
engineering to have the main classes in these project files conform to
strict component contracts.
I dunno what is meant by component contracts, Interfaces perhaps? In
any case don't assume anything. For interaction with a data store a
base class might contain the specific functionality while derived
classes could use off the shelf data providers to move the data
around. Today's specific data source is no guarantee of the future.
The public methods on our classes will never be used by anyone other
than the immediate small development team.

For example:

* do we need to have the component handle any invalid input values by
throwing an exception? For example, if someone passes a list, throw
an exception if any list element is null.
Depending upon the situation an improper list element may be an
ignorable error. For instance if items are being processed to be
placed on an order, how serious is quantity zero for an item? Should
the whole process be disrupted or can the error be noted and the item
skipped?
* do we need to have the component gracefully throw exceptions anytime
a dev makes an incorrect call sequence?
An expected call sequence might be something to avoid, especially if
the proper sequence is determined by logic found in the caller. If the
sequence is a drill down rather than this sequence

public List<Year> getYears(){...)
public List<Make> getMakes(Year year){...}
public List<Model> getModels(Year year, Make make){...}
public List<Engine> ...

a single method might be used.
public List<Qualifier> getNextQualifier(List<Qualifier>
selectedQualifiers){...}

Logic within getNextQualifier method can determine the proper call to
make based upon the selected qualifiers. With a single method there is
no concern about the caller using an incorrect sequence.
* should we add unit tests for every invalid and valid input parameter
combination we can think of? And of course add and test the software
to make all of these unit tests pass.
With thought many potential errors can be prevented by a proper
design. Validating input isn't a bad idea unless the type itself is
not concerned with the actual input. Generally a data provider has no
business inspecting and validating the data it handles.

Part of errors and exception handling is knowing what should happen
when a negative case occurs. If quantity zero on an order is a major
error, what happens to the aborted order? Designing for the
affirmative case is easy, it's all the negative cases where the design
really, really becomes important.
Design, design, design, I can't say it enough. A well though-out
design makes implementation into more of a paint by numbers scheme.
Most if not all of the original thought should come in the design
stage. Creating a proper OO design is important regardless of the
application's size, user base, proposed functionality .... It is the
foundation upon which everything is to be built. The specifics of a
design are dependant upon desired functionality and behavior.

regards
A.G.
 

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