Hook Contracts

Wprowadzenie

Hook to technologia interfejsu w Comarch ERP Enterprise, która może być używana do rozszerzania istniejącego kodu programu w sposób bezpieczny i bezkonfliktowy. Hooki są używane, jeśli dodatkowe kontrole funkcjonalne muszą być przeprowadzone dla rozszerzenia obiektu biznesowego w dostosowaniu lub aplikacji, która rozszerza standardowy kod, który uzupełnia istniejące kontrole w standardzie.

W przeciwieństwie do zamienników, istniejący kod programu może być wielokrotnie rozszerzany niezależnie od siebie za pomocą hooków.

Grupa docelowa

  • Programiści

Opis

Działanie hooków

Hooki są interfejsami pomiędzy dostawcą hooków a ich użytkownikami. Dostawca hooków definiuje metody w interfejsie Java (hook), które wywołuje w określonych sytuacjach. Użytkownik hooka implementuje wymagane hooki.

Przykład
Aby umożliwić rozszerzenie kontroli funkcjonalnej za pomocą hooków, dostawca hooków definiuje metodę

void validateUpdate(...)

i wywołuje tę metodę hooka oprócz istniejącej kontroli technicznej.

Użytkownik hooka zapewnia implementację metody. W implementacji metody użytkownik hooka przeprowadza kontrole i wysyła komunikaty do kolejki komunikatów programu w przypadku wystąpienia błędu.

Dostawca hooków udostępnia dane jako część interfejsu implementacji poprzez parametry metody hooka.

Ze względu na kierunek wywołania od dostawcy hooka do użytkownika, kontrola procesu pozostaje po stronie dostawcy hooka. Implementacje hooków mogą wpływać na dostawcę hooków tylko w zakresie zdefiniowanego interfejsu.

Przykład
Jeśli użytkownik hooka wyśle komunikat o błędzie do kolejki komunikatów programu w metodzie validateUpdate(), uniemożliwi to zapisanie obiektu. Użytkownik hooka nie może jednak pominąć innych kontroli ani wykonać innych działań dla jednostki biznesowej, ponieważ hook nie zapewnia takiej opcji.

Hook można zaimplementować wielokrotnie, dzięki czemu przykładowo sprawdzenie jednostki biznesowej można również utworzyć w innej aplikacji.

Dostępne hooki i ich implementacje są przechowywane w oddzielnych obiektach deweloperskich. Definicja Hook Contract zawiera oferowane hooki, podczas gdy zaimplementowane hooki są wymienione w implementacji Hook Contract.

Obiekty deweloperskie infrastruktury Hook

Definicje i implementacje Hook Contract
Definicje Hook Contract

Definicja Hook Contract zawiera powiązane hooki, np. wszystkie hooki na poziomie jednostki biznesowej dla określonej jednostki biznesowej. Jednak hooki z warstw logiki i dialogu dla tej samej jednostki biznesowej powinny być zawarte w oddzielnych definicjach Hook Contract.

Hooki są zwalniane do implementacji tylko przez definicję Hook Contract.

Definicje Hook Contract  są obiektami deweloperskimi typu Hook Contract, podtyp Definicja Hook Contract (XML: HOOK_DEFINITION). Jest to typ obiektu deweloperskiego XML. Dokładny opis elementów XML można znaleźć w artykule Obiekty deweloperskie.

Przykład
Przykład definicji Hook Contract, która zwalnia hook stanowy (HookState) i hook bezstanowy:

<?xml version="1.0" encoding="UTF-8"?>

<HookContract xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="HookXMLSchema.xsd">.

<HOOK_DEFINITION>

<contextClass>com.cisag.app.general.log.CountryEntity
</contextClass>

<hookState>

<interface>com.cisag.app.general.hook.log.SingleObjectEntityState
</interface>.

</hookState>

<hook>

<interface>com  .cisag.app.general.hook.log.SingleObjectValidateUpdateHook </interface>

</hook>

</HOOK_DEFINITION>

</HookContract>

Klasa kontekstu (contextClass) służy do identyfikacji definicji Hook Contract z kodu Java dostawcy hooka. Należy użyć klasy, której zachowanie może zostać rozszerzone przez hook.

Hook może być również zwolniony w kilku definicjach Hook Contract. Implementacja hooka zawsze odnosi się do definicji Hook Contract. Na przykład, te same hooki są często używane na poziomie logiki SingleObjectEntities. Jednak w każdym przypadku definicja Hook Contract odnosi się do jednego SingleObjectEntity.

Implementacje Hook Contract

Aby zaimplementować hook, oprócz jego implementacji (klasa Java) wymagana jest implementacja Hook Contract. Wszystkie hooki, które mają zostać zaimplementowane i odpowiednia klasa implementacji są określone w implementacji Hook Contract.

Dowolny podzbiór oferowanych hooków może zostać zaimplementowany w celu wdrożenia Hook Contract. Nie jest zatem konieczne implementowanie wszystkich hooków.

Implementacja Hook Contract jest obiektem programistycznym typu Hook Contract, podtyp Hook Contract Implementation (XML: „HOOK_IMPLEMENTATION”).

Przykład
Przykład implementuje oba hooki z powyższej definicji hook contract:

<?xml version=”1.0″ encoding=”UTF-8″?>

<HookContract xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”HookXMLSchema.xsd”>

<HOOK_DEFINITION>

<contextClass>com.cisag.app.general.log.CountryEntity
</contextClass>

 

<hookState>

<interface>com.cisag.app.general.hook.log.SingleObjectEntityState
</interface>

</hookState>

 

<hook>

<interface>com.cisag.app.general.hook.log.SingleObjectValidateUpdateHook
</interface>

</hook>

</HOOK_DEFINITION>

</HookContract>

Implementacja Hook Contract zawsze implementuje dokładnie jedną jego definicję. Jeśli dla danego zadania muszą zostać zaimplementowane różne definicje hook contract, dla każdej z nich wymagana jest osobna implementacja.

Poniższe zasady mają zastosowanie do wielu implementacji:

  • ten sam hook może być zaimplementowany kilka razy w implementacji hook contract. Ma to jednak zastosowanie tylko w szczególnych przypadkach, na przykład gdy wymagane są różne ograniczenia hooków.
  • w adaptacji lub aplikacji możliwe jest utworzenie kilku implementacji hook contract dla tej samej definicji. Ma to jednak zastosowanie tylko wtedy, gdy należy podzielić obiekty programistyczne w ramach większej adaptacji lub aplikacji.
  • hook stanowy z definicji hook contract może zostać zaimplementowany tylko raz w adaptacji (prefiks programistyczny) lub aplikacji. Jeśli istnieją inne implementacje definicji hook contract, implementacja hooka stanowego jest również tam dostępna (zakładając odpowiedni parametr metody).
Rozszerzalność definicji hook contract

Opublikowana definicja hook contract może zostać rozszerzona wyłącznie poprzez wprowadzenie nowych hooków. Istniejące hooki nie mogą być zmieniane retrospektywnie, tj. metody nie mogą być zmieniane, usuwane lub dodawane.

Uwaga
Hook nie może zostać usunięty z definicji hook contract, nawet jeśli jego interfejs okazał się niekompletny lub wadliwy. Wszystkie istniejące punkty wywołania muszą zostać zachowane (wyjątki, patrz Przestarzałe poniżej).

W takim przypadku definicje hook contract powinny zostać uzupełnione o nowy hook. Interfejs Java nowego hooka nie może jednak dziedziczyć po starym hooku ani powielać metod starego hooka. W razie potrzeby implementacje hooków mogą jednocześnie korzystać z metod starego i nowego hooaka.

Przestarzałe znaczniki są możliwe w definicjach umów hooków (znacznik Rejected na obiekcie deweloperskim) i hooków (adnotacja @Deprecated w kodzie Java). Obiekty deweloperskie można następnie usunąć w kolejnym wydaniu. Jednak przestarzałe znaczniki powinny pozostać wyjątkiem dla definicji hook contract, hooków i stanów hooków, ponieważ pogarszają one bezpieczeństwo wydania.

Hooki

Hooki są interfejsami Java w przestrzeniach nazw dostawcy hooków. Istnieją hooki:

  • bezstanowe
  • stanowe

Hook jest zaimplementowany w klasie Java, która sama implementuje jego interfejs. Każda implementacja hooka musi być wymieniona w implementacji Hook Contract.

Hooki bezstanowe

Hooki bezstanowe zawierają metody hooków, które są wywoływane przez dostawcę hooków w określonych sytuacjach. Hooki bezstanowe rozszerzają interfejs com.cisag.pgm.base.Hook.

Implementacje muszą być CisFactory-Singletons  i posiadać domyślny konstruktor. Ich czas życia jest zazwyczaj krótki. Są one generowane przez silnik systemu, gdy tylko dostawca hooków wywoła odpowiednie metody w CisHookManager.

Możliwe jest zaimplementowanie kilku hooków w tej samej klasie Java.

Kolejność wywołań

Hook może być implementowany wielokrotnie. Metody hooków są zwykle wywoływane kolejno we wszystkich implementacjach, chyba że dla danego hooka przewidziano inną procedurę.

Kolejność wywołań jest określana przez silnik systemowy i nie może być modyfikowana przez implementacje hooków. Nie jest zdefiniowana żadna konkretna kolejność wywołań dla implementacji hooków.
Z tego powodu różne implementacje tej samej metody hooka nie powinny być od siebie zależne.

Parametry metod

Parametry metod hooków stanowią część interfejsu. Dane dostawcy hooków, do których implementacja hooka ma mieć dostęp, są przekazywane jako parametry.

Najczęściej używane parametry w metodach hooków:

  • widok obiektu zawiera dane jednostki biznesowej. Niektóre dane wewnętrzne mogą nie być zawarte w widoku obiektu. Widoki obiektów mogą mieć następujące poziomy dostępu:
    • tylko do odczytu
    • ograniczona możliwość zapisu – pozwala na zapis tylko atrybutu z rozszerzeń jednostek biznesowych z własnym prefiksem deweloperskim.
    • nieograniczona możliwość zapisu
  • Instancja hooka z obsługą stanów

     

Izolacja kolejki komunikatów programu

Każda implementacja hooka jest odizolowana od komunikatów z innych implementacji tego samego hooka w ramach wywołania metody. Oznacza to, że komunikaty z innych hooków, a także od samego dostawcy hooka, nie są widoczne w implementacji hooka. Ta izolacja jest wykonywana automatycznie przez silnik systemu.

Wyjątki w metodach hook

Metody hook nie powinny przewidywać wyjątków w swoim interfejsie. Wyjątki mogą być zgłaszane przez implementację hook tylko w przypadku błędów programistycznych. W przypadku wystąpienia wyjątku, wywołanie wszystkich implementacji hooka dla tego samego wywołania hooka zostaje przerwane.

Ograniczenia hook

Bezstanowe hooki mogą być dostarczane z ograniczeniem hooka. Jego ograniczenie powoduje wywołanie implementacji hooka z dodatkowymi warunkami. Podczas wywoływania hooka, dostawca hooka określa obiekty deweloperskiego jako ograniczenie hooka. Infrastruktura hooków wybiera do wywołania tylko te implementacje hooka, które używają tych samych obiektów deweloperskich jako ograniczenie. Klasy Java (Java Class), obiekty biznesowe (Business object), logiczne typy danych (logical data type), widoki obiektów (Data view) i aplikacje (Application) mogą być używane jako obiekty deweloperskie.

Ograniczenie hooka jest określone w XML definicji hook contract i implementacji hook contract dla hooku, który ma być ograniczony. Typ i identyfikator są określone dla każdego obiektu deweloperskiego w definicji hook contract:

<hook>

…

<interface>…</interface>

<restriction>

<businessObject id=”objectClass”/>

</restriction>

In der Hook-Contract-Implementierung muss nun das Business Object selbst angegeben werden:

<hook>

…

<interface>…</interface>

<restriction>

<businessObject id=”objectClass”>

com.cisag.app.production.obj.ProductionItem
</businessObject>

</restriction>

<implementation>…</implementation>

Implementacja hook oznaczona w ten sposób jest wywoływana tylko wtedy, gdy dostawca hooka określa ten sam obiekt biznesowy (Business Object)podczas jego wywoływania.

Ograniczenia hooków są szczególnie przydatne w definicjach hook contract, które mają zastosowanie do wielu jednostek biznesowych. Przykładem takich zastosowań są BIS-Hooks.

Więcej informacji na temat sprawdzania ograniczeń można znaleźć w rozdziale Wskazówki dotyczące rozwoju.

Składnia XML:

Definicja pojedynczego ograniczenia w definicji hook contract:

<restriction type id="identifier" [optional="boolean"]/>

Dozwolone typy ograniczeń:

  • javaClass dla klas Java
  • dataView dla widoków obiektów
  • businessObject dla obiektów biznesowych
  • logicalDatatype dla logicznych typów danych
  • Application dla aplikacji

Identyfikator musi być unikalny w ramach bloku ograniczeń.

Atrybut optional wskazuje, czy ograniczenie jest opcjonalne (true), czy nie (false). Jeśli nie zostanie określony, ograniczenie jest domyślnie wymagane.

Definicja pojedynczego ograniczenia w implementacji hook contract:

<restriction type id="identifier">

    Nazwa obiektu deweloperskiego

</restriction type>

Zamiast określonego obiektu deweloperskiego można również użyć symbolu wieloznacznego „*”. Więcej informacji na temat sprawdzania ograniczeń można znaleźć w rozdziale Wskazówki dotyczące rozwoju.

Implementacje

Poniższy przykład przedstawia implementację hooka z dostępem do hooka stanowego udostępnianego przez widok obiektu.

Implementacje hooka bezstanowego HookImpl i hooka stanowego StateImpl, są zaimplementowane w tej samej adaptacji lub w tej samej aplikacji. Za pomocą pomocniczej metody getState() implementacja hooka uzyskuje dostęp do „swojej” implementacji hooka z obsługą stanów.

public class HookImpl implements SingleObjectValidateUpdateHook {
 private final CisHookManager hm = CisEnvironment.
 getInstance().getHookManager();
 @Override
 public void validateUpdate( CountryView view) {
 CountryHookStateImpl hookState = hm.getState(
 view.getHookState(), CountryHookStateImpl.class);
 // method implementation
 }
} 
Generics

Hooki, które są używane w kilku definicjach hook contract, często określają widoki obiektów jako parametry ogólne, aby móc abstrahować od konkretnej jednostki biznesowej definicji hook contract. W implementacji takiego hooka parametry generyczne powinny zostać zinstancjonowane w odniesieniu do widoku obiektu odpowiadającego danej definicji hook contract.

Przykład
Poniższy hook jest oferowany przez definicję hook contract Country:

interface SingleObjectValidateUpdateHook<V extends DataView<?>>

Ponieważ hook jest również używany w innych definicjach hook contract, zamiast CountryView określono tylko DataView<?>. W implementacji hook contract dla definicji hook contract Country należy teraz określić CountryView.

public class CountryHookImplementation implements
SingleObjectValidateUpdateHook<CountryView>

Hooki z obsługą stanów

Hooki stanowe (HookState) dają ich użytkownikom możliwość utrzymywania stanu pomiędzy kilkoma wywołaniami hooków. Na przykład, dane zależne lub inny stan aplikacji mogą być przechowywane w HookState. Hooki stanowe rozszerzają interfejs com.cisag.pgm.base.HookState.

W większości przypadków hooki stanowe nie mają metod, ale są dostępne w metodach hooków bezstanowych. Jednak hook stanowy jest zwykle zawarty w widoku obiektu.

Hooki stanowe mają zdefiniowany cykl życia. Implementacje są tworzone przez silnik systemu i zarządzane przez dostawcę hooaków. Od dostawcy hooków zależy, ile obiektów klasy implementacji jest faktycznie tworzonych. Oddzielny obiekt HookState jest tworzony dla każdej instancji aplikacji dialogowej.

Jeśli hook z obsługą stanów deklaruje metody, obowiązują dla nich te same zasady, co dla metod Hook. Jeśli zadeklarowana jest metoda

void clone()

to jej implementacja musi tworzyć kopię obiektu HookState.

Implemetacje

HookStates muszą być zawsze zaimplementowane w oddzielnej klasie Java ze względu na ich cykl życia. Interfejs HookState zwykle nie zawiera żadnych atrybutów i metod, a użytkownik hook może zdefiniować dowolne atrybuty i metody, jak w poniższym przykładzie:

public class StateImpl implements AHookState {

private String s;

public StateImpl() {

// może zainicjować atrybuty

}

public String someMethod() {

// ...

}

}

Każda implementacja HookState musi posiadać domyślny konstruktor.

Centralne interfejsy hook

Interfejsy hook, które są wykorzystywane przez wiele definicji hook contract, np. przez jednostki biznesowe korzystające z infrastruktury SingleObjectEntity, są zawarte w następujących przestrzeniach nazw:

  • com.cisag.app.general.hook.log (dla hooków logicznych)
  • com.cisag.app.general.hook.ui (dla hooków interfejsu dialogowego)
Klasy bazowe hooków

Hook, oprócz swojego interfejsu Java, może zawierać dodatkowo abstrakcyjną klasę bazową. Implementacje Hook mogą wówczas według własnego uznania dziedziczyć z tej klasy bazowej zamiast bezpośrednio implementować interfejs Java. Dzięki klasie bazowej implementacje Hook muszą zaimplementować tylko część metod Hook.

Jeśli istnieje klasa bazowa, jest ona definiowana jako klasa wewnętrzna w interfejsie Java pod nazwą Base.

CisHookManager

Hooki są wywoływane w kodzie Java dostawcy hooków za pośrednictwem interfejsu PGM CisHookManager.

CisHookManager używa kontenerów hook , aby oddzielić dostawcę hooków od liczby dostępnych konkretnych implementacji hook. Możliwy jest jednak również dostęp do poszczególnych ich implementacji.

Wywoływanie metod hook

Metody hook mogą być wywoływane zarówno w kontenerze hook, jak i bezpośrednio w implementacjach hook. Kontener hook jest proxy Java i w ten sposób implementuje odpowiedni interfejs hook.

Wywołanie kontenera hook automatycznie prowadzi do wywołania wszystkich implementacji, a jego wywołanie jest możliwe tylko wtedy, gdy metoda hook używa typu zwracanego void.

Poniższy przykład pokazuje wywołanie kontenera, gdzie hm jest CisHookManager, contextClass jest klasą kontekstu wywoływanej definicji hook contract, a dataView (data view) jest używany jako parametr hook.

SingleObjectValidateUpdateHook hook =hm.getHookContainer(

contextClass, SingleObjectValidateUpdateHook.class);

hook.validateUpdate(dataView);

To samo wywołanie hook we wszystkich implementacjach wygląda następująco:

for (SingleObjectValidateUpdateHook hook :
hm.getHookImplementations(contextClass,
SingleObjectValidateUpdateHook.class) {

hook.validateUpdate(dataView);

}

W przypadku metod hook z typami zwracanymi innymi niż void, do poniższego przykładu należy dodać kombinację wartości zwracanych.

Jeśli hook wymaga ograniczeń, należy je określić jako dodatkowe parametry w metodach

hm.getHookContainer lub hm.getHookImplementations:

HookRestriction res = HookRestriction.create

(HookRestriction.restrictBusinessObject("object",

com.cisag.app.general.obj.Partner.class),

HookRestriction.restrictDataView("view",

PurchaseContractDetailView.class));

SingleObjectValidateUpdateHook hook =hm.getHookContainer(

contextClass, res, SingleObjectValidateUpdateHook.class);

Istnieją specjalne hooki (strategie, ActionHooks), dla których metody hook muszą być wywoływane tylko w niektórych implementacjach, ale nie we wszystkich. W takim przypadku można wywołać tylko implementację. HookContainer nie może być używany.

 Zarządzanie hookami z obsługą stanów

Implementacje HookState są zarządzane w kontenerach HookState. Kontener HookState jest tworzony przez dostawcę hooków przy użyciu następującej metody:

CisHookManager.createStateContainer(contextClass,hookStateClass) CisHookManager.createStateContainer(contextClass,hookStateClass)

Obiekt kontenera zawiera wszystkie implementacje HookState, które istnieją dla żądanej definicji hook contract (contextClass) i hooka stanowego (hookStateClass).

Dostawca hooków nie ma dostępu do poszczególnych implementacji HookState. Zamiast tego musi przekazać kontener podczas tworzenia widoku obiektu, aby implementacje były dostępne w hookach.

Hooki w hierarchiach dziedziczenia

W przypadku, gdy wielu dostawców Hook jest zintegrowanych w strukturę dziedziczenia, taką jak SingleObjectEntity, i te same Hooki mają być udostępniane, warto przenieść wszystkie wspólne elementy między dostawcami Hook do klas bazowych struktury dziedziczenia.

Podobne definicje hook contract często różnią się tylko klasą kontekstu i konkretnym typem widoku obiektu. Są to jedyne aspekty, które muszą być zdefiniowane w podklasach hierarchii dziedziczenia.

Infrastruktura hook pozwala również poszczególnym podklasom na brak definicji hook contract, nawet jeśli nadklasa wywołuje metody hooka. W tym celu CisHookManager zawsze zwraca pusty kontener hooków, jeśli jako klasa kontekstu zostanie przekazana wartość null. Wywołanie metod hook nie ma wtedy żadnego efektu.

Określanie klasy kontekstu

Klasa kontekstu nigdy nie powinna być określana dynamicznie (np. this.getClass()), ale zawsze powinna być określona jako stała (com.cisag.app…X.class). W przeciwnym razie niewłaściwa klasa kontekstu zostanie użyta w przypadku zastąpienia klasy dostawcy hook (Replacement).

Wskazówki dotyczące rozwoju

Aby wersja obiektu deweloperskiego hook contract (definicja hook contract, implementacja hook contract) zablokowana w zadaniu deweloperskiego mogła być używana przez serwer aplikacji systemu ERP (SAS) w czasie wykonywania, katalogi zadania deweloperskiego (dla blokady w zadaniu lub blokady lokalnej) muszą być dostępne w ścieżce klas. Dotyczy to w szczególności skompilowanych klas Java w katalogu klas zadania deweloperskiego. W przeciwnym razie SAS używa aktywnej wersji obiektu deweloperskiego.

Po utworzeniu nowego obiektu deweloperskiego hook contract, obiekt deweloperski musi zostać zapisany co najmniej raz, aby SAS mógł użyć obiektu deweloperskiego w czasie wykonywania.

Podczas uruchamiania SAS należy zwrócić uwagę na komunikaty o błędach i ostrzeżeniach z infrastruktury hook w pliku dziennika lub w konsoli. Komunikaty te wskazują, czy określone definicje hook contract lub implementacje hook contract są niespójne.

Implementacje hook contract, które nie są spójne, nie są brane pod uwagę przez infrastrukturę hook w czasie wykonywania SAS, tj. stany hooków nie są generowane, a metody hooków z tej implementacji hook contract nie są wywoływane.

Definicje hook contract, które nie są spójne, nie są brane pod uwagę przez infrastrukturę hooków, podobnie jak wszystkie implementacje hook contract dla tej definicji hook contract.

Weryfikacja ograniczeń

Podczas sprawdzania spójności istniejących implementacji hook (podczas uruchamiania serwera aplikacji) muszą być spełnione następujące warunki, aby implementacja była prawidłowa:

  • dla każdej restrykcji zadeklarowanej w implementacji hook musi istnieć odpowiednia restrykcja zadeklarowana w definicji
  • dla każdej restrykcji zadeklarowanej jako nieopcjonalna w definicji Hook musi istnieć odpowiednia restrykcja w implementacji.

Definicja restrykcji jest zgodna z deklaracją w implementacji, jeśli zarówno identyfikator, jak i typ są identyczne.

Możliwości określenia odpowiednich implementacji w czasie wykonania:

  • metody dwuelementowe – metody getHookImplementations (klasa kontekstu, interfejs hook) oraz getHookContainer (.,.) nie uwzględniają restrykcji w czasie wykonania i dlatego określają wszystkie implementacje interfejsu bez sprawdzania zgodności z istniejącymi definicjami ograniczeń implementacji.
  • metody trzyelementowe – metody getHookImplementations (klasa kontekstu, ograniczenie, interfejs haok) i getHookContainer (.,.,.) otrzymują listę ograniczeń. Mają one następujący wpływ na wybór implementacji:
    • lista nie musi zawierać wszystkich ograniczeń zadeklarowanych przez implementację. Jednak każde przekazane ograniczenie w czasie wykonania musi być zgodne z ograniczeniem zadeklarowanym w implementacji hook. Oznacza to, że tylko przekazane restrykcje w czasie wykonania ograniczają wybór implementacji, natomiast brakujące restrykcje nie mają wpływu.

Ograniczenie w czasie wykonania jest zgodne z deklaracją implementacji, jeśli identyfikator, typ i wartość obiektu deweloperskiego są identyczne. Jeśli symbol wieloznaczny „*” jest określony w deklaracji implementacji zamiast konkretnego obiektu deweloperskiego , wszystkie wartości tego obiektu są dozwolone, tylko identyfikator i typ muszą być nadal zgodne.

Deklaracja ograniczenia jako opcjonalnego (w definicji hook) nie ma wpływu na określenie odpowiednich implementacji.

Zależność instalacji

Określenie interfejsu i klasy implementacji w implementacji hook contract tworzy zależność instalacyjną między aplikacją dostawcy, która zapewnia interfejs, a aplikacją użytkownika z jej implementacją hook contract. Artykuł Komunikacja aplikacji bez zależności instalacyjnych opisuje możliwości unikania tej zależności.

Czy ten artykuł był pomocny?