Model obiect sistem (SOMObjects) | |
---|---|
Dezvoltator | CILabs ( IBM , Apple Computer , etc.) |
Sistem de operare | MacOS , OS /2 , AIX , Windows , DOS |
ultima versiune | 3.0 (decembrie 1996 ) |
System Object Model ( SOM ) este un sistem de biblioteci dinamice orientate pe obiecte dezvoltate de CILabs ( IBM , Apple , OMG, Adobe , Oracle etc.). DSOM, o versiune distribuită bazată pe CORBA a SOM care permite ca obiectele să fie distribuite pe diferite sisteme de calcul. Există implementări pentru sistemele de operare Windows NT, MacOS Classic, OS/2, AIX, DOS, Copland, OS/390, NonStop OS. Pentru Windows NT, MacOS și OS/2, există o implementare a dezvoltării componentelor OpenDoc bazate pe SOM/DSOM. Sistemul a fost dezvoltat la mijlocul anilor 1990, a fost abandonat în 1998 [1] .
IBM SOM este conceptual similar cu Microsoft Component Object Model . Ambele sisteme rezolvă problema creării unui format de bibliotecă standard care poate fi apelat din mai multe limbi. SOM este considerat a fi mai funcțional decât COM. COM oferă două moduri de a apela metode pe un obiect, iar un obiect poate implementa una sau ambele dintre ele. Prima este invocarea dinamică și legarea tardivă (IDispatch) și, ca SOM, este independentă de limbaj. A doua modalitate, printr-o interfață privată, folosește un tabel de funcții care poate fi construit în C sau folosește un tabel de metode virtuale compatibil de nivel inferior al unui obiect C++. Folosind compilatoare C++ compatibile, puteți declara interfețele private ca clase C++ virtuale pure. Interfețele private reprezintă un compromis între funcționalitate și performanță. Odată ce o interfață a fost publicată pentru un produs lansat, aceasta nu poate fi modificată deoarece aplicațiile utilizator ale interfeței au fost compilate pentru un anumit dispozitiv de masă la un nivel scăzut. Acesta este un exemplu de problemă fragilă a clasei de bază care poate duce la iadul DLL , unde după instalarea unei noi versiuni a unei biblioteci partajate, toate programele care utilizează versiunea veche nu mai funcționează corect. Pentru a evita această problemă, dezvoltatorii COM ar trebui să țină întotdeauna cont de faptul că interfețele care au fost deja publicate nu trebuie modificate. Dacă doriți să adăugați noi metode sau să faceți alte modificări, trebuie să definiți interfețe noi. SOM previne aceste probleme oferind numai legături tardive și permițând linker-ului de execuție să reconstruiască tabelele din mers. Astfel, modificările la bibliotecile de bază sunt recalculate atunci când sunt încărcate în programe, cu prețul unei mici lovituri de performanță.
Interfața, însă, nu poate fi schimbată nu numai din motive tehnice, ci și din punctul de vedere al OOP. O interfață, spre deosebire de o clasă, nu are o implementare implicită și poate fi implementată de oricine, inclusiv de un dezvoltator terță parte. În consecință, dacă se fac modificări la interfață, clasele terțe nu pot suporta automat noua interfață. Astfel, fie puteți folosi doar clase în loc de interfețe, oferind o implementare implicită mereu actualizată, fie puteți împiedica dezvoltatorii terți să implementeze o interfață potențial extensibilă, caz în care cuvântul „interfață” își pierde sensul în Termeni OOP.
SOM este, de asemenea, mai funcțional în ceea ce privește suportul complet pentru diferite limbi OO. În timp ce dezvoltarea COM se limitează la utilizarea unei versiuni reduse de C++, SOM acceptă aproape toate caracteristicile obișnuite și chiar câteva ezoterice. De exemplu, SOM acceptă moștenire multiple, metaclase și apeluri dinamice. Unele dintre aceste caracteristici nu sunt disponibile în majoritatea limbilor, așa că multe sisteme de tip SOM/COM sunt mai ușor de implementat în detrimentul suportării unui set mai mic de limbi. Flexibilitatea deplină a suportului multilingv a fost importantă pentru IBM datorită necesității de a suporta atât Smalltalk (moștenire unică, legare dinamică), cât și C++ (moștenire multiplă și legare statică). Necesitatea de a suporta moștenirea multiplă este, printre altele, o consecință a faptului că în loc de interfețe există doar clase. Trebuie remarcat faptul că suportul C++ pentru moștenirea multiplă diferă de CLOS, Dylan, SOM și Python, iar problemele de moștenire multiplă ale C++ nu sunt specifice SOM.
Cea mai vizibilă diferență între SOM și COM este suportul pentru moștenire, pe care COM nu o are deloc. Poate părea ciudat că Microsoft a produs un sistem de bibliotecă de obiecte care nu acceptă cel mai fundamental principiu al OOP. Principalul obstacol în acest sens este dificultatea de a determina unde se află clasa de bază în sistem în timp ce bibliotecile sunt încărcate într-o ordine potențial arbitrară. COM cere dezvoltatorului să specifice clasa de bază exact în timpul compilării, făcând imposibilă inserarea altor clase moștenite în mijloc (cel puțin în bibliotecile COM străine).
În contrast, SOM folosește un algoritm simplu, parcurgând arborele de moștenire căutând o potențială clasă de bază și stabilindu-se pe prima potrivită. În cele mai multe cazuri, acesta este principiul de bază al moștenirii. Dezavantajul acestei abordări este posibilitatea ca noile versiuni ale clasei de bază să nu funcționeze în ciuda API-ului neschimbat. Această posibilitate există în orice program, nu doar în cei care folosesc biblioteci partajate, dar problema devine foarte dificil de urmărit dacă există în codul altcuiva. În SOM, singura soluție este testarea completă a noilor versiuni de biblioteci, ceea ce nu este întotdeauna ușor.
Comparația cu alte abordări a fost făcută în raportul „Release-to-Release Binary Compatibility and the Correctness of Separate Compilation” [2] , în special, Smalltalk, CLOS, Generic C++, SOM, SGI Delta/C++, OBI, Objective-C , Java. Dintre sistemele moderne, este cel mai apropiat de SOM în ceea ce privește furnizarea de compatibilitate Objective-C la nivel scăzut, mai ales după implementarea ivar-urilor non-fragile.
Emițătorii pentru C și C++ sunt incluși în SOMobjects Developer Toolkit însuși și vă permit să apelați atât metode obiect, cât și să moșteniți din clase. Unele compilatoare C++, mai întâi MetaWare High C++, apoi IBM VisualAge C++, au implementat capacitatea Direct-to-SOM. VisualAge C++ pentru Windows a introdus această caracteristică în versiunea 3.5 [3] , care a fost și ultima versiune care a suportat această caracteristică.
ObjectREXX, livrat cu OS/2, este integrat cu SOM, permițându-vă să apelați metode pe obiecte și să moșteniți din clase. Când sursele ObjectREXX au fost lansate comunității open source, toate fișierele necesare pentru ca această integrare să funcționeze nu au fost transferate, iar această caracteristică nu a fost inclusă în versiunea open source. De ceva timp au existat urme de integrare cu SOM în depozit, dar a fost imposibil de compilat, iar ulterior tot ce ține de SOM a fost complet eliminat.
Pachetul VisualAge SmallTalk SOMSupport vă permite să apelați metode SOM pe obiecte și să creați pachete SOM pentru clasele SmallTalk .
IBM ObjectCOBOL a folosit inițial SOM ca sistem de obiecte în modul Direct-to-SOM. Ulterior, ObjectCOBOL a fost portat în Java și a început să folosească sistemul de obiecte Java în loc de SOM.
Unele versiuni de VisualAge pentru Basic au avut integrare SOM [4] . În plus, Lotus Script, inclus în distribuția OpenDoc, poate funcționa și cu obiecte SOM prin OpenDoc Direct Scripting (ODDS) [5] .
În SOMObjects Java Client [6] a fost posibilă apelarea obiectelor SOM doar de la distanță, prin DSOM. Exemplul demonstrativ a avut clase care au fost puse la dispoziție pe serverul DSOM, iar apoi appletul Java a fost găzduit pe o resursă de Internet, a creat obiecte la distanță și a numit metodele acestora. Apelurile la metodele locale nu sunt furnizate.
Emițătoarele pentru Virtual Pascal au fost dezvoltate de o persoană privată, ulterior portate la Free Pascal [7] (doar OS/2). Ele vă permit să apelați metode și să vă creați propriile clase.
SOMIRIMP.exe [8] (numai Windows), un importator din baza de date binară SOM.IR în legăturile Delphi, a fost dezvoltat independent de o altă persoană. Vă permite să apelați metode, dar nu să creați clase. Spre deosebire de emițătorul anterior implementat în C, SOMIRIMP este scris în Delphi și folosește legături autogenerate.
Dezvoltatorii compilatorului PowerAda au realizat emițători [9] și exemple de utilizare a SOM. PowerAda a fost disponibil numai pe AIX, iar emitatorul necesită SOM 3.0 Beta, tot pentru AIX, pentru a rula. SOM 3.0 pentru AIX a fost pierdut.
Canterbury Modula-2 pentru OS/2 avea extensii orientate pe obiecte similare cu Oberon-2 și suporta modul de compilare Direct-to-SOM în versiunea profesională. [zece]
Oberon Microsystems a anunțat suport pentru Direct-to-SOM pe Mac OS Classic, dar starea acestui proiect este necunoscută. [unsprezece]
De obicei, dezvoltarea pentru SOM decurge după cum urmează:
În modul consumer:
Dezvoltatorul rulează compilatorul SOM cu un emițător pentru limbajul de programare dorit, specificând la ce fișiere IDL din biblioteca dorită se leagă. De exemplu:
sc -sada somcm.idl
Emițătorul creează unul sau mai multe fișiere în formatul pe care îl înțelege compilatorul limbajului de programare selectat. Cu ajutorul acestor fișiere, devine posibil să se creeze obiecte din clasele descrise și să se numească metodele acestora.
În modul producător:
Dezvoltatorul își scrie propriile fișiere .idl, care #includ alte fișiere .idl și moștenesc din clasele descrise în alte fișiere .idl. Apoi, dezvoltatorul rulează un emițător special care va crea fișiere cu cod auxiliar și fișiere cu implementări goale ale metodelor de clasă.
De exemplu:
sc -sih animals.idl
sc -sc animals.idl
Primul apel va crea animals.ih, care va conține, de exemplu, o implementare a Animals_AnimalNewClass care va rula somBuildClass2, trecându-i o structură complexă sintetizată din intrarea .idl. În plus față de acest apel, acest fișier conține această structură în sine și alte câteva elemente auxiliare pe care dezvoltatorul nu ar trebui să le schimbe deloc. Al doilea apel va crea animale.c cu implementări de metode goale. Emițătorul C și C++ de la IBM poate funcționa în mod incremental, adăugând noi metode goale fără a atinge codul metodelor existente.
În plus, există emițători pentru crearea .dll. Emițătorul IMOD sintetizează funcția principală .dll, emițătorul DEF sintetizează fișierele .def și .nid.
Emițătorul este o bibliotecă numită emit*.dll, unde * este o opțiune pentru argumentul -s al compilatorului SOM. Biblioteca trebuie să exporte o procedură emit (SOM 2.1) sau emitSL (SOM 3.0) care, atunci când este apelată din compilatorul SOM, efectuează lucrări specifice emițătorului selectat. Munca poate fi oricare. Pentru a crea emițători noi, există un script newemit.
Emițătorii includ un emițător IR care creează sau actualizează baza de date binară SOM.IR. Această bază de date poate fi apoi deschisă folosind Interface Repository Framework. Acesta este cel mai frecvent utilizat pentru apeluri de procedură la distanță și limbaje de programare dinamică. Acesta este modul în care funcționează VisualAge SOMSupport pentru Smalltalk și ObjectREXX.
În plus, standardul OpenDoc include OpenDoc Direct Scripting (ODDS), iar interpreții de limbaj de scripting care implementează interfața ODScriptComponent pot accesa astfel clasele SOM prin ODDS. Un exemplu de astfel de limbaj de programare este Lotus Script, furnizat cu OpenDoc [5] .
Baza de date SOM.IR poate fi folosită și pentru a crea legături pentru limbaje de programare compilate [12] .
Novell a dezvoltat o punte care face obiectele SOM disponibile din limbi care acceptă automatizarea OLE. În plus, Novell ComponentGlue permite aplicațiilor care utilizează una dintre tehnologiile OLE sau OpenDoc să utilizeze componente realizate folosind o altă tehnologie, precum și să încapsuleze partea OpenDoc ca componentă OLE (OCX). Aceasta folosește utilitarul ctypelib . Când utilizați acest utilitar, nu este generat niciun cod de program în timpul compilării. Același DLL de la OpenDoc este înregistrat în registru, care este capabil să încarce biblioteca SOM în memorie și să creeze tabele de metode virtuale, tramburi și alte elemente necesare pentru obiectele COM proxy în timpul execuției. De obicei, ComponentGlue implementează doar interfața IDispatch, dar pentru a accelera lucrurile, este posibil să vă declarați și să implementați propria interfață COM prin marcarea interfeței SOM cu modificatorul ODdual și respectând toate regulile pentru interfețele OLE.
Un alt instrument pentru integrarea SOM și COM este utilitarul emitcom , care creează pachete COM pentru clasele SOM în C++. emitcom a fost inclus în SOM 3.0 Beta (februarie 1996), dar nu a fost inclus în SOM 3.0 Release (decembrie 1996), ca multe alte caracteristici.
Trebuie remarcat, totuși, că, deoarece COM nu face nimic pentru a rezolva problema fragilă a clasei de bază, ar trebui să fiți atenți la astfel de poduri. Wrapper-urile COM produse de emitcom corespund nugget-ului de interfață a clasei la momentul creării, iar atunci când interfața se schimbă, trebuie create noi versiuni ale wrapper-urilor cu noi GUID-uri de interfață COM care acceptă în continuare interfețele COM ale versiunilor vechi de wrapper. . Interfețele COM generate de utilitarul ctypelib pentru clasele SOM marcate cu modificatorul ODdual nu ar trebui utilizate din limbaje de programare compilate, deoarece reprezentarea la nivel scăzut a unei astfel de interfețe nu este stabilă. ctypelib suprascrie de obicei biblioteca de tip COM și nu există nicio prevedere pentru menținerea mai multor versiuni diferite ale unei interfețe în paralel.
Atunci când utilizați emițători în limbaje de programare compilate, cum ar fi C++, emițătorul C++ dă aspectul că clasa SOM este o clasă C++. somInit este mapat la constructorul standard, iar somAssign este mapat la operator=. Cu toate acestea, la implementarea claselor lor, scrierea .idl joacă un rol major, iar implementarea metodelor nu arată ca implementarea metodelor de clasă. Trebuie să apelați în mod constant compilatorul SOM pentru a actualiza fișierele. SOM se dovedește a fi ceva străin de limbajele de programare ale căror compilatoare nu au suport încorporat pentru SOM.
Compilatorul Direct-to-SOM C++ elimină nevoia de a scrie fișiere .idl. Fișierele .idl sunt generate pe baza fișierelor antet C++ DTS, nu invers. Astfel, compilatorul DTS C++ oferă un mediu de dezvoltare complet, omogen, care vă permite să scrieți totul într-o singură limbă. Lucrul cu som.dll în DTS C++ este similar cu lucrul cu objc.dll în Objective-C.
Emițătoarele sunt încă necesare, dar numai pentru importarea bibliotecilor terțe. Microsoft C++ are capacitatea de a scrie #import <something.tlb>. Același lucru ar putea fi făcut cu IDL în DTS C++, dar acest lucru nu a fost implementat. În schimb, trebuie să aplicați un emițător care va crea fișierele .hh necesare compilatorului DTS C++. Compilatorul DTS C++ acceptă atât clasele C++ obișnuite, cât și clasele SOM care moștenesc de la SOMObject (explicit sau implicit, cu #pragma SOMAsDefault (activat)). Ca și în cazul unui alt hibrid, Objective-C++, capacitatea de a amesteca clase din ierarhii diferite este limitată.
Direct-to-SOM C++ a apărut în MetaWare High C++ și a fost ulterior duplicat în VisualAge C++, în plus, aceste implementări nu sunt direct compatibile, doar prin import/export în .idl. În cartea „Putting Metaclasses to Work” a fost descris un al treilea dialect cunoscut al DTS C++, compilatorul pentru care încă nu există.
Există o implementare deschisă a SOM - somFree [13] . Proiectul pretinde compatibilitate binară cu implementarea originală de la IBM. Netlabs.org menține o implementare NOM care se bazează pe principiile SOM, dar nu este compatibilă nici cu sursa, nici binar.
API-uri OS/2 | Componente și|
---|---|
Principal | |
Servicii de management | |
Jocuri |
|
Nucleul OS | |
Sisteme de fișiere | |
Subsistemul grafic |
|
Model obiect | SOM
|
Compatibilitate |
|