Das Factory-Pattern

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Wenn Sie mit der Verwendung von Interfaces vertraut sind und diese anwenden, um verschiedene Implementierungen einer Klasse einzusetzen, fehlt nur noch ein kleiner Schritt zur Entkopplung des aufrufenden Codes zu den genutzten Klassen. Dieser Beitrag zeigt, wie Sie das Factory-Pattern für die Erzeugung beliebiger Implementierungen einer Schnittstelle nutzen, ohne dass die aufrufende Prozedur einen Bezug zu dieser Implementierung hat.

Der Beitrag Schnittstellenvererbung (www.access-im-unternehmen.de/734) zeigt am Beispiel des Versands einer E-Mail, wie Sie eine Schnittstelle beziehungsweise ein Interface nutzen können, um eine von mehreren konkreten Implementierungen dieses Interfaces zu verwenden.

Der Aufbau des dortigen Beispiels besteht aus einer Interface-Klasse namens ISendMail, welche die in einer Implementierung der SendMail-Klasse zu verwendenden Elemente, also Eigenschaften und Methoden, vorgibt (s. Listing 1).

Listing 1: Beispiel für eine Interface-Klasse

Public Property Let Sender(strSender As String)
End Property
Public Property Let Recipient(strRecipient As String)
End Property
Public Property Let Subject(strSubject As String)
End Property
Public Property Let Body(strBody As String)
End Property
Public Function SendMail() As Boolean
End Function

Eine konkrete Implementierung sieht dann wie in Bild 1 aus. Es kann gleich mehrere Klassen dieser Art geben, zum Beispiel clsSendSMTPMail oder clsSendOutlookMail. Gründe dafür, mehrere gleichartige Implementierungen in ein Projekt einzubauen, gibt es viele: So können Sie beispielsweise eine Klasse zum Versenden von E-Mails via Outlook vorsehen, die immer dann eingesetzt wird, wenn auf dem Rechner, auf dem die Datenbankanwendung eingesetzt wird, Outlook vorhanden ist. Ist kein Outlook installiert, soll die E-Mail über den direkten Kontakt zum SMTP-Server verschickt werden, der beispielsweise mit den Methoden der WinSock-Klasse hergestellt werden kann.Die Outlook-Methode wäre jedoch zu bevorzugen, weil der Benutzer die versendeten Mails hier jederzeit im Ordner der gesendeten Objekte nachhalten könnte.

pic001.png

Bild 1: Implementierung einer Schnittstelle

Um die Verwendung der Klassen zu vereinfachen, nutzen wir beispielsweise eine Prozedur, die nur die Parameter für den Mail-Versand und die Angabe der Versandart erwartet. Diese deklariert alle möglichen Mail-Klassen und instanziert dann die jeweils benötigte (s. Listing 2).

Listing 2: Konkrete Instanzierung von E-Mail-Klassen

Public Sub MailVersenden(strAbsender As String, strEmpfaenger As String, strBetreff As String, _
        strInhalt As String, strVersandart As String)
    Dim objSendSMTPMail As clsSendSMTPMail
    Dim objSendOutlookMail As clsSendOutlookMail
    Select Case strVersandart
        Case "SMTP"
            Set objSendSMTPMail = New clsSendSMTPMail
            With objSendSMTPMail
                .Sender = strAbsender
                ''... weitere Zugriffe auf die Klasse
            End With
        Case "Outlook"
            Set objSendOutlookMail = New clsSendOutlookMail
            With objSendOutlookMail
                .Sender = strAbsender
                ''... weitere Zugriffe auf die Klasse
            End With
    End Select
End Sub

Wenn wir statt mehrerer Objektvariablen für jede der konkreten Klassen nur eine Objektvariable namens objSendMail mit dem Datentyp der Schnittstelle ISendMail deklarieren, können wir der Objektvariablen objSendMail beim Instanzieren die jeweils benötigte Klasse zuweisen (s. Listing 3).

Listing 3: Verwenden einer Schnittstelle

Public Sub MailVersenden(strAbsender As String, strEmpfaenger As String, strBetreff As String, _
        strInhalt As String, strVersandart As String)
    Dim objSendMail As ISendMail
    Select Case strVersandart
        Case "SMTP"
            Set objSendMail = New clsSendSMTPMail
        Case "Outlook"
            Set objSendMail = New clsSendOutlookMail
    End Select
    With objSendMail
        .Sender = strAbsender
        ''... weitere Zugriffe auf die Klasse
    End With
End Sub

Dies spart eine Menge Code und somit Wartungsaufwand ein, denn wir haben nicht mehr zwei Objektvariablen, für die wir entsprechend auch alle nötigen Eigenschaftszuweisungen und Methodenaufrufe programmieren müssen, sondern wir haben nur noch eine Objektvariable, die je nach Bedarf gefüllt wird und die Zugriffe auf die Eigenschaften und Methoden an die tatsächliche Implementierung weiterreicht.

Es fehlt jedoch noch ein entscheidender Schritt, denn die Beispielprozedur MailVersenden ist immer noch nicht nur von der Schnittstellenklasse ISendMail, sondern auch noch von deren Implementierungen clsSendOutlookMail und clsSendSMTPMail abhängig: Immerhin werden diese noch per New instanziert und objSendMail zugewiesen.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar