Man kan fra VBScript 5.0, lave sine egne klasser, hvilket betyder at man i ASP 3.0 også kan benytte denne feature.

Klasser har flere fordele, dels indkapsler de funktionalitet, dels følger der nogle features med når man arbejder med klasser.

For lige at tage den sidste pointe først, så kan man f.eks. benytte klassens evne til at kalde en funktion når den nedlægges, til at rydde op i de resurser den har fat i. En resurse som ofte benyttes på dynamiske websites og som er kritisk at få frigivet er forbindelser til databaser. Dette kan f.eks. klares således:

class database
  private m_conn
  private m_conn_str

  private sub class_initialize()
    set m_conn = nothing
    m_conn_str = "...dine indstillinger for databaseforbindelsen..."
  end sub
 
  public property get conn()
    if m_conn is nothing then 
      set m_conn = Server.CreateObject("ADODB.Connection")
    end if
    set conn = m_conn
  end sub

  public property get conn_str: conn_str = m_conn_str: property end
  public property let conn_str(value)
    me.close
    m_conn_str = value
  property end

  public sub open()
    if m_conn.state = 0 then
      m_conn.open m_conn_str
    end if
  end sub

  public sub close()
    if m_conn.state <> 0 then
      m_conn.Close
    end if
  end sub 

  private sub class_terminate()
    if not m_conn is nothing then
      if m_conn.state <> 0 then
        m_conn.Close
      end if
    end if
  end sub
end class

' Opret en forekomst af database-objektet og åben forbindelsen
set db = new database
db.open
set rs = db.conn.execute("SELECT * FROM tabel")
'.... osv...

Hvis man så skulle komme for skade at efterlade db.conn åben inden man sætter db til nothing, så klarer klassen selv at lukke forbindelsen inden objektet bliver nedlagt. På denne måde kan man i princippet også efterlade db-objektet (lade det gå ud af scope) og blot lade det nedlægge sig selv og i den forbindelse lukke for forbindelsen til databasen. Det er dog ikke en strategi jeg anbefaler, men det kan måske redde en ellers brav kodekarl fra problemer med databaseforbindelser som "hænger" og evt. låser databasen...

Ud over at hjælpe til med oprydning, så hjælper klassen også for pakke logikken omkring en funktionalitet ind, så det ikke forplumrer koden på andre sider. I ovenstående tilfælde er der tale om logik til at skabe forbindelse til en databasen, men det kunne ligeså godt have været logik til at arbejde med oplysninger om en bruger, herunder læse, skrive, slette osv. en brugers oplysninger. I sådan et tilfælde, kunne man have et regelsæt for om - og hvornår - en given bruger måtte benytte forskellige sider eller elementer af et site. Disse regler kunne implementeres i klassen uden at andre skulle bekymre sig om hvordan, men bare skulle forholde sig til OM en bruger havde adgang til et område af sitet. Dette er eksemplificeret (og simplificeret nedenfor):

class bruger
  private m_id
  private m_navn
  private m_kode

  public sub hent(id)
    ' henter brugerens oplysninger fra databasen...
  end sub

  public sub gem()
    ' gemmer brugerens oplysninger i databasen
    ' (dvs. opretter eller opdaterer alt efter om id er sat eller ej)
  end sub

  public sub slet()
    ' sletter brugerens oplysninger fra databasen
  end sub

  public function harAdgang(side)
    select case side
      case "admin.asp", "brugerliste.asp"
        harAdgang = false
      case else
        harAdgang = true
    end select
  end function

  public property get navn
    navn = m_navn
  end property

  public property get kode
    kode = m_kode
  end property
end class

Nu er ovenstående klasse en meget simpel udgave af adgangskontrol, men princippet kan sagtens udbygges til at omfatte opslag i en database eller lignende, således den bliver meget dynamisk og omfattende rent funktionelt.

Klassen kunne så benyttes på en side som følger (med udgangspunkt i at session("id") indeholder den aktuelle brugers id):

<%
dim aktuelleBruger
set aktuelleBruger = new bruger
aktuelleBruger.hent session("id")
if not aktuelleBruger.harAdgang(Request.ServerVariables("script_name")) then
  Response.Redirect "login.asp" end if
'
' ellers fortsæt med at vise siden
'
%>

Man kunne endda lave en funktion på objektet som tog udgangspunkt i det aktuelle scriptnavn:

class bruger
  private m_id
  private m_navn
  private m_kode

  public function harAdgangTilAktuelSide()
    dim side
    side = Request.ServerVariables("script_name")
    select case side
      case "admin.asp", "brugerliste.asp"
        harAdgangTilAktuelleSide = false
      case else
        harAdgangTilAktuelleSide = true
    end select
  end function
end class

Denne nye metode skal så kaldes som i forrige eksempel, men denne gang er parameteren ikke nødvendigt (den logik er pakket ind i klassen).

<%
dim aktuelleBruger
set aktuelleBruger = new bruger
aktuelleBruger.hent session("id")
if not aktuelleBruger.harAdgangTilAktuelleSide() then
  Response.Redirect "login.asp"
end if
'
' ellers fortsæt med at vise siden
'
%>
 

En anden "forbedring" man kan lave på brugerklassen er at den aktuelle bruger kunne være default for klassen, dvs. når klassens hent-motode kaldes uden parameter, så er det den aktuelle bruger der hentes. Det er besnærende at hente den aktuelle bruger som udgangspunkt, men hvis man bruger klassen meget i andre sammenhænge end til at operere med den aktuelle bruger, kan dette belaste databasen og systemet i en højere grad en ønsket, derfor vil jeg anbefale kun at gøre dette med ekstra omtanke.

class bruger
  private m_id
  private m_navn
  private m_kode

  public sub hentAktuelleBruger()
    ' henter brugerens oplysninger fra databasen på grundlag af
    ' det aktuelt registrerede id i session...
    ' objektets metode til hent benyttes for at undgå dobbeltkode
    ' (da det er samme operation, blot med en foruddefineret parameter).
    me.hent session("id")
  end sub
end class

Brugen af klassen kan dermed omskrives som følger:

<%
dim aktuelleBruger
set aktuelleBruger = new bruger
aktuelleBruger.hentAktuelleBruger
if not aktuelleBruger.harAdgangTilAktuelleSide() then
  Response.Redirect "login.asp"
end if
'
' ellers fortsæt med at vise siden
'
%>

Ændringen fra det forrige eksempel er ikke stor, men man overlader nu til klassen at bestemme hvordan oplysninger om den aktuelle bruger opbevares mens de er online. Det kunne være man senere ønskede at opbevare "tilstand" på en anden måde end i session og med en klasse til at pakke logikken ind, behøver man kun at koncentrere sig om at rette klassens logik, for at ændre håndtering af "tilstand".

Klassen kunne udvides med andre faciliteter, f.eks. mulighed for at

  • kontrollere om brugeren er online (ved f.eks. at slå op i databasen for at se om brugerne er markeret som værende online - man kan ikke checke session, da der ikke er adgang til andre brugeres session-oplysninger).
  • kontrollere om brugerens loginoplysninger er korrekte (dvs. sende 2 parametre til en metode på klassen, som slår op i databasen osv.)
  • foretage faktisk login af en bruger på grundlag af loginoplysninger som sendes til en metode på klassen
  • sende en mail til brugeren vedr. en eller anden hændelse
  • tilknytte til brugeren relaterede oplysninger, så som favoritbrugere (indikation af hvilke andre brugere i systemet som den aktuelle bruger specielt ønsker at fokusere på)
  • hente oplysninger der på den ene eller anden måde har relation til den aktuelle bruger (f.eks. debatindlæg den aktuelle bruger har oprettet eller deltaget i, eller post som brugeren har sendt/modtaget)

 

 
Sidst opdateret: 10-09-2008 19:02:22
Tilmeld link | Tilføj Link | Tilføj Link | @-begynder
Erklæring om beskyttelse af personlige oplysninger

nope.dk - Danmarks Website Chart