Strukturierter Aufbau in der ASP-Programmierung
Geschrieben von: Rene Drescher-Hackel Im heutigen Artikel möchte ich Ihnen zeigen, daß es sinnvoll sein kann, seinen ASP-Dateien mehr "Struktur" zu verleihen. Der Artikel wird Ihnen zeigen, wie Sie selbst bei übermäßig vielen Programmzeilen immer noch den Überblick behalten. In meiner täglichen Praxis erlebe ich immer wieder, wie wichtig es ist, sauber und übersichtlich zu programmieren. Fast jeder von Ihnen wird immer öfter mit Arbeiten konfrontiert, die vor Monaten - oder Jahren - einmal fertiggestellt wurden. Wer will da noch die genauen Überlegungen kennen, die einst bei der Scripterstellung leitend waren. ASP-Einsteigern soll der Artikel dazu dienen, von Anfang an auf eine saubere und übersichtliche Programmierung zu achten und zeigen, wie man dies unter anderem erreichen kann. Allgemeiner Aufbau der SeiteDer erste Eintrag auf der ASP-Seite ist <%@ Language=VBScript %> wenn VBScript die von Ihnen bevorzugte Script-Sprache ist. Sie sollten auf gar keinen Fall die erste Zeile umbrechen und innerhalb der ersten Begrenzungszeichen weiteren Code unterbringen. Dies führt regelmäßig zu folgender Fehlermeldung: Active Server Pages- Fehler 'ASP 0221' Ungültige @ Kommandozuweisung Als nächstes folgen daher wieder die typischen Script-Begrenzungszeichen: <% ... %> Innerhalb dieser Begrenzungszeichen steht dann der eigentliche Code. Ihr nächster Eintrag sollte dann die Anweisung Option Explicit sein. Diese Anweisung "zwingt" Sie dazu, daß Sie Ihre im Script später benutzten Varaiablen vor ihrer ersten Verwendung deklarieren, also bekannt machen. Dies macht aus zweierlei Gründen Sinn: Zum einen wissen Sie beim ersten Lesen Ihres Scriptes später, welche Variablen Sie alle benutzen. Zum anderen ist der Zugriff auf deklarierte Variablen schneller, da hier über die Ordinalzahl (der Variable) auf sie zugegriffen wird, während im anderen Fall über den Varaiablennamen der Zugriff erfolgt. Die Variablendeklarationen können dabei mit Private | Public | Dim Variablenname erfolgen. Es empfiehlt sich dabei, die einzelne Anweisung gleichzeitig zu kommentieren: Dim strName ' Name des Benutzers Ein weiterer Punkt ist die Namensgebung bei der Variablenbenennung. Ich empfand es bislang als äußerst hilfreich, den von mir in der Variable erwarteten Variablentyp im Namen mit anzugeben. Wenn also der Typ "String" erwartet wird, dann wurde dem Variablennamen das Kürzel "str" voran gestellt. Beim Typ "Integer" dann "int", bei "Boolean" dann "bln" und so weiter. Darüber hinaus sollten Sie sich angewöhnen, sinnvolle Namen als Bezeichnung zu wählen. So kann die Variable für eine Kundennummer z.B. "intKundenNr" heißen, statt nur "KNR". Wie oben für die Variablendeklaration schon angesprochen, sollten Sie Ihre Scripte kommentieren - das erhöht die spätere Lesbarkeit. Kommentare können dabei u.a. den dann folgenden Scriptblock näher beschreiben oder gar nur eine einzelne Anweisung näher erläutern. Häufig wiederkehrende Anweisungen in Prozeduren/Methoden verpackenStellen Sie sich vor, sie müssen aus diversen Datenbanktabellen verschiedene Informationen zusammentragen und in einer SELECT-BOX darstellen. Es wäre müßig, jedes Mal den selben Codeabschnitt neu zu verfassen. Hier kann man sich die Arbeit dadurch erleichtern, in dem man immer wiederkehrende Programmteile in einzelne Prozeduren verpackt. Dabei können Sie zwischen Private | Public Sub | Function ([parameter]) wählen. Ob Sie nun "Sub" oder "Function" wählen hängt ganz davon ab, was Sie von Ihrer Prozedur erwarten. Soll ein bestimmter Codeblock nur abgearbeitet werden, so ist "Sub" die richtige Wahl. Möchten Sie aber durch den Aufruf der Prozedur einen Wert zurück erhalten, dann ist Function die richtige Entscheidung. Hier wird also deutlich: Sub kann keine Werte zurück geben (mit einer Ausnahme, wie Sie weiter unten noch sehen werden) - Function schon. Die Prozedur bzw. Methode wird durch die Angabe des Gültigkeitsbereiches (Private oder Public) , der Methodenart (Sub oder Function) und der an die Prozedur zu übergebenden Parameter gekennzeichnet. Die Angabe von Parametern ist optional. Sind keine Parameter zu übergeben, entfällt also diese Angabe. Hier ist jedoch noch zu beachten: Übergeben Sie Parameter an die Prozedur immer " ByVal " (Wertübergabe). Dies hat den Vorteil, daß innerhalb der Prozdur der Wert der Variablen sich ändern kann, jedoch außerhalb der Prozedur der ursprüngliche Variablenwert erhalten bleibt. Wollen Sie jedoch gerade diesen Umstand bezwecken, daß sich aufgrund des Prozeduraufrufes die an die Prozedur übergebene Variable sich mit ändert, lassen Sie den Zusatz "ByVal" weg. Standardmäßig werden Variablen an Prozeduren "ByRef" übergeben. Das Ende einer Prozedur wird mit der Anweisung End Sub | Function gekennzeichnet. Ist es erforderlich die Prozedur vorzeitig zu verlassen, so erfolgt dies mit Exit Sub | Function Schauen wir uns das ganze mal an einem Beispiel an - einer dynamisch erzeugten SELECT-BOX. Der Code hierfür könnte wie folgt aussehen: Public Sub meineSelectBox(ByVal strTable, ByVal strColumn, ByVal strElement) ' Prozedur erzeugt anhand der übergebenen Werte für ' Tabelle, Spalte und Elementname eine Select-Box Dim strTemp ' Temporärvariable strTemp = "<select name=" & strElement & ">" strTemp = strTemp & "<Option value=0 >Bitte wählen Sie</Option>" ' Datenbankteil ' SQL-Abfrage Dim sql sql = " SELECT id, " & strColumn & " FROM " & strTable & " " call dbconnect() ' Datenbankverbindung herstellen set rs = conn.Execute(sql) if rs.eof then ' Prozedur vorzeitig verlassen ' und nur Textfeld ausgeben Response.Write "<input type=text name=" & strElement & ">" call dbclose() ' Datenbankverbindung vorher schließen Exit Sub ' Prozedurende else while not rs.eof strTemp = strTemp & "<Option value=" & rs(0) & ">" & rs(1) & "</Option>" rs.MoveNext wend end if call dbclose() ' Datenbankverbindung schließen strTemp = strTemp & "</select>" ' SelectBox ausgeben Response.Write strTemp End Sub Nach der einleitenden Kommentierung erfolgt zunächst die Deklarierung einer lokalen Variable strTemp. Dies ist insoweit vorteilhaft, als daß der Zugriff auf lokale Variablen (also solchen, die innerhalb von Prozeduren deklariert werden), wieder schneller ist, als der Zugriff auf globale (außerhalb von Prozeduren deklarierte) Variablen. Für die Datenbankverbindung ist es jedoch ratsamer die Variable "conn" global zu deklarieren, damit andere Prozeduren das conn-Objekt nutzen können. Dabei sollten Sie beachten, daß im Fall der "conn"-Variable, diese PUBLIC deklariert werden sollte. Dann folgt der erste Teil der Select-Box. Dadurch, daß der Elementname mitübergeben wurde, kann die Select-Box mit jedem Aufruf der Prozedur einen beliebigen Namen bekommen, sodaß am Ende dieselbe Prozedur auf ein und derselben Seite mehrfach aufgerufen werden kann und dennoch immer wieder (namentlich) verschiedene HTML-Elemente erzeugt werden. Jetzt folgt die SQL-Anweisung. Auch hier ist die SQL-Anweisung so formuliert, daß sie am Ende variabel einsetzbar ist. Hierbei wurde jedoch davon ausgegangen, daß die abzufragende Tabelle über eine Primärschlüsselspalte mit der Bezeichnung "id" verfügt. Dies ist dann für die Wertzuweisung im Option-Value hilfreich. An das SQL-Statement wird die auszulesende Spalte und Tabelle übergeben. Dadurch ist es wieder möglich jede x-beliebige Tabelle/Spalte auszulesen und das Ergebnis in einer Select-Box darzustellen. Sofern kein Datensatz gefunden wurde, wird - um das HTML-Design nicht zu zerstören - ein einfaches Textfeld ausgegeben und die Prozedur vorzeitig verlassen. Ist ein Datensatz vorhanden, so werden die Option-Einträge der Select-Box erzeugt. An dieser Stelle kommt uns der Primärschlüssel des ausgelesenen Datensatzes zu gute. Um dem value nicht eine unnötig lange Zeichenkette zuzuweisen, wird hier einfach ein Integer-Wert - die Datensatz-ID - zugewiesen. Abschließend wird die HTML-Anweisung komplettiert und ausgegeben. Das ganze ließe sich mit einer Function genauso realisieren. Lediglich die erste und die letzten beiden Zeilen würden sich ändern: Public Function meineSelectBox(ByVal strTable, ByVal strColumn, ByVal strElement) ... meineSelectBox = strTemp End Function Damit die Function den Wert entsprechend zurückgibt, wird ihr der Wert von "strTemp" entsprechend zugewiesen. Die Ausgabe erfolgt dann mit dem Funktionsaufruf: Response.Write meineSelectBox(...) In den runden Klammern sind dann die Werte für die entsprechende Tabelle/Spalte und der Elementname an die Function mitzuübergeben. Richtige Übergabe der Parameter an die ProzedurBei der Übergabe der Parameter an die Prozedur sollte folgendes beachtet werden: Wie oben in unserem kleinen Beispiel schon zu sehen war, können die Parameter durch Voranstellen des Schlüsselwortes ByVal an die jeweilige Prozedur übergeben werden. ByVal bewirkt dabei, daß nur der Wert der Variablen übergeben wird. Arbeiten Sie innerhalb der Prozedur mit der gleichen Varaiablen weiter, so bleibt der Wert der Variablen außerhalb der Prozedur erhalten - gleich welchen Wert Sie der Variablen innerhalb der Prozedur zuweisen. Folgendes Codebeispiel soll Ihnen dies hier einmal verdeutlichen: <% dim a ' Variable a a=5 ' Wertzuweisung Response.Write "Die Variable a= " & a & " vor Prozeduraufruf <hr>" 'vor Prozeduraufruf call meineProzedur(a) Response.Write "Die Variable a= " & a & " nach Prozeduraufruf <hr>" 'vor Prozeduraufruf Public Sub meineProzedurByVal(ByVal a) Response.Write "Die Variable a= " & a & " in der Prozedur vor Wertänderung <hr>" a=10 ' Wert ändern Response.Write "Die Variable a= " & a & " in der Prozedur nach Wertänderung <hr>" End Sub %> In diesem Beispiel wird der Variablen a der Wert 5 zu gewiesen. Dann erfolgt der Aufruf einer Prozedur, wobei die Variable a ByVal an die Prozedur übergeben wird. Um deutlich zu machen, wie sich eine Wertänderung innerhalb der Prozedur außerhalb dieser wieder auf a wertmäßig auswirkt, habe ich hier in der Prozedur a den Wert 10 zugewiesen. Die nachfolgende Grafik zeigt recht deutlich, welchen Wert a jeweils angenommen hat und wie sich ByVal in der Parameterübergabe auf den Wert der Variablen ausgewirkt hat. Das Gegenstück zu ByVal ist ByRef. Hier wird die Adresse der Variable übergeben, so daß - das obige Beispiel entsprechend abgeändert - a den Wert aus der Prozedur automatisch übernimmt. dim a ' Variable a a=5 ' Wertzuweisung Response.Write "Die Variable a= " & a & " vor Prozeduraufruf <hr>" 'vor Prozeduraufruf call meineProzedur(a) Response.Write "Die Variable a= " & a & " nach Prozeduraufruf <hr>" 'vor Prozeduraufruf Public Sub meineProzedurByRef(ByRef b) Response.Write "Die Variable a= " & a & " in der Prozedur vor Wertänderung <hr>" b=10 ' Wert ändern Response.Write "Die Variable a= " & a & " in der Prozedur nach Wertänderung <hr>" End Sub Um deutlich zu machen, wie ByRef sich verhält, habe ich jetzt die Prozedurvariable b eingeführt. Im Gegensatz zu dem vorangegangenen Beispiel habe ich hier b den Wert 10 zugewiesen. Dennoch hat sich der Wert von a geändert, wie die nachfolgende Grafik wieder zeigt: Anders als bei PHP, erfolgt die Übergabe der Variablen standardmäßig - also ohne Angabe von ByVal oder ByRef - By Reference. Die Übergabe von Variablen ByRef an die Prozedur ist also dann sinnvoll, wenn der Variablenwert mit geändert werden soll. Daneben ist der Einsatz von ByRef wieder etwas schneller als ByVal. Wenn man dabei ist, sich Gedanken zu machen wie und wann es am sinnvollsten erscheint ByVal oder ByRef einzusetzen, so möchte ich Ihnen noch folgenden Hinweis geben: Gelegentlich kommt es vor, daß man mehr als einen Wert durch den Funktionsaufruf zurückgegeben haben möchte, eine Function aber andererseits nur einen Rückgabewert erlaubt. Wie kann man dem Abhelfen? Nun, Sie übergeben einfach eine zusätzliche Variable an die Funktion - allerdings diesmal bewußt ByRef. Da Sie nun wissen, wie sich der Wert der Variable ändern kann, die ByRef an die Funktion übergeben wurde, haben Sie auch zugleich den Weg, mehr als einen Wert aus einem Funktionsaufruf zurückzuerhalten. Und genau so könnten Sie mit einer Sub-Prozedur verfahren. Die Sub-Routinen geben nie einen Wert an die aufrufende Stelle zurück. Benötigen Sie aber gerade durch den Aufruf einer Sub einen bestimmten Rückgabewert, so übergeben Sie an die Sub einfach einen Wert ByRef. Das Ergebnis ist analog den obigen Ausführungen zur Function. Private oder Public oder doch Dim?Lassen Sie mich an dieser Stelle ein paar Ausführungen zum Unterschied der Schlüsselwörter Private und Public machen. Beide Schlüsselwörter beschreiben den Geltungsbereich - sowohl der Prozedur als auch der einzelnen Variable. Hinsichtlich der Variablendeklaration sollten Sie folgende Überlegungen beachten:
ASP-Logik kapselnWenn Sie denn so detailiert vorgehen und fast alles in Prozeduren verpacken, dann stellt sich die Frage, wie man am besten die ASP-Script-Logik zentral verfügbar (administrierbar) machen kann. Dies erreichen Sie über ein entsprechendes INCLUDE der jeweiligen Logik-Seite. <!--#include file="../meineLogik.asp"--> Hierbei müssen Sie aber beachten, daß die Seite, in welcher der INCLUDE-Befehl steht, ebenfalls eine ASP-Seite sein muß. Dies ist dadurch begründet, da Sie ja hier die Prozedur aus der includierten Seite aufrufen wollen, was regelmäßig wie folgt geschieht: <% call meinProzedurname(meineParameter,...) %> Die call-Anweisung ist dabei nicht zwingend, bringt aber einen entscheidenen Syntax-Vorteil im Aufruf der Prozedur. Nehmen wir hier wieder das obige Beispiel der Select-Box. Hier haben wir uns für eine SUB-Prozedur entschieden. Der Aufruf dieser SUB-Prozedur ohne dem Schlüsselwort call müßte dann korrekter Weise folgendermaßen erfolgen: MeineSelectBox strTable, strColumn, strElement Wenn wir nun call verwenden sieht das Ganze so aus: call meineSelectBox(strTable, strColumn, strElement) Sie sehen also, beim Einsatz von call ist es erforderlich, die übergebenen Parameter in runden Klammern zu fassen. Wäre unsere Prozedur als FUNCTION definiert worden, so müßten wir in jedem Fall die Parameter in entsprechender Umklammerung mit angeben. Die Benutzung von call beim Prozeduraufruf hat also den Vorteil der einheitlichen Syntax - ich muß also nicht mehr darauf achten, ob ich nun eine SUB oder eine FUNCTION aufrufe - in jedem Fall werden die Parameter in runder Umklammerung an die Prozedur übergeben. Des weiteren wird durch call im Script deutlich, daß an dieser Stelle eine Prozedur aufgerufen wird. ZusammenfassungDer Artikel soll insbesondere ASP-Einsteigern dazu dienen, von Anfang an darauf zu achten, sauber und übersichtlich - strukturiert - zu programmieren. Durch den Einsatz von Prozeduren, lassen sich insbesondere mit Blick auf die Ressourcen, verschiedenste Programmteile gezielt ansteuern. So kann eine Datenbankverbindung z.B. erst dann angefordert werden, wenn diese auch explizit benötigt wird und sobald sie nicht mehr erforderlich ist, entsprechend wieder freigegeben werden. Mit Prozeduren kann man seinen Code so gestalten, daß er weitgehend allgemeingültig bleibt, was die Wiederverwendbarkeit in anderen Projekten enorm erleichtert. Eine weitere Möglichkeit wäre auch Kapselung des Script-Codes in einzelne Klassen (Class ... End Class). Durch die "Auslagerung" der einzelnen Prozeduren in eine eigenständige ASP-Datei kann man auch noch klarer Design und Programmierung voneinander trennen, was am Ende die Wartungsfreundlichkeit des ASP-Codes und die Zusammenarbeit der Abteilungen (Designer/Programmierer) enorm erleichtert. Download des CodesKlicken Sie hier, um den Download zu starten. Verwandte Artikel
Überprüfen von HTML-Formularen mit ASP Wenn Sie jetzt Fragen haben...Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten. Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.
Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.
©2000-2006 AspHeute.com |