Component Object Model

 

Ingress: Alle er enige om at inndeling av programvare i komponenter er en bra ting. Microsoft har sin arkitektur for dette som kalles COM, og som vi skal se på her. Vi skal også se på hva konkurrentene til Microsoft foretar seg på dette området.

 

Å bryte opp programvaren i komponenter innebærer at man legger større flid i å bestemme hvordan komponenten skal påvirke og bli påvirket av sine omgivelser. I programmererlingo kalles dette for "grensesnittet", og at grensesnittet skal være uten "sideeffekter". Gjør man denne jobben skikkelig, kan en komponent bygges og testes helt separat, og når den fungerer som ønsket, kan den brukes om og om igjen i forskjellige programmer uten at det oppstår noen overraskelser.

 

Dette har programmererne visst i 30 år, men drømmen om "reusable software" er aldri blitt oppfylt slik som man har håpet: At ute i verden skulle det flyte av komponenter i et enormt utvalg, og at programutvikling skulle koke ned til å lage et "lim" som satte sammen komponentenes funksjonalitet på en riktig måte. Grunnene til at dette aldri har fungert slik, er bl.a. at man har undervurdert den oppslutning som kreves rundt én slik komponentmodell for at ikke det hele skal pulveriseres rundt mange forskjellige konkurrerende teknologier.

 

Også idag har vi mange forslag og halvt utviklede løsninger som gjør krav på å kunne være den ene teknologien som skal "frelse verden". Microsoft har en slik teknologi, og med den tyngden som Microsoft utgjør i leverandørmarkedet, må et utspill fra den kanten ansees som interessant allerede i utgangspunktet. "Alle andre" prøver på sin side å lage allianser som kan utgjøre en like sterk kraft i markedet, f.eks. Object Management Group med modellen "Corba" - Common Object Request Broker Architecture. I tillegg kommer en liten "kjekkas" som kalles Java med teknologi som mange finner interessant.

 

Vi skal i denne omgang fokusere litt på Micosofts bidrag, som kalles Common Object Model (COM). COM dreier seg om en arkitektur som beskriver hvordan programkomponenter kan kalle på tjenester i andre programkomponenter i en klient-tjener fasong. Og det hele skal foregå innen en objektorientert programmeringsmodell, slik at nøkkelbegreper som klassifikasjon og arvelighet skal være tatt vare på.

 

Objekter har en tilstand (datavariabler), og de har metoder for å spørre eller endre på denne tilstanden. Det vanlige er også at dataene er innkapslet, dvs. at dataene bare kan sees direkte fra den koden som utgjør metodene for objektet.

 

I Microsoft-verdenen kan et objekt være implementert av en DLL (dynamisk lastet kodemodul) og et datasegment som tilhører denne. I dette tilfellet kan vi laste inn DLL’en, og kalle metodene (prosedyrene) i denne på samme måte som vi alltid har gjort, og la kompilatoren for programmeringsspråket sørge for "objekt-utseendet". I andre tilfeller ønsker vi at objektets metoder skal utføres i en egen såkalt "prosess-kontekst", dvs. i en prosess som er adskilt fra klientens prosess (i en EXE-fil). Dessuten ønsker vi at objektet (med tilstand og metoder) skal kunne befinne seg på et annen maskin, slik at all overføring av parametre og returdata må foregå gjennom et datanettverk.

 

Ideelt sett bør det ikke vedkomme programmereren hvilken av disse tre alternativene som faktisk brukes, det bør være en avgjørelse som tas under konfigureringen av det ferdige systemet. Derfor kan det ikke være noen forskjell på hvordan et objekt skal behandles, om det så nås på den ene eller den andre måten. Dette kravet er det som gjør COM og andre objektmodeller svært kompliserte; for å kalle på objekter i sin enkleste form må vi bruke mekanismer og følge regler som er tilpasset en mulig distribusjon av objekter rundt i nettverket.

 

Interfaces

 

Tjenestene til et COM-objekt viser seg gjennom noe som kalles "Interfaces", her kaller vi dem Grensesnitt. Et grensesnitt er en samling metoder for å behandle objektets tilstand (data). Når en klient ber om å få laget et objekt av en bestemt klasse, vil klienten få i retur opplysninger (en peker) til ett av grensesnittene, og kan kalle de metodene som er gruppert under dette. En av metodene som tilbys er å spørre etter opplysninger om andre grensesnitt, som kan sette klienten i stand til å kalle metoder gruppert der.

 

Hvorfor flere grensesnitt til ett og samme objekt? Noen objektorienterte programmeringsspråk, f.eks. C++, har ikke et "grensesnitt"-begrep, men legger alle mulige metoder i samme kurv. Java, derimot har mulighet for flere grensesnitt gjennom "interface"-deklarasjoner. Tanken er at metoder som hører sammen og utgjør en hovedfunksjon tilobjektet, skal grupperes i et eget "navneområde" (metoder i forskjellige grensesnitt kan ha samme navn).

 

En annen grunn til å ha flere grensesnitt er en spesiell egenskap ved COM-arkitekturen: Et grensesnitt skal aldri endres! Når det først har fått sin utforming, må alle endringer i metodene skje ved at det etableres en ny "versjon" av grensesnittet. Den gamle må beholdes "for evig", og vil dermed sørge for at gamle klienter fortsatt vil virke. Versjonshåndering altså, og vi har sansen for et strengt regime for å unngå versjonsproblematikk, mer "tilllitsfulle" metoder i andre teknologier har vist seg ikke å virke godt i praksis.

 

Arvelighet

 

I objektorientert programmering bruker vi begrepet "arvelighet" for å ordne objektklassene i et hierarki av egenskaper. Arvelighet betyr at et objekt tilbyr alle de metoder som finnes i klasser "over seg" i dette hierarkiet.

 

I alle de objektorienterte programmeringsspråkene som vi har vært borte i, har slik arvelighet betydd å "arve kode". Med det menes at et objekt arver både definisjon og kode i metodene høyere opp i hierarkiet.

 

I COM finner vi en enklere modell som vi kan kalle "arvet definisjon". I COM vil altså en klasse arve grensesnittene til sin "morklasse", men må selv skaffe koden for å implementere dette grensesnittet.

 

Et slikt skjema skaper enklere mekanismer for å finne frem til den koden som skal utføres når man kaller metoden til et objekt. Mindre grad av såkalt "dynamisk binding" til objektets metoder, mindre behov for å lagre hele klassehierarkiet i hvert enkelt objekt, og mindre tvetydighet når man tvinger et objekt til å tilhøre en annen klasse (casting).

 

Flertydighet

 

Flertydighet eller "Polymorfisme" er betegnelsen på en nøkkelegenskap ved objektorienterte systemer. Flere objektklasser kan ha metoder som heter det samme. I prosedyreorienterte systemer er ikke dette mulig, der må man lage f.eks. prosedyrene "PrintStack", "PrintArray" og "PrintReal". I et objektorientert system kan man lage en "Print"-metode for hver klasse, og deretter overlate til kompilatoren å finne ut hvem av dem som skal kalles, basert på kunnskapen om de objektene som brukes som parameter.

 

Slik flertydighet er det kompilatoren som tilbyr. For en arkitektur som befatter seg med kompilert kode er flertydighet et lite sentralt begrep. COM støtter nemlig uten videre muligheten for at objekter av ulik klasse kan ha metoder med samme navn.

 

Flertydighet betyr derimot også at samme objekt kan ha metoder med samme navn, men med ulikt parameteroppsett. Slik flertydighet er ikke støttet av COM.