.NET Forum / Languages / C# / November 2006
Learning OOP conceptual question(s)
|
|
Thread rating:  |
RSH - 08 Nov 2006 15:36 GMT 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
DeveloperX - 08 Nov 2006 16:13 GMT 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.
> I am still trying to grasp the use of real world Objects and how to > conceptualize them using a business scenerio. [quoted text clipped - 29 lines] > Thanks so much for your help! > Ron RSH - 08 Nov 2006 16:35 GMT 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
> 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 [quoted text clipped - 62 lines] >> Thanks so much for your help! >> Ron Joanna Carter [TeamB] - 08 Nov 2006 22:44 GMT |I am still trying to grasp the use of real world Objects and how to | conceptualize them using a business scenerio. [quoted text clipped - 26 lines] | | 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
 Signature Joanna Carter [TeamB] Consultant Software Engineer
DeveloperX - 09 Nov 2006 10:20 GMT 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.
> |I am still trying to grasp the use of real world Objects and how to > | conceptualize them using a business scenerio. [quoted text clipped - 162 lines] > > Joanna RSH - 09 Nov 2006 13:37 GMT 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.
Joanna Carter [TeamB] wrote:
> "RSH" <way_beyond_oops@yahoo.com> a écrit dans le message de news: > uImm3u0AHHA.3540@TK2MSFTNGP03.phx.gbl... [quoted text clipped - 173 lines] > > Joanna RSH - 09 Nov 2006 14:23 GMT 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
> 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 [quoted text clipped - 213 lines] >> >> Joanna
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|