Abrufen von Html-Daten in Klasse kapseln
-
Samstag, 28. April 2012 10:51
Hallo,
ich möchte das Abrufen einiger HTML-Daten in eine Klasse kapseln. Meine Frage ist, ob es besser ist, das Abrufen der Daten in den Konstruktor zu packen (VARIANTE 1) oder lieber eine Public Methode definieren und diese verwenden (VARIANTE 2)? Die Klasse mit den zwei Möglichkeiten habe ich unten aufgelistet:
Public Class Class1 Private m_Eigenschaft1 As String Public ReadOnly Property Eigenschaft1() As String Get Return m_Eigenschaft1 End Get End Property Private m_Eigenschaft2 As String Public ReadOnly Property Eigenschaft2() As String Get Return m_Eigenschaft2 End Get End Property ' Hier befinden sich weitere Eigenschaften Private m_Url As String Public Property Url() As String Get Return m_Url End Get Set(ByVal value As String) m_Url = value End Set End Property ' ************** ' * VARIANTE 1 * ' ************** Public Sub New(ByVal url As String) m_Url = url GetUrlData() End Sub Private Sub GetUrlData() If IsNothing(m_Url) Then Throw New ArgumentNullException("Url sollte nicht Null sein.") ElseIf m_Url.Length = 0 Then Throw New ArgumentException("Url sollte nicht leer sein.") End If ' Hier Daten aus Url ermitteln und Eigenschaften setzen End Sub ' ************** ' * VARIANTE 2 * ' ************** Public Sub New(ByVal url As String) m_Url = url End Sub Public Sub GetUrlData() If IsNothing(m_Url) Then Throw New ArgumentNullException("Url sollte nicht Null sein.") ElseIf m_Url.Length = 0 Then Throw New ArgumentException("Url sollte nicht leer sein.") End If ' Hier Daten aus Url ermitteln und Eigenschaften setzen End Sub End ClassGibt es vielleicht eine bessere Alternative?
Gruss,
LittleBlueBird
Alle Antworten
-
Samstag, 28. April 2012 19:33Beantworter
Hallo,
schau Dir System.Uri an, dort findest Du bereits eine vollständige Klasse, die u. a. HTTP abdeckt
(und deren teilweise diffizilen Besonderheiten). In den meisten Fällen fährt damit besser,
als mit einer eigenen Lösung, da sie von anderen .NET Methoden (z. B. WebClient) ebenfalls verwendet wird.Zum allgemeinen Teil, ob Eigenschaft oder Konstruktor:
Grundsätzlich kannst Du ab VB 2010 auch Eigenschaften mit gemischtem Zugriff erstellen, siehe
Gewusst wie: Deklarieren einer Eigenschaft mit gemischten Zugriffsebenen (Visual Basic)Damit kann Parameter im Konstruktor (Sub New) über die Eigenschaftszuweisung erstellen
somit man eine zusätzliche Methoden vermeiden kann - hier:
Verlagere die Tests aus GetUrlData in den Setter von Url.
Was die Ausnahmen angeht, so ist es immer etwas problematisch, wenn sie im Konstruktor auftreten,
da Du damit keine gültige Instanz hast.Gruß Elmar
- Als Antwort markiert LittleBlueBird Montag, 30. April 2012 08:54
-
Sonntag, 29. April 2012 08:50
Hallo Elmar,
besten Dank für Deine Antwort. Ich benutze bereits die HtmlAgilityPack Library, um die Html-Daten zu laden und zu parsen. System.Uri war nicht so leistungsfähig. Ausserdem verwende ich noch die Newtonsoft.Json Library, um die Javascript-Daten zu verarbeiten. Das alles passiert in der Methode GetUrlData.
Wenn ich Deine Erklärung richtig interpretiert habe, dann müsste ich in etwa folgende Klasse haben:
Public Class Class1 Private m_Eigenschaft1 As String Public ReadOnly Property Eigenschaft1() As String Get Return m_Eigenschaft1 End Get End Property Private m_Eigenschaft2 As String Public ReadOnly Property Eigenschaft2() As String Get Return m_Eigenschaft2 End Get End Property ' Hier befinden sich weitere Eigenschaften Private m_Url As String Public Property Url() As String Get Return m_Url End Get Private Set(ByVal value As String) If IsNothing(value) Then Throw New ArgumentNullException("Url sollte nicht Null sein.") ElseIf value.Length = 0 Then Throw New ArgumentException("Url sollte nicht leer sein.") Else m_Url = value End If End Set End Property Public Sub New(ByVal url As String) Me.Url = url End Sub Public Sub GetUrlData() ' Hier Daten aus Url ermitteln und Eigenschaften setzen End Sub End ClassIn diesem Fall kann ich keinen parameterlosen Konstruktor mehr verwenden. Demzufolge kann ich die Url nicht mehr über die Eigenschaft sondern lediglich über den parametrierten Konstruktor setzen. Meines Erachtens ist es besser, wenn ich den Setter auch als Public definiere. Ich kann ihn immer noch im Konstruktor verwenden und gleichzeitig direkt setzen, so wie unten aufgeführt:
Public Class Class1 Private m_Eigenschaft1 As String Public ReadOnly Property Eigenschaft1() As String Get Return m_Eigenschaft1 End Get End Property Private m_Eigenschaft2 As String Public ReadOnly Property Eigenschaft2() As String Get Return m_Eigenschaft2 End Get End Property ' Hier befinden sich weitere Eigenschaften Private m_Url As String Public Property Url() As String Get Return m_Url End Get Set(ByVal value As String) If IsNothing(value) Then Throw New ArgumentNullException("Url sollte nicht Null sein.") ElseIf value.Length = 0 Then Throw New ArgumentException("Url sollte nicht leer sein.") Else m_Url = value End If End Set End Property Public Sub New() End Sub Public Sub New(ByVal url As String) Me.Url = url ' Hier weise ich den Wert der Eigenschaft zu statt der Membervariablen End Sub Public Sub GetUrlData() ' Hier Daten aus Url ermitteln und Eigenschaften setzen End Sub End ClassDie Ausnahmen betreffend gebe ich Dir vollkommen Recht. Wobei ich schon Klassen gesehen habe, die im Konstruktor eine Ausnahme auslösen. Ich habe mir das abgeschaut und bei mir dann verwendet in der Annahme, es sei korrekt.
Gruss LittleBlueBird
EDIT: Jetzt habe ich kapiert, was Du mit "zusätzliche Methode vermeiden" meintest. Ich soll nicht nur die Tests auf Null und Leerstring in den Setter verlagern, sondern auch die Datenermittlung und das Setzen der Eingeschaft1,2,...
- Bearbeitet LittleBlueBird Montag, 30. April 2012 08:58 Ergänzung

