Learning OOP conceptual question(s)

R

RSH

I am still trying to grasp the use of real world Objects and how to
conceptualize them using a business scenerio.

What I have below is an outline that I am wrestling with trying to figure
out a class structure:\

Top level Objects:
Companies
Employees

Under Companies I have:
CompanyDeductions
CompanyAccruals
CompanyTaxes

Under Employees I have:
EmployeeDeductions
EmployeeAccruals
EmployeeTaxes

Now my question is how should I setup my classes based on that information
above?
I originally thought about making Company the base Class and Have the
CompanyDeductions,Accruals and Taxes inherit the Company Class, but I'm not
sure thats the way to go. My other thought then became just having The
Deductions Accruals and Tax information as optional properties under the
company so that the Employees, which belong to companies could inherit the
company class.

How would you suggest I go about setting up my class structure?

Thanks so much for your help!
Ron
 
D

DeveloperX

This is a bit of a brainstorm, and raises a bunch of questions, so
don't look at it as an attempt at an answer, but some ideas and
thoughts.
It isn't clear from your post whether companies contains company
classes, I'll assume it does, if not just disregard that bit.
So Companies is a collection of company objects, Employees is a
collection of Employee objects.
It also isn't clear whether you want the employee to have deductions as
well as other things (like a name, ss number, etc) I'll assume you do.
If not I think revisiting the names might be in order.

So, An employee has deductions, accruals and taxes as does a company.
When you look at it, those three things are all financial records, so
it might be sensible to have a FinancialTransaction class which you
could derive into accruals/deductions and taxes. It depends on how
different they are, if each is represented as say a description, code
and amount then you can do away with three classes and simply add a
TransactionType to FinancialTransaction.
Is there any difference between an accrual for a company and an
employee (besides the numbers being bigger)? If so, maybe a derive from
FinancialTransaction creating EmployeeFinancialTransaction and
CompanyFinancialTransaction.
Will the company's transactions be driven by the employee transactions?
I.e. will you be adding up all the employee accruals and adding them to
the company's deductions?

So if you have a think about how the objects will interact and whether
the names reflect what the objects do, you will get a better idea I
think.
 
R

RSH

DeveloperX,

Thanks for this very thought provoking response.

I should have delved a little deeper into the objects to cast light...

Companies would be a collection of Company objects
Company Deductions, CompanyAccruals and CompanyTaxes contain meta data that
apply to all employees who are assigned these items

There are similarities but they are different enough to warrant seperate
objects I believe. They would contain different methods for calculations
and different properties shortly after dropping below the surface.

With that being said the Employees indeed have employeeDeductions which
would tie to the CompanyDeductions. The employee Deductions would have
rate, percent, pretax etc.

I drafted up a quick model ... using vb .net...sorry about that but I found
if you ask OOP questions in the VB group you dont get any responses)

Is this a bad practice to reference other objects from within an object?

Module Module1

Sub Main()

Dim Company1 As New Company("00000001", "Rons Test Co.", "12-3456789")

Dim Company2 As New Company("00000002", "Bills House of Bugs", "98-3456789")

Company1.AddDeduction("401k", "Company 401k Program")

Company1.AddDeduction("Uniform", "Company Uniforms")

Company1.PrintDeductions()

Company2.PrintDeductions()

Console.ReadLine()

End Sub

End Module

Public Class Company

Private _CompanyID As String

Private _CompanyName As String

Private _FEIN As String

Private _CompanyDeductions As New System.Collections.ArrayList

Public Sub New(ByVal CompanyID As String, ByVal CompanyName As String, ByVal
FEIN As String)

_CompanyID = CompanyID

_CompanyName = CompanyName

_FEIN = FEIN

End Sub



Public Property CompanyID() As String

Get

Return _CompanyID

End Get

Set(ByVal value As String)

_CompanyID = value

End Set

End Property

Public Property CompanyName() As String

Get

Return _CompanyName

End Get

Set(ByVal value As String)

_CompanyName = value

End Set

End Property

Public Property FEIN() As String

Get

Return _FEIN

End Get

Set(ByVal value As String)

_FEIN = value

End Set

End Property

Public Sub AddDeduction(ByVal DeductionID As String, ByVal DeductionName As
String)

Dim cd As CompanyDeduction = New CompanyDeduction(DeductionID,
DeductionName)

_CompanyDeductions.add(cd)

End Sub

Public Sub PrintDeductions()

Console.WriteLine(vbCrLf)

If _CompanyDeductions.Count > 0 Then

Dim cd As CompanyDeduction

Console.WriteLine("Deduction ID" & vbTab & "Deduction Name")

Console.WriteLine("---------------------------------------")

For Each cd In _CompanyDeductions

Console.WriteLine(cd.DeductionID & vbTab & cd.DeductionName)

Next

Else

Console.WriteLine("No Deductions exist for this company")

End If

End Sub

End Class



NotInheritable Class CompanyDeduction

Private _DeductionID As String

Private _DeductionName As String

Public Sub New(ByVal DeductionID As String, ByVal DeductionName As String)

_DeductionID = DeductionID

_DeductionName = DeductionName

End Sub

Public Property DeductionID() As String

Get

Return _DeductionID

End Get

Set(ByVal value As String)

_DeductionID = value

End Set

End Property

Public Property DeductionName() As String

Get

Return _DeductionName

End Get

Set(ByVal value As String)

_DeductionName = value

End Set

End Property

End Class





NotInheritable Class CompanyAccrual

Private _AccrualID As String

Private _AccrualName As String

Public Sub New(ByVal AccrualID As String, ByVal AccrualName As String)

_AccrualID = AccrualID

_AccrualName = AccrualName

End Sub

Public Property AccrualID() As String

Get

Return _AccrualID

End Get

Set(ByVal value As String)

_AccrualID = value

End Set

End Property

Public Property AccrualName() As String

Get

Return _AccrualName

End Get

Set(ByVal value As String)

_AccrualName = value

End Set

End Property

End Class
 
J

Joanna Carter [TeamB]

"RSH" <[email protected]> a écrit dans le message de (e-mail address removed)...
|I am still trying to grasp the use of real world Objects and how to
| conceptualize them using a business scenerio.
|
| What I have below is an outline that I am wrestling with trying to figure
| out a class structure:\
|
| Top level Objects:
| Companies
| Employees
|
| Under Companies I have:
| CompanyDeductions
| CompanyAccruals
| CompanyTaxes
|
| Under Employees I have:
| EmployeeDeductions
| EmployeeAccruals
| EmployeeTaxes
|
| Now my question is how should I setup my classes based on that information
| above?
| I originally thought about making Company the base Class and Have the
| CompanyDeductions,Accruals and Taxes inherit the Company Class, but I'm
not
| sure thats the way to go. My other thought then became just having The
| Deductions Accruals and Tax information as optional properties under the
| company so that the Employees, which belong to companies could inherit the
| company class.
|
| How would you suggest I go about setting up my class structure?

My guess is that you are very new, as was I, to OO design and, like I did,
you see everything as being solved by inheritance :)

There are no obvious inheritance relationships in the classes which you
describe, however there are other relationships that need to be clarifying.

I would declare the following classes :

Company
Employee
Deduction
Accrual
Tax

Note that all the names are singular and that the names do not apparently
link to each other, as in EmployeeAccrual.

Can I suggest your classes might look something like this (sorry, but I
don't speak VB)

public class Deduction
{
private string id;

private string name;

public Deduction(string id, string name)
{
this.id = id;
this.name = name;
}

public string ID
{
get { return id; }
}

public string Name
{
get { return name; }
}
}

public class Company
{
private string id;

private string name;

private string fein;

private ArrayList deductions;

public Company(string id, string name, string fein)
{
this.id = id;
this.name = name;
this.fein = fein;
}

public string ID
{
get { return id; }
}

public string Name
{
get { return name; }
}

public string Fein
{
get { return fein; }
}

public void AddDeduction(Deduction deduction)
{
if (deductions == null)
deductions = new ArrayList();
deductions.Add(deduction);
}

public void PrintDeductions()
{
// not exactly the same code as yours for simplicity of example
if (deductions == null || deductions.Count == 0)
{
Console.WriteLine("No Deductions exist for this company")
return;

foreach (Deduction deduction in deductions)
Console.WriteLine(deduction.ID + deduction.Name);
}
}
}

Note that the properties are readonly; this is because you have designed the
constructor to initialise all the fields, therefore indicating that this is
the normal way to setup an instance and that the instance, once created
should be immutable.

The AddDeduction(...) method takes a Deduction instance rather than the
parameters to create one; passing parameters rather than an object indicates
that a Deduction may only be created by a Company and cannot exist outside
of the Company. Passing an object parameter indicates that the Deduction can
exist outside of the Company.

So now your test code should look something like this :

void Main()
{
Company company1 = new Company("00000001", "Rons Test Co.", "12-3456789");

Company company2 = new Company("00000002", "Bills House of Bugs",
"98-3456789");

Deduction deduction = new Deduction("401k", "Company 401k Program");

company1.AddDeduction(deduction);

deduction = new Deduction("Uniform", "Company Uniforms");

company1.AddDeduction(deduction);

company1.PrintDeductions();

company2.PrintDeductions();

Console.ReadLine();
}

As you can see, no inheritance is required.

Joanna
 
D

DeveloperX

I'm not sure the properties should be read only simply because of the
constructor signature. It might just be a way of saying an empty
Accrual has no meaning and shouldn't be allowed.
I also wouldn't agree that passing parameters rather than a concrete
object implies the object is for use only with in company as that would
invalidate any sort of factory method, but I do appreciate the logic as
it applies to this case.
I quite agree about inheritence though, it would be worth RSH
investigating interfaces as well. We've got three methods that
basically print a line of info to the screen. Each of the three could
perhaps implement an interface called IReport which returns a formatted
string, you could then run all the objects through the same print
routine. Whether that's sensible in this case is debatable, but I think
it would be a great way to see the benefit of interfaces in comparison
to inheritance.
 
R

RSH

Thanks to both of you. Joanna that makes total sense to me...and like you
eluded to I am new to the OOP design principals. I think I am (was) stuck
in a rut of forming class dependencies much like a database layout where
each table contains foreign key(s) to link them all up. I am having a hard
time not trying to force that same infrastructure on my poor little classes,
when in reality they are very different.

I needed to see how to structure them "correctly" in a working environment.

My other question that was answered below, is whether or not it was
acceptable to reference other objects from within an object. I see that
this is not only acceptable it is important.

My next question is now, how do I access a Deduction through the company
object?



thank you very much for your valuable insight!
Ron



I'm not sure the properties should be read only simply because of the
constructor signature. It might just be a way of saying an empty
Accrual has no meaning and shouldn't be allowed.
I also wouldn't agree that passing parameters rather than a concrete
object implies the object is for use only with in company as that would
invalidate any sort of factory method, but I do appreciate the logic as
it applies to this case.
I quite agree about inheritence though, it would be worth RSH
investigating interfaces as well. We've got three methods that
basically print a line of info to the screen. Each of the three could
perhaps implement an interface called IReport which returns a formatted
string, you could then run all the objects through the same print
routine. Whether that's sensible in this case is debatable, but I think
it would be a great way to see the benefit of interfaces in comparison
to inheritance.
 
R

RSH

WOW that is good stuff!

I implemented the structures Joanna suggested, and I see how it all ties
together, but at the same time can remain independent. I also see that this
style of implementation is used throughout the .Net framework. You can
disregard my last question, I see how to access or set any of the properties
or call any of the methods through the company object.

Thanks so much for the eye opener!
Ron


RSH said:
Thanks to both of you. Joanna that makes total sense to me...and like you
eluded to I am new to the OOP design principals. I think I am (was) stuck
in a rut of forming class dependencies much like a database layout where
each table contains foreign key(s) to link them all up. I am having a
hard time not trying to force that same infrastructure on my poor little
classes, when in reality they are very different.

I needed to see how to structure them "correctly" in a working
environment.

My other question that was answered below, is whether or not it was
acceptable to reference other objects from within an object. I see that
this is not only acceptable it is important.

My next question is now, how do I access a Deduction through the company
object?



thank you very much for your valuable insight!
Ron



I'm not sure the properties should be read only simply because of the
constructor signature. It might just be a way of saying an empty
Accrual has no meaning and shouldn't be allowed.
I also wouldn't agree that passing parameters rather than a concrete
object implies the object is for use only with in company as that would
invalidate any sort of factory method, but I do appreciate the logic as
it applies to this case.
I quite agree about inheritence though, it would be worth RSH
investigating interfaces as well. We've got three methods that
basically print a line of info to the screen. Each of the three could
perhaps implement an interface called IReport which returns a formatted
string, you could then run all the objects through the same print
routine. Whether that's sensible in this case is debatable, but I think
it would be a great way to see the benefit of interfaces in comparison
to inheritance.
 

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