1
\$\begingroup\$

While working on my demo database manager app, I have coded a previously presented Storage Library. The structure of the library's code and employed design patterns partially follow that of the Secure ADODB project, which was a great help. For instance, I liked its approach to parametrized class instantiation involving the factory design pattern and predeclared classes, but I used a slightly modified approach.

The relevant part of the DataTableADODB class is:

'@PredeclaredId

Implements IDataTableStorage

Private Type TDataTableADODB
    Model As DataTableModel
    SQL As SQLlib
    ADO As ADOlib
    AdoCommand As ADODB.Command
    AdoRst As ADODB.Recordset
    ConnectionString As String
    TableName As String
    FieldNames() As String
    FieldTypes() As ADODB.DataTypeEnum
    FieldMap As Scripting.Dictionary
    IDs As Variant
    TypeCast As FieldFormat
End Type
Private this As TDataTableADODB


Public Function Create(ByVal Model As DataTableModel, _
                       ByVal ConnectionString As String, _
                       ByVal TableName As String) As DataTableADODB
    Dim Instance As DataTableADODB
    Set Instance = New DataTableADODB
    Instance.Init Model, ConnectionString, TableName
    Set Create = Instance
End Function


Friend Sub Init(ByVal Model As DataTableModel, _
                ByVal ConnectionString As String, _
                ByVal TableName As String)
    Guard.NullReference Model
    Guard.EmptyString ConnectionString
    
    Set this.Model = Model
    Set this.SQL = SQLlib.Create(TableName)
    Set this.ADO = ADOlib.Create
    If LCase$(Left$(ConnectionString, 7)) = SQLITE_CONNSTR_PREFIX Then
        this.ConnectionString = this.ADO.GetSQLiteConnectionString(ConnectionString)("ADO")
    Else
        this.ConnectionString = ConnectionString
    End If
    this.ADO.SetConnectionString this.ConnectionString
    this.TableName = TableName
    
    this.ADO.GetTableMeta this.TableName, this.FieldNames, this.FieldTypes, this.FieldMap
End Sub

The class implements the IDataTableStorage interface and encapsulates a set of private attributes. It defines a conventionally named factory method Create used for parameterized object instantiation. Here, Create is defined as a Public Function (it should return the new instance), which only news the class (creates an uninitialized instance) and calls the constructor Init on the new instance. Init, having the same parameter signature as Create, is a Sub responsible for initialization and input validation. Init is only called once (from Create), but it needs to be at least Friend to be accessible from the factory.

Another interesting matter is whether the factory should return the default interface (DataTableADODB) or the implemented interface (IDataTableStorage). My understanding is that, in general, there is only a subtle difference. One particular example is when, after creation, a method is called on the implemented interface of the new object, and then it is discarded. If the factory returns the implemented interface, then the calls can be chained. Otherwise, the calling code is responsible for switching the interface and must assign the new object reference to a local variable before such a call.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.