473,395 Members | 1,516 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Which class should handle this method?

Say I have a class called Invoice. An invoice consists of a header and
detail lines. In my class called Invoice I have a member which is a object
of a collection of DetailLines, defined as follows:

public class Invoice
{
.....
List <DetailLinedetail;
}

When I retrieve an invoice, I also want to retrieve the detail lines. So do
I retrieve the detail lines in my method GetInvoice(long invoiceNo) in the
Invoice class or is it more proper to have an InvoiceController class that
first gets the Invoice and then gets the detail lines and populates the
member field in the Invoice class.

I realize that it works both ways, but what is the best way to do it.

Bill

Sep 24 '07 #1
4 1474
On Sep 24, 10:06 pm, "BillG" <billgo...@charter.netwrote:
Say I have a class called Invoice. An invoice consists of a header and
detail lines. In my class called Invoice I have a member which is a object
of a collection of DetailLines, defined as follows:

public class Invoice
{
.....
List <DetailLinedetail;

}

When I retrieve an invoice, I also want to retrieve the detail lines. So do
I retrieve the detail lines in my method GetInvoice(long invoiceNo) in the
Invoice class or is it more proper to have an InvoiceController class that
first gets the Invoice and then gets the detail lines and populates the
member field in the Invoice class.

I realize that it works both ways, but what is the best way to do it.

Bill
The best way I personally think would be to encapsulate the fetching
of the detail lines in the invoice class. The invoice class might
delegate the actual fetching. The reason for this as that you might
end up with a "god" class (the controller class). The controller class
becomes a class that in itself has no information, but is purely there
to populate other objects. The temptation later could be to extend the
"god" class to do other work on the Invoice and InvoiceLine classes,
thus removing behaviour from the classes and the classes become pure
data carriers.

Here are a couple of links that might explain better:
http://en.wikipedia.org/wiki/God_object
http://c2.com/cgi/wiki?GodClass
http://www.pbell.com/index.cfm/2006/...eating-a-Class

Pieter

Sep 24 '07 #2

"pieter" <sc************@gmail.comwrote in message
news:11**********************@w3g2000hsg.googlegro ups.com...
On Sep 24, 10:06 pm, "BillG" <billgo...@charter.netwrote:
>Say I have a class called Invoice. An invoice consists of a header and
detail lines. In my class called Invoice I have a member which is a
object
of a collection of DetailLines, defined as follows:

public class Invoice
{
.....
List <DetailLinedetail;

}

When I retrieve an invoice, I also want to retrieve the detail lines. So
do
I retrieve the detail lines in my method GetInvoice(long invoiceNo) in
the
Invoice class or is it more proper to have an InvoiceController class
that
first gets the Invoice and then gets the detail lines and populates the
member field in the Invoice class.

I realize that it works both ways, but what is the best way to do it.

Bill

The best way I personally think would be to encapsulate the fetching
of the detail lines in the invoice class. The invoice class might
delegate the actual fetching. The reason for this as that you might
end up with a "god" class (the controller class). The controller class
becomes a class that in itself has no information, but is purely there
to populate other objects. The temptation later could be to extend the
"god" class to do other work on the Invoice and InvoiceLine classes,
thus removing behaviour from the classes and the classes become pure
data carriers.
Except that now your data access layer and your object model are conflated.
If there's any need to handle different database formats or other storage
and networking protocols in general, then the methods for populating an
Invoice should probably be kept separate from the Invoice class.
>
Here are a couple of links that might explain better:
http://en.wikipedia.org/wiki/God_object
http://c2.com/cgi/wiki?GodClass
http://www.pbell.com/index.cfm/2006/...eating-a-Class

Pieter

Sep 24 '07 #3

I agree with your statement. You could pass the data access layer
component into the invoice class, e.g.
GetInvoice(long invoiceNo, IRepository DataAccess) or have a
constructor that takes an implementation of your data access component
as a parameter. If you want to take this scenario even further you
could use an IoC container (e.g. Windsor / MicroKernel from
castleproject.org) to dynamically inject the data access component
into the class.

Thus when the database format (or networking protocols) changes the
Invoice class is not affected as the IRepository implementation takes
care of the fetching, but the invoice class is still responsible for
the population of invoice lines.

The point I was trying to get across is that it normally better to
avoid "god" classes as these classes knows to much about other classes
which results in a tightly coupled system. Again these are just my
humble opinions.

Pieter

Sep 25 '07 #4
Ben Voigt [C++ MVP] wrote:
Except that now your data access layer and your object model are conflated.
If there's any need to handle different database formats or other storage
and networking protocols in general, then the methods for populating an
Invoice should probably be kept separate from the Invoice class.
In situations like these I prefer to have a Data Access class specific
to invoices, and have the Invoice class only know that it needs to talk
to an InvoiceDataRetriever (or whatever naming convention suits you) and
that it will be provided via constructor. This way you keep your data
abstraction and also the ability to have the Invoice class manage
retrieving its InvoiceDetail children.

Chris.
Sep 25 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Adil Hasan | last post by:
Hello Fred, I just ran across your question. I think that the following code will work: ----- SERVER CODE ------ import SocketServer import time class...
16
by: cody | last post by:
I have a method that gets called if the user presses a certain button. If the object is in a state that doesn't allow the calling of that method, what should I do? Should I better throw an...
4
by: mchoya | last post by:
I'm so frustrated. I'm beginning school next week and I have been working on a simple program for several days now without being able to complete it. (Though I have brushed up on a lot of C++...
12
by: craigkenisston | last post by:
Hi, I will use an example to do a simplified description of my problem, please don't laugh. I just "believe" I would have to use either interface or abstract classes, but I've not ever write an...
5
by: hillcountry74 | last post by:
Hi, I'm a newbie to OOP and VB.Net. In the business layer, I have a base class, which is an abstract class in VB.Net. The derived class overrides a method and calls other methods in the base...
6
by: brian_harris | last post by:
I have a function that passes a string class pointer to a function, this function is then suppose to fill it and the outer function uses it. But I believe that I am running into problem due to...
20
by: tshad | last post by:
Using VS 2003, I am trying to take a class that I created to create new variable types to handle nulls and track changes to standard variable types. This is for use with database variables. This...
5
by: Nitesh | last post by:
Objects of type X are basic building blocks of my application and there are a few functions which return XHandle (typedef X** XHandle). The task at hand needs to use a couple of these functions and...
0
by: ma740988 | last post by:
Consider # include <iostream> # include <vector> # include <typeinfo> # include <string> class BaseMsg { friend std::ostream& operator<<( std::ostream&, const BaseMsg& ); std::string name...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.