close

Komponentowy model obiektowy

Przejdź do nawigacji Przejdź do wyszukiwania

Component Object Model (COM) to platforma Microsoft dla komponentów oprogramowania , wprowadzona w 1993 roku . Platforma ta służy do umożliwienia komunikacji między procesami oraz dynamicznego tworzenia obiektów, w dowolnym języku programowania obsługującym tę technologię. Termin COM jest często używany w świecie tworzenia oprogramowania jako termin ogólny dla technologii OLE, OLE Automation, ActiveX, COM+ i DCOM. Chociaż COM został wprowadzony w 1993 roku, Microsoft nie podkreślał nazwy COM aż do 1997 roku.

Zasadniczo COM jest sposobem implementacji obiektów neutralnych językowo, dzięki czemu można ich używać w środowiskach innych niż to, w którym zostały utworzone, poza granicami maszyn. W przypadku dobrze utworzonych komponentów COM umożliwia ponowne użycie obiektów bez wiedzy o ich wewnętrznej implementacji, ponieważ zmusza realizatorów komponentów do zapewnienia dobrze zdefiniowanych interfejsów, które są oddzielone od implementacji. Różne semantyki alokacji pamięci są uwzględniane przez uczynienie obiektów odpowiedzialnymi za ich własne tworzenie i niszczenie za pomocą licznika odwołań. Możesz rzutować między różnymi interfejsami obiektu za pomocą funkcjiQueryInterface(). Preferowaną metodą dziedziczenia w modelu COM jest tworzenie podobiektów, do których są delegowane wywołania metod (tzw. agregacja).

Chociaż te technologie zostały zaimplementowane na wielu platformach, są używane głównie z programem Microsoft Windows . Oczekuje się, że model COM zostanie zastąpiony, przynajmniej do pewnego stopnia, przez platformę Microsoft .NET i obsługę usług sieci Web za pośrednictwem programu Windows Communication Foundation (WCF). Sieciowy model DCOM używa zastrzeżonych formatów binarnych, podczas gdy WCF używa komunikatów protokołu SOAP opartych na języku XML . COM konkuruje również z CORBA i JavaBeans jako system komponentów oprogramowania.

Szczegóły techniczne

Programiści COM tworzą oprogramowanie przy użyciu komponentów oprogramowania zgodnych z COM. Różne typy składników są identyfikowane przez identyfikatory typu (CLSID), które są globalnie unikalnymi identyfikatorami lub identyfikatorami GUID. Każdy składnik COM ujawnia swoją funkcjonalność poprzez jeden lub więcej interfejsów. Różne interfejsy obsługiwane przez komponent są odróżniane od siebie za pomocą identyfikatorów interfejsów (IID), które są również identyfikatorami GUID.

Interfejsy COM mają implementacje w różnych językach, takich jak C, C++, Visual Basic i kilku językach skryptowych zaimplementowanych na platformie Windows. Cały dostęp do komponentów odbywa się za pomocą metod interfejsów. Pozwala to na stosowanie technik, takich jak przetwarzanie międzyoperacyjne, a nawet programowanie między komputerami (to ostatnie dzięki obsłudze DCOM).

Interfejsy

Wszystkie składniki COM muszą implementować co najmniej standardowy interfejs IUnknown , a zatem wszystkie interfejsy COM pochodzą od IUnknown . Interfejs IUnknown składa się z trzech metod: AddRef()i Release(), które implementują zliczanie odwołań i kontrolę cyklu życia interfejsu; i QueryInterface(), który poprzez określenie IID umożliwia wywołanie w celu pobrania odwołań do różnych interfejsów implementowanych przez komponent. Efekt QueryInterface()jest podobny do dynamic_cast <>C++ lub castingC# i Java.

Interfejsy składnika COM są wymagane do wyświetlania właściwości zwrotnych, symetrycznych i przechodnich. Właściwość odblaskowa odnosi się do zdolności wywołania QueryInterface(), dla danego interfejsu z identyfikatorem interfejsu, do zwrócenia tej samej instancji interfejsu. Właściwość symetryczna odnosi się do faktu, że gdy interfejs B jest pobierany z interfejsu A przez QueryInterface(), to interfejs A można również pobrać z interfejsu B. Właściwość przechodnia jest podobna do właściwości symetrycznej, ale wymaga, aby interfejs B mógł zostać pobrany z A, i C z kolei z B, wtedy interfejs C powinien być dostępny z A.

Interfejs składa się ze wskaźnika funkcji wirtualnej, który zawiera listę wskaźników do funkcji, które funkcja zadeklarowana w interfejsie implementuje, w tej samej kolejności, w jakiej zostały zadeklarowane w interfejsie. Ta technika przekazywania wskaźnika funkcji struktury jest bardzo podobna do tej używanej przez OLE 1.0 do komunikacji z systemem bibliotecznym.

COM określa wiele innych standardowych interfejsów używanych do komunikacji między komponentami. Na przykład jednym z nich jest IStream , który jest przeznaczony dla komponentów, które mają semantykę strumienia danych ( składnik FileStream używany do odczytu i zapisu plików). Ma oczekiwane metody Read i Write do wykonywania odczytów i zapisów strumienia. Innym standardowym interfejsem jest IOleObject , który jest przeznaczony dla komponentów, które mają być powiązane lub osadzone w kontenerze. IOleObject zawiera metody, które umożliwiają zainteresowanym stronom określenie rozmiaru granic składnika prostokąta, jeśli składnik obsługuje operacje, takie jak „Open” , „Save” i tak dalej.

Zajęcia

Klasa w modelu COM jest nazywana koklasą , która jest zakontraktowaną formą klasy Component Object . Koklasa jest sposobem COM na zdefiniowanie klasy w niezależnym od języka, zorientowanym obiektowo sensie. Koklasa dostarcza konkretną implementację jednego lub więcej interfejsów. W modelu COM takie konkretne implementacje można napisać w dowolnym języku programowania obsługującym tworzenie komponentów COM, takim jak C++, Visual Basic itp.

Jednym z największych wkładów COM w świat programistów Windows jest świadomość koncepcji oddzielenia interfejsu od implementacji. Ta świadomość niewątpliwie wpłynęła na sposób, w jaki programiści budują dzisiejsze systemy. Rozszerzeniem tej podstawowej koncepcji jest koncepcja jednego interfejsu, wielu implementacji. Oznacza to, że w czasie wykonywania aplikacja może wybrać instancję interfejsu z jednej z kilku konkretnych implementacji.

Biblioteki języków i typów definicji interfejsu

Biblioteki typów zawierają metadane reprezentujące typy COM. Jednak te typy muszą być najpierw opisane przy użyciu języka Microsoft Interface Definition Language (MIDL). Jest to powszechna praktyka podczas tworzenia komponentu COM, na przykład, gdy zaczynasz od definicji typów przy użyciu IDL. Plik IDL jest tym, co zapewnia model COM, który umożliwia programistom niezależne definiowanie klas, interfejsów, struktur, wyliczeń i innych typów zdefiniowanych przez użytkownika w języku. COM IDL jest podobny w wyglądzie do deklaracji C lub C++ z dodatkiem słów kluczowych, takich jak „interfejs” i „biblioteka” , odpowiednio do definicji interfejsów i kolekcji klas. IDL wymaga również użycia atrybutów w nawiasach przed deklaracjami w celu dostarczenia dodatkowych informacji, takich jak identyfikatory GUID interfejsów i relacje między parametrami wskaźnika i długości pól.

Plik IDL jest kompilowany przez kompilator MIDL na kilka sposobów do użytku w różnych językach. W przypadku języka C/C++ kompilator MIDL generuje niezależny od kompilatora nagłówek zawierający definicje struktur, które dopasowują funkcje wirtualne do deklaracji interfejsu oraz plik C zawierający identyfikatory GUID deklaracji interfejsu. Kod źródłowy C++ dla modułu Proxy może być również wygenerowany przez kompilator MIDL. Ten serwer proxy zawiera metody skrótowe do konwersji wywołań COM na RPC, na co zezwala DCOM.

Plik IDL może być również skompilowany przez kompilator MIDL do biblioteki typów (plik .TLB). Metadane binarne zawarte w bibliotece mają być przetwarzane przez kompilatory języka i środowiska uruchomieniowe (VB, Delphi, .NET CLR itp.). Efektem końcowym takiego przetwarzania TLB jest to, że tworzone są konstrukcje specyficzne dla języka, które reprezentują klasę COM zdefiniowaną w .TLB (i ostatecznie tę zdefiniowaną w pliku źródłowym IDL).

Liczenie referencji

Najważniejszy ze wszystkich interfejsów COM, tj. IUnknown (z którego muszą pochodzić wszystkie interfejsy COM), obsługuje dwie główne koncepcje: zapytania o funkcje (lub interfejsy implementowane przez obiekt) za pomocą metody queryInterface()oraz zarządzanie cyklem życia obiektu przez włączenie AddRef ()i Release (). Funkcja zliczania odwołań i zapytań dotyczy obiektów (nie każdego interfejsu) i dlatego musi mieć scentralizowaną implementację.

Specyfikacje COM wymagają techniki zwanej liczeniem odwołań, aby zapewnić, że różne obiekty są aktywne, o ile istnieją klienci, którzy uzyskali dostęp do jednego lub więcej ich interfejsów i odwrotnie, że ten sam obiekt jest prawidłowo usuwany, gdy cały kod jest teraźniejszość, która korzysta z przedmiotu, robi to z nim i już go nie potrzebuje. Obiekt COM jest odpowiedzialny za zwolnienie własnej pamięci po zmniejszeniu liczby odwołań do zera.

W celu wykonania obiekt COM na ogół zachowuje wartość, która jest używana jako odniesienie do zliczania. W przypadku wywołania AddRef ()przez dowolny z interfejsów obiektu ta wartość jest zwiększana. Gdy jest wywoływana Release(), ta liczba całkowita jest zmniejszana. AddRef ()i Release ()są jedynymi środkami, dzięki którym klient obiektu COM może wpływać na jego cykl życia. Wartość wewnętrzna pozostaje prywatnym elementem członkowskim obiektu COM i nigdy nie będzie bezpośrednio dostępna.

Instancja

COM standaryzuje proces tworzenia instancji (czyli tworzenia) obiektów COM, wymagając użycia klasy Factories . Dla każdego utworzonego obiektu COM muszą istnieć dwa skojarzone parametry:

  • Klasa ID .
  • Klasa Factory .

Każda klasa COM lub CoClass musi być powiązana z unikalnym identyfikatorem klasy (GUID). Musi być również powiązany z własną klasą Factory (co można osiągnąć za pomocą scentralizowanego rejestru). Klasa Factory sama w sobie jest obiektem COM. Jest to obiekt, który musi eksponować interfejs IClassFactory lub IClassFactory2 (ten ostatni z licencjami wsparcia). Odpowiedzialność takiego obiektu polega na tworzeniu innych obiektów.

Klasa Factory jest zwykle zawarta w tym samym kodzie wykonywalnym (czyli na serwerze kodu), co sam obiekt COM. Gdy klasa Factory jest wywoływana w celu utworzenia obiektu docelowego, celem tego obiektu jest identyfikator klasy, który należy podać. W ten sposób klasa Factory wie, którą klasę obiektu ma instancję.

Pojedyncza klasa obiektów Factory może tworzyć obiekty z więcej niż jednej klasy. Oznacza to, że ta sama klasa obiektów Factory może utworzyć dwa obiekty o różnych identyfikatorach klas. Jest to jednak niewidoczne dla systemu COM.

Delegując odpowiedzialność za tworzenie obiektu na oddzielny obiekt, osiąga się wyższy poziom abstrakcji, a programista ma większą elastyczność.

Aby aplikacje klienckie mogły uzyskać klasy obiektów Factory , serwery COM muszą je odpowiednio uwidaczniać. Klasa Factory jest uwidaczniana w różny sposób, w zależności od natury kodu serwera. Serwer oparty na bibliotekach DLL musi wyeksportować funkcję globalną DllGetClassObject (). Serwer EXE oparty na klasie Factory rejestruje się w czasie wykonywania za pomocą funkcji Windows API CoRegisterClassObject ().

Programowanie

COM jest standardem binarnym i może być opracowany w dowolnym języku programowania zdolnym do zrozumienia i implementacji zdefiniowanych typów danych binarnych i interfejsów.

Biblioteki uruchomieniowe (w sytuacjach ekstremalnych programiści) odpowiadają za wchodzenie i wychodzenie ze środowiska COM, tworzenie instancji i zliczanie referencji obiektów COM, obiekty za odpytywanie informacji o wersji, kodowanie do korzystania z zaawansowanych wersji obiektów.

Przejrzystość aplikacji i sieci

Do obiektów COM można tworzyć wystąpienia i odwoływać się w ramach procesu, poza granicami procesów w komputerze oraz w sieci przy użyciu technologii DCOM . Wyjście z procesu i zdalne obiekty mogą wykorzystać serializację do wysyłania wywołań metod i zwracania wartości w przód iw tył. Serializacja jest niewidoczna dla obiektu i kodu korzystającego z obiektu.

Krytyka

Komunikat o pompowaniu

Gdy STA jest inicjowana, tworzy ukryte okno, które jest używane do routingu wiadomości między mieszkaniami i między procesami. To okno powinno mieć regularnie pompowaną kolejkę wiadomości. Ta konstrukcja jest znana jako bomba wiadomości. W starszych wersjach systemu Windows niewykonanie tego może spowodować awarie całego systemu. Ten problem jest szczególnie nieprzyjemny, ponieważ niektóre interfejsy API systemu Windows inicjują model COM jako część swojej aplikacji, co powoduje wyciek szczegółów implementacji.

Liczenie referencji

Zliczanie odwołań w modelu COM może powodować problemy, jeśli dwa lub więcej obiektów jest cyklicznie przywoływanych. Projekt aplikacji musi to uwzględniać, aby obiekty nie były osierocone.

Obiekty mogą również pozostawić aktywne zliczanie odniesień, jeśli używanym modelem jest „przypadek zagłębienia” COM. Ponieważ obiekt, który uruchamia zdarzenie, potrzebuje odwołania do obiektu, aby zareagować na zdarzenie, liczba odwołań do obiektu nigdy nie osiąga zera.

piekło DLL

Ponieważ lokalizacja każdego składnika jest przechowywana w lokalizacji systemowej (w rejestrze systemu Windows), może być zainstalowana tylko jedna wersja określonego składnika. Dlatego COM bardzo cierpi z powodu piekło DLL , gdzie dwie lub więcej aplikacji wymaga różnych wersji tego samego komponentu.

Windows XP wprowadza nowy tryb rejestracji obiektów COM: „COM Free Registration”. Ta usługa umożliwia aplikacjom, które muszą zainstalować obiekty COM, przechowywanie wszystkich informacji rejestru potrzebnych do rejestracji COM w katalogu żądań, a nie w rejestrze globalnym, gdzie używane jest tylko jedno żądanie. piekło DLL można uniknąć dzięki COM bez rejestru, jedynym ograniczeniem jest to, że wymaga co najmniej systemu Windows XP lub nowszych wersji systemu Windows i że nie należy go używać do EXE, COM lub komponentów systemowych obejmujących cały serwer, takich jak MDAC , MSXML , DirectX lub Internet Explorer.

Referencje

Zobacz także

Linki zewnętrzne