Learning OOP conceptual question

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?

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 below...

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

Thanks so much for your help!
Ron



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")

Company2.AddAccrual("Sick", "Sick")

Company2.AddAccrual("Vacation", "Vacation")

Company1.Print("Deductions")

Company2.Print("Accruals")

Console.ReadLine()

Company1.SetDeductionRate("401k", 23.45)

Company1.Print("Deductions")

End Sub

End Module

Public Class Company

Private _CompanyID As String

Private _CompanyName As String

Private _FEIN As String

Private _CompanyDeductions As New Hashtable

Private _CompanyAccruals As New Hashtable

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(DeductionID, cd)

End Sub

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

Dim ca As CompanyAccrual = New CompanyAccrual(AccrualID, AccrualName)

_CompanyAccruals.Add(AccrualID, ca)

End Sub

Public Sub SetDeductionRate(ByVal DeductionID As String, ByVal Rate As
Double)

Dim cd As CompanyDeduction

cd = _CompanyDeductions(DeductionID)

cd.Rate = Rate

End Sub

Public Sub Print(ByVal type As String)

Console.WriteLine(vbCrLf)

Dim al As New Hashtable

Dim i As Integer

Console.WriteLine("CompanyId:" & _CompanyID & " CompanyName:" &
_CompanyName)

Select Case Type

Case "Deductions"

al = _CompanyDeductions

Case "Accruals"

al = _CompanyAccruals

End Select

If al.Count > 0 Then

Console.WriteLine(type & " ID" & vbTab & type & " Name" & vbTab & " Rate")

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

Dim myEnumerator As IDictionaryEnumerator = al.GetEnumerator()

While myEnumerator.MoveNext()

Console.WriteLine("{0} : {1}", myEnumerator.Value(0))

End While

Else

Console.WriteLine("No " & Type & " exist for this company")

End If

End Sub

End Class



NotInheritable Class CompanyDeduction

Private _ID As String

Private _Name As String

Private _Rate As Double

Public Sub New(ByVal ID As String, ByVal Name As String)

_ID = ID

_Name = Name

End Sub

Public Property ID() As String

Get

Return _ID

End Get

Set(ByVal value As String)

_ID = value

End Set

End Property

Public Property Name() As String

Get

Return _Name

End Get

Set(ByVal value As String)

_Name = value

End Set

End Property

Public Property Rate() As Double

Get

Return _Rate

End Get

Set(ByVal value As Double)

_Rate = value

End Set

End Property

End Class





NotInheritable Class CompanyAccrual

Private _ID As String

Private _Name As String

Private _Rate As Double

Public Sub New(ByVal ID As String, ByVal Name As String)

_ID = ID

_Name = Name

End Sub

Public Property ID() As String

Get

Return _ID

End Get

Set(ByVal value As String)

_ID = value

End Set

End Property

Public Property Name() As String

Get

Return _Name

End Get

Set(ByVal value As String)

_Name = value

End Set

End Property

Public Property Rate() As Double

Get

Return _Rate

End Get

Set(ByVal value As Double)

_Rate = value

End Set

End Property

End Class
 
C

chris.nebinger

I"m not sure I understand the business practice. Are you doing
accounting/finance?

Two approaches came to mind. The first is to use a interface to
implement required features, and have the interface expose Deductions,
Accurals, and Taxes.

Or, you could also have a Deduction(s) Class, Accural(s) Class, and
Tax(es) Class, then :


Class Company
Public Deductions as New Deductions
Public Accurals as New Accurals
Public Taxes as New Taxes
End Class


Repeat for employees.

Assuming that Deductions is a collection class with a .Add method, then
:


Dim c as New Company
c.Deductions.Add (New Deduction("401K", "401K Program")



Chris
 
C

Cor Ligthert [MVP]

RSH,

Creating classic data classes is only a partial thing of OO, what is not
direct OOP.

And because of the fact that those classic dataclasses are mostly useless in
dotNet, I would take more an eye on using the full OOP implementing classes
from AdoNet which are related to SQL implementing databases.

Just my thought,

Cor
 
R

RSH

I am struggling with interfaces. I am intrigued by that option that you put
out. Would it be possible for you to do a quick code sample of how I might
set that up?

My business practice is payroll in this exersize...but I am more or less
just trying to learn OOP principals that apply to my own class structures.

Thanks for the insight!
ron
 
R

RSH

Cor,

Is there an article or series of articles that you would reccomend to alter
my thinking on the subject?

I will definitely admit I am new to OOP principals and while I have been
programming heavily with databases for a number of years it is a very
difficult thing to unleash the datacentric tendencies that I have. I
suppose the fact that pretty much every tutorial I see relates objects to
real world objects (dogs, cats, animals etc.) that I am taking it too
literally by implementing objects at face value.

I would love for you to elaborate a bit more as this sort of conceptual
discussions is very enlightening.

Thanks!
Ron
 
R

RobinS

If you want to understand how the business object logic
works with OO, I recommend "Understanding Objects in VB"
by Deborah Kurata. She has a VB2005 version coming out in
January or February. It really gave me the understanding
I needed to build an application by starting with the
classes and then doing the UI, etc.

She has a VB6 version of the book -- there are some for
sale on Amazon for 50 cents + shipping. This would certainly
give you the general idea, and be fairly painless. I would
definitely check out her book when it comes out early
next year.

Just an idea.

Robin S.
 
C

Cor Ligthert [MVP]

RSH,

The OOP is based on creating objects from pre defined classes *every time*
you need to do something.
Those can be your own classes, but in dotNet mostly it are those given to
you by the framework.

That opposite to the modular model where you create a big program with in
fact everything all the time predefined in it.

Just start, try to avoid modules, static classes, structures and declare
things global and you will see that you are quickly busy with OOP
programming as you are using VB.Net.

VB.Net has not any thing in it, to prevent you doing this (beside the crazy
C# type warnings in the version 2005)..

For others, with this I don't say that you should forever not use those
things I wrote to avoid, it is just to learn the concepts of OOP.

Cor
 
C

Cor Ligthert [MVP]

It can be read in another way, therefore read that part of the text as


Try to avoid all things as modules, static classes, structures and declaring
things globaly

Cor
 
D

Daniel

Why is it best to avoid Modules and Structures? I just finished a
VB.NET class and those two components seemed to me to be very useful
and commonly used.

Thanks,
Daniel
 
C

Cor Ligthert [MVP]

Daniel,

Read my message complete (the original one), I did not write what you said I
wrote.

Cor
 
J

Jay B. Harlow

Daniel,
Modules can "pollute" the "global" namespace. They allow you to use methods
& properties unqualified making it hard to know where those methods &
properties originate from.

Public Module UtilityModule
Public Function Create() As Something
End Function
End Module

When ever you use "Create" in an expression is not readily apparent where
the method came from...

Dim x As Something = Create()

Generally I use static/shared classes instead of Modules.

Public NotInheritable Class UtilityModule
Private Sub New()
End Sub

Public Shared Function Create() As Something
End Function
End Class

Now its readily apparent that Create is in the UtilityModule.

Dim x As Something = UtilityModule.Create()


There are cases where I prefer Modules over static/shared classes, where the
methods of said type are truly global; for example System.Math. Luckily you
can treat any class as a module by importing that class.

Imports System.Math

x = Sin(y) * Cos(z)

As opposed to:

x = Math.Sin(y) * Math.Cos(z)


Structures are used for defining Value Types where as Classes are used for
defining Reference Types. Each have their respective roles in .NET.
Generally I create reference types unless I know I need a value type. I know
I need a value type when I have a type that meets most or all of the
following criteria:
- Act like primitive types
- Have an instance size under 16 bytes
- Are immutable
- Value semantics are desirable

http://msdn.microsoft.com/library/d...genref/html/cpconValueTypeUsageGuidelines.asp


--
Hope this helps
Jay B. Harlow
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


Daniel said:
Why is it best to avoid Modules and Structures? I just finished a
VB.NET class and those two components seemed to me to be very useful
and commonly used.

Thanks,
Daniel
<<snip>>
 
C

Cor Ligthert [MVP]

Jay,

A little addition to your message from my point of view, because I like
currently a *good* written module.
Modules can "pollute" the "global" namespace. They allow you to use
methods & properties unqualified making it hard to know where those
methods & properties originate from.

But that is not necessary, if you write a module as a class, they look very
nice, I prefer since short a good written module above a static/shared
class.

A bad written module has all that as Jay decribes in my opinion.

Cor
 

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