Avatar billede websam Nybegynder
27. marts 2007 - 09:34 Der er 11 kommentarer og
1 løsning

Kalde klasse i en anden klasse ?

Hejsa,

Jeg skal lige høre om der er nogen der kan fortælle mig hvordan jeg kalder en klasse i en anden klasse.

Forstået på den måde at jeg har en klasse der tager sig af at åbne og lukke database tilgang og en anden klasse der tager sig af sql kald til databasen, hvor jeg så skal bruge den første klasse ?

/Websam
Avatar billede softspot Forsker
27. marts 2007 - 09:42 #1
Prøv at definere hvad du mener med klasse.

Umiddelbart findes der et class-koncept i VBScript, men er det rent faktisk sådan en klasse du taler om - og er det VBS?

Hvis der er tale om ovenstående klassekoncept, så ville jeg forvente at metoderne i den klasse der sørger for opslagene, skulle tage en klasse, eller rettere et objekt, der holder styr på forbindelsen, som parameter, og så bruge dette objekt til at få kontakt til den relevante database.
Avatar billede websam Nybegynder
27. marts 2007 - 09:55 #2
Class database
    '--- noget kode.....
End Class

Class metoder
    '--- noget kode.....
End Class

Så ja der er tale om class-koncept og i VBScript, jeg skal sådan set bare vide hvordan jeg bære mig ad med at kalde min database klasse i en hvilken som helst anden klasse.

er det noget i stil med :

Class metoder
    Set objDB = New database
End Class

Sådan ville jeg gøre i .net, men da asp jo ikke er OOP på samme måde kan jeg ikke få det til at spille ?
Avatar billede softspot Forsker
27. marts 2007 - 10:01 #3
Ja, det er da en måde at gøre det på... hvorvidt det er smart eller ej at binde metodeklassen så tæt til databaseklassen kan så diskuteres, men da det jo bare er et eksempel, antager jeg at du finder på noget der er mere dynamisk :)
Avatar billede websam Nybegynder
27. marts 2007 - 10:04 #4
Kom gerne med et eksempel ;o)
Avatar billede softspot Forsker
27. marts 2007 - 10:34 #5
Et hurtigt eksempel lige ud af hovedet (og derfor ikke mere gennemtænkt end som så).
Jeg tager udgangspunkt i et databaselag som understøtter min adgang til databasen og herunder et simpelt "interface" (execQuery og execNonQuery) og en forretningsklasse som (næsten) abstraherer fra hvlilken database der benyttes.

SQL-sætningerne bliver dannet i forretningsobjektet, hvilket ikke er optimalt ifht. at gøre sig uafhængig af databasevalget (men som sagt et lidt hurtigt eksempel).

Der kan laves meget mere detaljeret kode og fejlhåndtering, men det er udeladt her for eksemplets skyld. Jeg er sikker på at du nok kan finde ud af hvordan det skal gøres... :)

class database
  private conn
  private dsn

  private sub class_initialize()
    dsn = "provider=..."
  end sub

  public sub open()
    set conn = Server.CreateObject("ADODB.Connection")
    conn.open dsn
  end sub

  public sub close()
    if not conn is nothing then
      conn.close
    end if
  end sub

  public function execQuery(sql)
    dim rs
    set rs = conn.execute(sql)
    set execQuery = rs
  end function

  public function execNonQuery(sql)
    execNonQuery = conn.execute(sql)
  end sub
end class


class person
  private db
  private m_id
  private m_navn
  private m_adresse

  public sub initconnection(objdb)
    set db = objdb
  end sub

  public sub hent(id)
    dim sql, rs
    sql = "select navn, adresse from person where id = " & id
    set rs = db.execQuery(sql)
    if not rs.eof then
      m_id = id
      m_navn = rs("navn")
      m_adresse = rs("adresse")
    end if
    rs.close
    set rs = nothing
  end sub

  public sub gem()
    dim sql
    if isempty(m_id) or m_id = 0 then
      sql = "insert into person (navn, adresse) values('" & m_navn & "','" & m_adresse & "')"
    else
      sql = "update person set navn = '" & m_navn & "', adresse = '" & m_adresse & "' where id = " & m_id
    end if
    db.execNonQuery(sql)
  end sub

  public sub slet()
    dim sql
    sql = "delete from person where id = " & m_id
    db.execNonQuery(sql)
  end sub

  public property get id
    id = m_id
  end property

  public property get navn
    navn = m_navn
  end property

  public property get adresse
    adresse = m_adresse
  end property

  public property let navn(value)
    m_navn = value
  end property

  public property get adresse(value)
    m_adresse = value
  end property
end class

set db = new database
db.open
set p1 = new person
p1.initdatabase db
' opret en ny person
p1.navn = "softspot"
p1.adresse = "internettet"
p1.gem
set p1 = nothing

set p1 = new person
p1.initdatabase db
' slet en person
p1.hent 1
p1.slet
set p1 = nothing
Avatar billede softspot Forsker
27. marts 2007 - 10:36 #6
UPS! den sidste property i person-klassen skal lige være en let-property:

  public property let adresse(value)
    m_adresse = value
  end property
Avatar billede softspot Forsker
27. marts 2007 - 10:39 #7
...og lige en rettelse mere. funktionen initconnection skal lige omdøbes:

  public sub initdatabase(objdb)
    set db = objdb
  end sub


og til sidst kunne man for en god ordens skyld lige kalde close på database-objektet:

db.close
Avatar billede websam Nybegynder
27. marts 2007 - 11:45 #8
På den måde du viser det der er skal jeg jo kalde database klassen på selve asp siden der loader evt. indhold og det er da ikke det mest optimale i mine øjne det skulle jo kun være nødvendigt at kalde databasen i den klasse hvor den skal bruges og så lave enten en insert, update og delete eller select der sender et array med data videre til visning for derefter at lukke database forbindelsen.

Men det er ikke sikkert at det er muligt at gøre dette i asp (har de sidste par år primært beskæftiget mig med asp.net)
Avatar billede softspot Forsker
27. marts 2007 - 11:58 #9
Jo, det er da muligt at kalde den inde fra objektet, men jeg ville bare gøre bindingen til databasen løsere, så du ikke skulle ændre i dine forretningsobjekter hvis du lavede en ny database-klasse, men blot der hvor den nye klasse skulle bruges... det er da meget muligt at det er en akademisk diskussion, men så har du da set et eksempel på det. Den viste metode giver dig også større fleksibilitet ifht. at styre om der skal ske mere på den samme forbindelse end bare den ene operation som du vil begrænse dig til hvis du opretter databaseobjektet i hent-, gem- og slet-funktionerne.

Hvis du vil pakke databasekaldene ind i din forretningsklasse, kan du jo bare oprette database-objektet der hvor det skal bruges og lukke det igen efter brug.
Evt. med et check på om objektet er oprettet i forvejen, så du bibeholder muligheden for at udføre flere operationer på samme databaseforbindelse.

Herunder har jeg rettet slet-funktionen i person-klassen så du kan se princippet:

  public sub slet()
    dim sql, localConnection
    sql = "delete from person where id = " & m_id
    if db is nothing then
      set db = new database
      db.open
      localConnection = true
    else
      localConnection = false
    end if
    db.execNonQuery(sql)
    if localConnection then
      db.close
      set db = nothing
    end if
  end sub

personklassen kan så benyttes således:

dim p1
set p1 = new person
p1.hent 1
p1.slet
set p1 = nothing
Avatar billede websam Nybegynder
27. marts 2007 - 12:53 #10
Super, smid et svar ;o)
Avatar billede softspot Forsker
27. marts 2007 - 13:29 #11
Velbekomme :)
Avatar billede softspot Forsker
27. marts 2007 - 14:20 #12
Tak for point :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester