В данный момент я пытаюсь создать своего рода модель в vb.net, который может использоваться для создавания/выбирания записей базы данных.
Я создал основной класс Модель с общей функцией для выборки наборов данных, например, Model.find (). Теперь я хотел бы создать Классы, которые наследовали основной Образцовый Класс, например, отдельный для пользователей: UserModel.find () => "ВЫБИРАЮТ * ОТ пользователей".
В чем я нуждаюсь, теперь должен найти способ сказать Класс, какую таблицу он должен использовать. Я думал об абстрактной Строке "таблица", которая является константой в каждой "дочерней модели", но как это могло быть реализовано, поскольку не возможно переопределить совместно использованных участников?
Заранее спасибо!
Править: Возможно, это сделает это немного более ясным, что я имею в виду:
Public Class Model
Public Shared _controller As Controller
Public Shared table As String
Protected Shared tableFields As String()
Shared reader As Npgsql.NpgsqlDataReader
Public Shared Function find()
Dim a As ArrayList = New ArrayList
'Test if the tablefields are already known to the class, if not, get them
If tableFields Is Nothing Then
getTableFields()
End If
Dim query As String = "SELECT " + String.Join(", ", tableFields) + " FROM " + table
reader = _controller.executeReader(query)
While reader.Read
o = New Model
Dim v As New Hashtable
For Each field In tableFields
v(field) = reader(field)
Next
o.values = v
a.Add(o)
End While
reader.Close()
Return DirectCast(a.ToArray(GetType(Model)), Model())
End Function
Public values As Hashtable
Public Sub New()
End Sub
End Class
Таким образом, я хочу общий метод, который находит все записи базы данных и отдает массив экземпляров его собственного типа, например, Модель (). Вот почему я хотел сохранить находить-метод совместно использованным и не связанный к экземпляру.
Я думаю, вы могли бы использовать Generics
. Здесь я вставил пример
Все классы в вашем домене могут наследоваться от Entity class
Public MustInherit Class Entity
'...
End Class
Вашего Model class, с вашим методом Find
Public Class Model
Public Shared Sub Find(Of T As Entity)()
' You could know the name of T to find the table
Dim tableName As String = GetType(T).Name
'...
End Sub
End Class
Один класс вашего домена, например: Класс пользователя
Public Class User
Inherits Entity
' ...
End Class
И, наконец, пример как вы можете инстанцировать метод Find
Model.Find(Of User)()
'...
Не знаю, то ли это, что вы имеете в виду, вы находите это полезным?
Вы можете сделать свой главный класс абстрактным, и каждый подкласс должен будет возвращать "свое" имя таблицы через свою собственную реализацию (например, getTableName
). Таким образом, вам придется поддерживать логику метода только в главном классе.
Общие (статические) объекты или члены объекта не могут быть унаследованы или переопределены. Наследование предназначено для экземпляра объекта. Поскольку вам не нужно инстанцировать статический класс, вы не можете наследоваться от него. То же самое с методами. Статический метод не должен быть виртуальным (переопределяемым в VB), поскольку он определяет метод, выполняющий задачи без экземпляра класса. Тогда это делает невозможным использование полей или свойств экземпляра внутри статического метода (Shared в VB). Это плохая попытка проектирования.
На самом деле, каждый статический (Shared) класс должен быть помечен как NotInheritable в VB, и определять только пустой конструктор по умолчанию. Это утечка из VB в отношении концепций ООП.
В таких случаях принято использовать паттерн проектирования Singleton: создать метод экземпляра, переопределяемый наследующими классами. В каждом наследуемом классе этот метод должен возвращать объект Singleton, связанный с этим классом.
Вот один из способов сделать это:
MustInherit Class BaseClass
Public MustOverride Function getTableName() As String
End Class
Class Class1
Inherits BaseClass
Private Shared TableName As String = "myTable1"
Public Overrides Function getTableName() As String
Return TableName
End Function
End Class
Class Class2
Inherits BaseClass
Private Shared TableName As String = "myTable2"
Public Overrides Function getTableName() As String
Return TableName
End Function
End Class
EDIT: совершенно другой подход. Вы можете заставить базовый класс хранить некоторый словарь, который связывает типы классов (или имена типов) с правильной таблицей:
Class BaseClass
Private Shared myDictionary As New Collections.Generic.Dictionary(Of Type, String)
Friend Shared Sub RegisterType(ByVal childType As Type, ByVal tableName As String)
myDictionary.Add(childType, tableName)
End Sub
Public Shared Function getTableName(ByVal childType As Type) As String
Return myDictionary.Item(childType)
End Function
End Class
Class Class1
Shared Sub New()
BaseClass.RegisterType(GetType(Class1), "table1")
End Sub
End Class
Class Class2
Shared Sub New()
BaseClass.RegisterType(GetType(Class2), "table2")
End Sub
End Class