OO & Interface question

G

Guest

Hi,

I am kind of new to OO and I have the following problem :

I have a class containing a huge list of functions for accessing an SQL
database.
Public Class Transaction
#region "Client"
Public function GetClientInfos() as Dataset ...
Public sub InsertClientInfos() ...
#end region
#region "Employe"
Public function GetEmployeInfos() as Dataset ...
Public sub InsertEmployeInfos() ...
#end region
...
End Class

However now, those functions could optionnaly call web services instead of
direct sql requests. I thougt of doing something like this, using and
Interface :

Public Interface ITransaction
function GetClientInfos() as Dataset
sub InsertClientInfos()
function GetEmployeInfos() as Dataset ...
sub InsertEmployeInfos() ...
...
End Interface

Public Class TransactionSQL
Implements ITransaction
....
End Class

Public Class TransactionWeb
Implements ITransaction
....
End Class

A call to an instance of this Interface would look like :
Dim transaction as ITransaction
transaction = new TransactionSQL
dgClient.Datasource = transaction.GetClientInfos()


Since there a LOT of functions, I'ld really like to be able to use my
ITransaction Interface, but by adding levels to it. So a call to an
ITransaction instance would look like :

Dim transaction as ITransaction
transaction = new TransactionSQL
dgClient.Datasource = transaction.Client.GetInfos()
dgEmploye.Datasource = transaction.Employe.GetInfos()

How should I implement my classes and interfaces to be able to call my
procedure like that???

Hope it was clear enough
Thx
 
G

Guest

Not really into interfaces so can't really answer your question but my
compliments on your question as it's one of the best examples of where
interfaces are useful. I have a windows application that I want to later
port to a web site and I wish I'd thought of this technique for my database
access class. Looking forward to the replies you get.
 
C

Cor Ligthert [MVP]

Dennis,

I don't expect many replies on this.

In my opinion is it to complex to give and goes wrong in maintainability to
give it a change on a life.

A baby born with ten hearts.

However just my idea.

Cor
 
G

Guest

I have a class containing a huge list of functions for accessing an SQL
database.
Public Class Transaction
#region "Client"
Public function GetClientInfos() as Dataset ...
Public sub InsertClientInfos() ...
#end region
#region "Employe"
Public function GetEmployeInfos() as Dataset ...
Public sub InsertEmployeInfos() ...
#end region
...
End Class

However now, those functions could optionnaly call web services instead of
direct sql requests. ....
Since there a LOT of functions, I'ld really like to be able to use my
ITransaction Interface, but by adding levels to it. So a call to an
ITransaction instance would look like :

Dim transaction as ITransaction
transaction = new TransactionSQL
dgClient.Datasource = transaction.Client.GetInfos()
dgEmploye.Datasource = transaction.Employe.GetInfos()

If I understand this correctly, you have two types of info (client and
employee, and maybe more to follow) and you have two types of access (sql and
web, and maybe more to follow). You have a big list of functions (GetInfos,
InsertInfos, and many more) that apply to all types of info and types of
access. You would like to freely mix and match info and access - you need to
call GetInfos for a client via sql or the net, and ditto for employee.
Furthermore, the list of functions is broadly the same for all mix and match
cases (not necessarily identical, but similar).

If the above is generally a correct assessment, then I urge you to drop
interfaces and use class inheritence instead. The documentation uses the
terms abstract and concrete, so I will too. You write an abstract base class
that serves the purpose of your interface and does other things as well.
Then you write a concrete class that inherits from the abstract class and
provides specific functionality for client via sql. You write another
concrete class for client via net. Dito for employee. The class hierarchy
looks something like this:

TransactionBase
TransactionEmployeeSql
TransactionEmployeeNet
TransactionClientSql
TransactionClientNet

In TransactionBase, you provide a Create function that instantiates one of
the concrete classes and returns it cast as TransactionBase. In you code,
you declare a variable of type TransactionBase, but once instantiated, it is
really one of the concrete classes, something like this:

Dim How as string
' set how to "Sql" or "Net" depending on what your program is doing
' maybe at program start, you decide on Sql or Net?
Dim cl As TransactionBase = TransactionBase.Create("client", How)
cl.InsertInfos() ' does a client InsertInfos via Sql or Net

A sample of how to do all of this is as follows:

Public MustInherit Class TransactionBase ' abstract base class

Protected Sub New()
' abstract types are not instantiated and should not have constructors
End Sub

Public MustOverride Function GetInfos() As Integer ' should be As DataSet
Public MustOverride Sub InsertInfos()

Public SomeVariable as Integer ' a name common to all concrete classes
Public CreateType As String = "" ' how this instance was created, a debug
assist

Public Shared Function Create(ByVal Who As String, ByVal How As String) As
TransactionBase
' return a reference to a new TransactionBase subclass
Dim z As TransactionBase = Nothing
Dim CreateType As String = LCase(Who & "." & How)
Select Case LCase(Who & "." & How)
Case "employee.sql"
z = New TransactionEmployeeSql
Case "employee.net"
z = Nothing
Case "client.sql"
z = Nothing
Case "client.net"
z = Nothing
Case Else
Debug.Assert(False)
End Select
z.CreateType = CreateType
Return z
End Function

Public Sub UtilitySub()
' some function that is common to all subclasses
' may be shared or not
End Sub

End Class

Public Class TransactionEmployeeSql ' ditto for empnet, clientsql, clientnet
Inherits TransactionBase

Public Overrides Function GetInfos() As Integer
' whatever
End Function

Public Overrides Sub InsertInfos()
' whatever
End Sub

End Class

Public Module Sample
Public Sub test()
Dim x As TransactionBase = TransactionBase.Create("employee", "net")
x.GetInfos()
x.InsertInfos()
End Sub
End Module
 
G

Guest

That is a pretty smart way to do it. Many thx for your input. (sigh) But I
wish I could use interfaces one of these days. Each time I try to do it, I
end up using class inheritance instead.

Oh well, it'll have to wait for another day I guess!!!
 
G

Guest

Actually I think the initial interface would simplify my life considerably.

I am just trying to enhance it so it would be simpler to use and more
intuitive for the consumer of the class.

But I guess sometimes, you can make things more complex while trying to make
them simpler :)
 

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