IoC a DI

J1
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad rok
  • Postów:104
0

Cześć. Zmagam się ze zrozumieniem pojęć i różnic pomiędzy IoC a DI. Nigdy nie przykuwałem do tego uwagi, po prostu wiedziałem jak się powinno pisać kod.
Nie powinienem robić aby jakaś klasa zależała od drugiej, czyli pisać w klasie Test Class class = new Class();, tylko powinienem wstrzykiwać tę klasę do konstruktora klasy Test. Plusy znam, łatwe utrzymanie, można takie klasy testować zmieniając implementacje.

No ale właśnie, wiem jak to się robi, nie wiem co to dokładnie oznacza. Zawsze mi się wydawało, że to co u góry napisałem, to jest wstrzykiwanie zależności. Gdzieś nad tą klasą tworzę obiekt, który wstrzykuje i to jest właśnie Dependency Injection.

Czy Inversion Of Control jest to cały koncept tego tak jakby? Cały zamysł, a DI to jest tak jakby sposób tego zrobienia?

Przemaglowałem już wiele stron zaczynająć od SO, kończąc na jakiś udziwnionych ścianach tekstu, ale nie mogę tego do końca zrozumieć.
Może mnie ktoś oświecić?

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
2

IoC to jest forma DI. DI oznacza, że przez konstruktor wstrzykujesz zależności np:

Kopiuj

public final class UserService {

private final UserRepository userRepository;

public UserService(UserRepository userRepository) {
this,userRepository = userRepository;
}

//reszta kodu
}

Teraz możesz po prostu zamiast w mainie tworzyć cały graf zależności (czyli wywoływać new i przekazywać kolejne reference) użyć do tego kontenera IoC, ale idea jest ta sama. Kontener IoC ma swoje plusi i minusy, jak to ze wszystkim ;)
PS
Można też wstrzykiwac np. przez settery, ale to bardzo głupie, więc założ że tylko przez konstruktor :P


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: ŁF
J1
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad rok
  • Postów:104
0

Tak, te wszystkie wstrzykiwania znam.
Czyli załóżmy samo tworzenie obiektu w mainie i przesyłanie go do konstruktora to DI? A zamysł wywalenia new z klasy UserService to jest IoC?

edytowany 1x, ostatnio: ŁF
S9
Nie cytuj całego posta jeśli jest wyżej i odnosisz się co calosci
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

DI to znaczy że dostarczasz z zewnątrz zależności, a kontener IoC oznacza ze oddelegowujesz do tego framework np. Spring-a


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
13
  1. IoC to pewna idea i nie należy jej mylić z Dependency Inection ani z kontenerami IoC. IoC do kontenera IoC ma się tak jak krzesło do krzesła elektrycznego.
  2. IoC mówi tylko o tym, żeby nie wiązać się ze szczegółami implementacji innych modułów, a jedynie z kontraktami jakie wystawiają. Dany moduł powinien skupiać sie na wykonywaniu swoich zadań i nie powinien wiedzieć niczego o innych modułach, poza kontraktem/interfejsem jaki oferują. Możemy dzięki temu podmienić moduły na inne i póki kontrakty są poprawne, wszystko musi działać.
  3. DI to sposób realizacji IoC -> wstrzykujemy do modułów implementacje, z których one, poprzez jasno zdefiniowany interfejs, korzystają. Ale to nie jest jedyne rozwiązanie, jakiś ServiceLocator czy Factory też może być realizacją IoC.
  4. Kontener IoC to jest sposób realizacji DI, gdzie składaniem obiektów i wstrzykiwaniem zależności zajmuje się kontener

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
J1
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad rok
  • Postów:104
0

Dostarczam z zewnątrz z zależności, czyli przesyłam do konstruktora.

scibi92 napisał(a):

a IoC oznacza ze oddelegowujesz do tego framework np. Spring-a

W tym wypadku nie mam żadnego framework'a, to o co chodzi :D

Aventus
  • Rejestracja:prawie 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
2

Można też wstrzykiwac np. przez settery ale to bardzo głupie

Pozwolę sobie dodać coś od siebie bo scibi podał bardzo skąpą "argumentację" ;) Otóż przy definiowaniu zależności jako parametry konstruktora deklarujemy kontrakt danej klasy. Oznacza to że już na etapie tworzenia instancji obiekt musi posiadać poprawny stan, a my w konstruktorze możemy przeprowadzić niezbędną do tego walidację. Wstrzykiwanie zależności poprzez właściwości niczego nie gwarantuje, a nowo utworzony obiekt będzie miał duże prawdopodobieństwo posiadania niewłaściwego stanu jeśli jakaś zależność nie została wstrzyknięta. Z tego też powodu jeśli tylko możliwe należy tego unikać.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
J1
co oznacza kontrakt danej klasy? jakiś przykład bądź coś, bo Shalom też napisał "IoC mówi tylko o tym, żeby nie wiązać się ze szczegółami implementacji innych modułów, a jedynie z kontraktami jakie wystawiają. " i nie wiem czym są te konrakty.
Aventus
@jajko1233: kontrakt klasy czy też metody definiuje co dana klasa/metoda oczekuje w postaci argumentów, oraz co zwraca lub jakie operacje wykonuje. Dla przykładu kontrakt metody która dodaje dwie liczby może wyglądać tak: "int add(int x, int y)". Dzieki temu wiesz co musisz przekazać, oraz czego się spodziewać w zamian.
J1
Nie o to mi chodziło, nie wiem czym jest sam kontrakt, kontrakt może być między equals a hashCode i to rozumiem, coś jak umowa, a przy definiowaniu zależności jako parametry konstruktora deklarujemy kontrakt danej klasy. już nie rozumiem. Czy Tobie chodzi o to, że w konstuktorze klasy mamy np. construcotr(Service service) { this.service=service} ?
Aventus
Przecież podałem Ci przykład- nazwa metody, wraz z listą jej parametrów oraz zwracanym typem jest jej kontraktem. Analogicznie, konstruktor klasy wraz z parametrami (w sensie sam "nagłówek" konstruktora) jest kontraktem klasy. Chociaż to akurat uproszczenie, bo kontrakt klasy można też rozumieć jako szersze pojęcie, mianowicie jako zbiór konstruktorów oraz publicznych metod tejże klasy. Natomiast w kontekście tworzenia instancji klasy, to faktycznie sam konstruktor jest jej kontraktem, ponieważ jasno komunikuje wymagane zależności.
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Przede wszystkim użycie konstruktora oznacza że obiekt jest gotowy od razu do użycia i pozwala uniknąc mutowalności. Jesli współdzielimy referencję np. do jakiegoś serwisu a korzystamy z setterów to ktoś może na chama podmenić implementacje i to rozpropagować dalej.Oczywiście tak na ogół się nie zdarza, ale nie jest to wykluczone.


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Aventus
Nie przede wszystkim, a również ;) "użycie konstruktora oznacza że obiekt jest gotowy od razu do użycia" to jest dokładnie to co opisałem wyżej.
S9
No tak, ale nie napisałes o mutowalności :p
baant
zawsze można dać konstruktor + wystawić jeszcze setter. Dla odważnych :D
S9
Nie jeśli masz pola oznaczone jak final. A ja tak oznaczam :)
Aventus
@baant: to jeden z tych momentów zaczynających się od "potrzymaj mi piwo" ;)
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
4

@jajko1233:

co oznacza kontrakt danej klasy?

Możesz go dla uproszczenia utożsamić z interfejsem klasy która jest twoją zaleznością.
Wyobraź sobie że piszesz system który wczytuje dane skądś i zapisuje je w jakiejś postaci. Jak mogło by to wyglądać?

Kopiuj
class Loader{
    private final DataCollector dataCollector;
    private final DataSaver dataSaver;

    public void execute(){
        dataSaver.saveData(dataCollector.collectData());
    }
}

Zauważ że nie interesuje nas tutaj czy DataSaver to jest JSONDataSaver czy CSVDataSaver albo DataBaseDataSaver. Interesuje nas tylko, że obiekt który dostaniemy spełnia pewien kontrakt -> dostaje dane i zapisuje je, w sobie znany sposób.
Analogicznie ten nasz DataCollector może pobierać dane z różnych miejsc, w różny sposób, jest to dla nas obojętne o ile spełnia kontrakt -> pobiera dane i zwraca je w odpowiedniej postaci.

Zauważ ze napisaliśmy właśnie kawałek kodu, który może później działać z obiektami które nie istniały kiedy to pisalismy. Za 10 lat napiszesz sobie QuantumSingularityDataSaver, wrzucisz go tutaj i wszystko będzie nadal działać! Nie musimy tego kodu w ogóle ruszać, bo on w ogóle nie wie nic o żadnych konkretnych implementacjach. Będzie działać dla każdego obiektu który spelnia oczekiwany kontrakt.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
J1
Już rozumiem, dzięki wielkie!
neves
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 19 godzin
  • Lokalizacja:Kraków
  • Postów:1114
2

Tak jak już wyżej zostało podkreślone IoC to ogólna idea, polegająca na odwróceniu kontroli, która jest implementowana na kilka sposobów:

dependency injection zamiast tworzyć obiekt samemu, niech ten obiekt zostanie dostarczony z zewnątrz
dependency inversion zamiast polegać na jakimś interfejsie, to ja zdefiniuje interfejs jaki oczekuje i niech mi dostarczą obiekt który spełnia ten interfejs
events zamiast odpytywać czy stan się zmienił w systemie, niech system mnie poinformuje o zmianie (jedna z implementacji to chociażby wzorzec obserwator)
aspect-oriented programming zamiast wywoływać samemu powtarzający się kod (crosscutting concern), niech to ten powtarzający kod sam się wywoła i nie zawraca mi głowy

kolejność w tabelce jest nieprzypadkowa, im niżej tym więcej kontroli oddajemy na zewnątrz, co jest zwykle wygodne z punktu widzenia programisty, tyle że wtedy w systemie się pojawia magia i skoro oddaliśmy tą kontrolę to ciężej jest zapanować nad systemem.

A nazwa kontener IoC się wzięła właśnie stąd, że zwykle taki kontener umożliwia nie tylko DI ale też zwykle inna implementację IoC chociażby aspekty.


jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:32 minuty
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4706
1

Nie wiem skąd się nagle wzięło w temacie Aspect oriented Programming, ale warto pamiętać, że to rak. Niektórzy mówią, ze gorszy od GOTO.
Ślepa ścieżka ewolucji programowania obiektowego. Polecam nie zblizać się jesli nie trzeba.
AOP można użyć przy debugowaniu skomplikowanych bugów lub ewentualnie w monitoringu. Pchanie tam czegokolwiek, co jest ważne dla aplikacji (transakcje, security, itp ), to recepta na katastrofę.
Niestety czołowe frameworki javowe tak robią, ale warto chociaż nie dokładać swojego kamyczka.

Alternatywą sensowniejszą dla AOP jest Monada, a w szególności Free Monad.
Problemy łapiemy na etapie kompilacji (a nie w runtime), a do tego możemy łatwo testować zarówno z aspektami, jak i bez.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 2x, ostatnio: jarekr000000
Zobacz pozostałe 2 komentarze
S9
No ok, ale nie jestem jak rozumieć komentarz :P Nie zauważyłem zbyt duzo problemów związnych ze stosowaniem aspektów przez Springa, chociaż jeśli to możliwe wole kompozycje
jarekr000000
Z GOTO i zmennymi globalnymi wielu ludzi też nie widzi problemu.
somekind
@scibi92: ja komentowałem post, nie Twój komentarz. :) @jarekr000000: problemem nie jest używanie noży tylko krojenie nim swoich palców zamiast chleba. Widziałem milion sposób na zepsucie kodu bez goto, zmiennych globalnych i aspektów.
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

@jarekr000000: sądze że aspekty w typowej aplikacji biznesowej do zarządzania transakcjami czy security są całkiem OK, choć faktycznie sądze że lepiej by default korzystać z innych narzędzi i prawde powiedziawszy nie monad tylko klasycznego obiektowego rozwiązania


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:32 minuty
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4706
0

Decorator niestety uwypukla biedę programowania obiektowego, ale oczywiście, że to lepsze niż ** Stringly typed** AOP.
Poza tym, naprawdę nie sądzę, że jakiś poważniejszy biznes powinien swoje działanie opierać na tym, że akurat kontener będzie miał lepszy dzień, wstaną te aspekty co trzeba i dzieki szcześciu jeszcze podepną się do tych co trzeba metod (bo nikt nie zmieni nazw). Mam jeden projekt gdzie security tzw. runAs przypasowane jest nazwami metod i klas. Miodzio :/


jeden i pół terabajta powinno wystarczyć każdemu
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Spring Security działa całkiem dobrze z tego co zauważyłem. No i powiedz mi co jest biednego w tych decoratorach i OOP? Bo jak dla mnie OOP jest tak samo dobre jak FP w większości projektów. Odnosze wrażenie że czasami na siłe próbujesz wpychać FP tam gdzie nie trzeba...


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:32 minuty
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4706
0

Tu Mario mści sie na decoratorach (między innymi)

Nic nie usiłuję wpychać. Filozofię wyjaśnia to video:
https://vimeo.com/90738761#t=28m42s

(od wskazanego miejsca - reverse list of bananas)


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 2x, ostatnio: jarekr000000
S9
Chętnie obejrze jak będe miał czas, choć wątpie żebym przestał stosować wzorce :)
jarekr000000
Są podobne wideo jeszcze od Teda Newarda i innych. Generalnie dużo wzorców to tylko zapchajdziury dla brakujących featerow w języku. Nie ma sensu ich stosować jeśi twój język trochę dorósł. A może raczje- nie ma sensu wprowadzać specjalnej nazwy i się ceregielić jeśli jest bardziej ogólna koncepcja, która to pokrywa. (W tym wideo : high order function).
S9
Dobra obejrzałem odnosnie dekoratora. Generalnie częściowo mówi prawde, ale nie wszystko da sie się sprowadzić do lambd i funkcji... Jednak OOP w pewnych miejscach będzie lepsze of FP, taka jest moja opinia.
BZ
Źle mi się kojarzy ten akcent. :P
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:minuta
  • Lokalizacja:Wrocław
0

A to aspekty muszą być stringly typed i polegać na nazwach metod? o.O
W innych językach jakoś nie ma takich problemów.


Po dopracowaniu rozwiązania każdy będzie mógł założyć własny drzewiasty wątek.
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

@somekind: w Javie tez nie musisz polegać na nazwach metod w aspektach


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Zobacz pozostały 1 komentarz
S9
No bo w Javie można polegac i na nazwach metod, i na adnotacjach itd.
somekind
Tylko po co wybierać gorsze rozwiązanie, a potem upierać się, że cała koncepcja jest zła?
jarekr000000
Aspekty zrobione na nazwach metod to pole minowe. Aspekty chodzące na adnotacjach/(konwencjach) to po prostu pole pełne krowich placków. To drugie jest istotnie lepsze i mniej niebezpieczne. Jakkolwiek, wdepnięcia nie zaliczam do przyjemności. Ale to kwestia gustu.
somekind
Tu nie chodzi o to, na czym aspekty są oparte, ale do czego użyte. Problemem jest używanie ich do logiki biznesowej, a nie do infrastrukturalnej.
S9
No w Javie się używa aspektów to głównie 2/3 rzeczy: transakcyjności, security i ewentualnie cachowania
J1
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad rok
  • Postów:104
0

Jeszcze jedno pytanie, bo znalazłem taką definicję

Inversion of Control is a principle in software engineering by which the control of objects or portions of a program is transferred to a container or framework

Jeżeli nie piszę w żadnym frameworku, tylko tworzę prostą aplikację, w której nie tworzę silnych zależności pomiędzy klasami, to w jaki sposób mogę delegować kontrolę do kontenera lub frameworka? Czy jest to błędna definicja?

Zobacz pozostałe 7 komentarzy
PU
@jajko1233: żadna nie będzie kontenerem, po prostu odwrócisz zależność do warstwy wyżej, ale to nie czyni jej kontenerem
J1
@somekind: która cześć jest błędna?
J1
@pustypawel: ale w takim razie gdzie oddelegowuje kontrole wg definicji (choć może przez to ta definicja jest błędna, wg somekinda)
PU
Definicja mówi o tym, że IoC mamy wtedy gdy przekazujemy kontrolę do kontenera lub frameworka, co jest błędne bo możemy robić IoC bez kontenera i frameworka
J1
@pustypawel: No to w takim razie o tym był cały ten post i liczyłem od razu na odpowiedz ze to jest błędna definicja:D
BZ
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:8
0

Nie wiem skąd się nagle wzięło w temacie Aspect oriented Programming, ale warto pamiętać, że to rak. Niektórzy mówią, ze gorszy od GOTO.
Ślepa ścieżka ewolucji programowania obiektowego. Polecam nie zblizać się jesli nie trzeba.
AOP można użyć przy debugowaniu skomplikowanych bugów lub ewentualnie w monitoringu. Pchanie tam czegokolwiek, co jest ważne dla aplikacji (transakcje, security, itp ), to recepta na katastrofę.

Czy tylko dla mnie brzmi to jak Kult Cargo przepakowany sezonowym Hype..?

Za miesiąc się okaże, że kontener IOC to zło wcielone...

Zobacz pozostały 1 komentarz
BZ
S9
@Shalom: możesz wyjaśnić?
BZ
Kontener, AOP używa się, kiedy wnosi wartość do projektu. A samo AOP to nie jest żadne zło wcielone i najczęściej jest używane jako uproszczenie pewnych mechanizmów jak przekazywanie metadanych lub wywoływanie jakichś części infrastruktury.
Shalom
@scibi92: no bo kolega pisze że Za miesiąc się okaże a @jarekr000000 to wieszczy to już od lat :P
somekind
Mamy tu też takiego, co twierdzi, że OOP to zło. Różni są ludzie.
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:32 minuty
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4706
0
BigosZpomarańczy napisał(a):>

Za miesiąc się okaże, że kontener IOC to zło wcielone...

Z cyklu:
2ddy1a.jpg

Kontenery aplikacji w java

Poza tym nie zło wcielone. Na taki tytuł trzeba sobie zasłużyć.
To po prostu zwykła bieda z nędzą.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 1x, ostatnio: jarekr000000
BZ
To po prostu zwykła bieda z nędzą. Może mam inne odczucia dlatego że nie piszę w Javie.
BZ
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:8
1
jarekr000000 napisał(a):
BigosZpomarańczy napisał(a):>

Za miesiąc się okaże, że kontener IOC to zło wcielone...

Z cyklu:
2ddy1a.jpg

Kontenery aplikacji w java

Poza tym nie zło wcielone. Na taki tytuł trzeba sobie zasłużyć.
To po prostu zwykła bieda z nędzą.

Skoro tak wyglądał świat 3000 lat temu to dzisiaj powinno być mniej więcej tak:

Albo tak:

edytowany 1x, ostatnio: BigosZpomarańczy
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
3

Nie chcę brać udziału w tej dyskusji bo to chyba 50-ta z tej serii, nie chcę też tworzyć jakichś ulotnych i łatwo podważalnych definicji, ale chciałbym wyprostować jedno pojęcie.

Podano tu nieścisłe twierdzenia o IoC:

scibi92 napisał(a):

IoC to jest forma DI. DI oznacza że przez konstruktor wstrzykujesz zależności np:

Shalom napisał(a):
  1. DI to sposób realizacji IoC -> wstrzykujemy do modułów implementacje, z których one, poprzez jasno zdefiniowany interfejs, korzystają. Ale to nie jest jedyne rozwiązanie, jakiś ServiceLocator czy Factory też może być realizacją IoC.

Pracowałem z frameworkiem IoC w COBOLu. Tam nie ma konstruktorów, setterów ani interfejsów.
Prosta i krótka definicja: IoC inverts the flow control as compared to traditional control flow
Źródło: https://en.wikipedia.org/wiki/Inversion_of_control

Coś takiego można też zrobić w dowolnym innym języku. IoC można np. zauważyć przy odpalaniu skryptów /etc/init.d gdzie o przepływie sterowania decyduje "framework" a nie skrypt znajdujący się w tym katalogu.

Ogólnie DI nie ma w podstawowym znaczeniu związku z IoC.
IoC nie wymaga DI a samo DI (np. przez konstruktor) często jest realizowane bez IoC.
Przykład: https://hackernoon.com/you-dont-need-a-dependency-injection-container-10a5d4a5f878

Dopiero na poziomie kontenera oba te terminy mogą się spotkać, np. w takim Springu - tam kontener wie tak dużo o module że może mu grzebać w bebechach bez wiedzy wybranego obiektu.

Ogólnie bliższe mi jest znaczenie z wiki niż takie odwołujące się w każdym zdaniu (pośrednio lub bezpośrednio) do Springa:

The term is related to, but different from, the dependency inversion principle, which concerns itself with decoupling dependencies between high-level and low-level layers through shared abstractions. The general concept is also related to event-driven programming in that it is often implemented using IoC, so that the custom code is commonly only concerned with the handling of events, whereas the event loop and dispatch of events/messages is handled by the framework or the runtime environment.

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Definicja @Shalom jest oczywiście poprawna, ja tutaj popełniłem uproszczenie, bo od początku chodziło mi o kontener IOC.


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)