Programowanie wielowarstwowe
Programowanie wielowarstwowe (lub programowanie bezpoziomowe ) to paradygmat programowania dla oprogramowania rozproszonego , który zazwyczaj opiera się na architekturze wielowarstwowej , fizycznie rozdzielając różne funkcjonalne aspekty oprogramowania na różne poziomy (np. klient, serwer i baza danych w aplikacji internetowej). Programowanie wielowarstwowe umożliwia tworzenie funkcji obejmujących wiele takich warstw w jednej jednostce kompilacji przy użyciu jednego języka programowania . Bez programowania wielowarstwowego warstwy są tworzone przy użyciu różnych języków, np. JavaScript dla klienta WWW, PHP dla serwera WWW i SQL dla bazy danych. Programowanie wielowarstwowe jest często integrowane z językami ogólnego przeznaczenia poprzez rozszerzenie ich o obsługę dystrybucji.
Koncepcje programowania wielowarstwowego zostały zapoczątkowane przez języki Hop i Links i znalazły zastosowanie w przemyśle w rozwiązaniach takich jak Ocsigen, Opa , WebSharper , Meteor czy GWT .
Programowanie wielowarstwowe zapewnia globalny widok na system rozproszony. Ten aspekt został pokazany podobnie do innych paradygmatów programowania, takich jak programowanie choreograficzne , makroprogramowanie i obliczenia zagregowane.
Kontekst
Kod różnych warstw może być wykonywany w sposób rozproszony na różnych komputerach w sieci . Na przykład w architekturze trójwarstwowej system jest podzielony na trzy główne warstwy — zwykle warstwę prezentacji, biznesową i danych. Takie podejście ma tę zaletę, że dzieląc system na warstwy, funkcjonalność zaimplementowana w jednej z warstw może być zmieniana niezależnie od innych warstw. Z drugiej strony ta decyzja architektoniczna rozrzuca przekrojową funkcjonalność należącą do kilku warstw na kilka jednostek kompilacji.
W programowaniu wielowarstwowym różne warstwy są implementowane przy użyciu jednego języka programowania. Różne backendy kompilacji uwzględniają warstwę docelową (np. Java dla serwera i JavaScript dla przeglądarki internetowej). W konsekwencji funkcjonalność, która jest rozłożona na warstwy, może być zaimplementowana w pojedynczej jednostce kompilacji programu wielowarstwowego.
Przykład
Zasadniczo języki wielowarstwowe pozwalają programistom definiować dla różnych fragmentów kodu poziomy, do których należy kod. Funkcje językowe, które umożliwiają tę definicję, są dość zróżnicowane w różnych językach wielowarstwowych, począwszy od przemieszczania , przez adnotacje , po typy . Poniższy przykład pokazuje aplikację klient-serwer Echo, która ilustruje różne podejścia. W przykładzie klient wysyła wiadomość do serwera, a serwer zwraca tę samą wiadomość klientowi, gdzie jest ona dołączana do listy odebranych wiadomości.
Aplikacja Echo w Hop.js
service echo () { var input = <input type= "text" /> return <html> <body onload=~{ var ws = new WebSocket ( "ws://localhost:" + ${hop.port} + " /hop/ws" ) ws.onmessage = function ( zdarzenie ) { document.getElemenetById ( "lista" )
. appendChild ( <li>${event.data}</li> ) } }> <div> ${input} <button onclick=~{ ws.send ( ${input}.value ) }>Echo!</button > </div> <ul id= "list" /> </body> </html> } var wss = new WebSocketServer ( "ws" ) wss.onconnection = funkcja
( zdarzenie ) { var ws = wartość zdarzenia . ws.onmessage = funkcja ( zdarzenie ) { ws.send ( wartość zdarzenia ) } }
Hop wykorzystuje staging do osadzania kodu, który ma być uruchamiany na kliencie, w programie po stronie serwera: Używając notacji ~{…}, kod procedur obsługi onload (linia 4) i onclick (linia 10) nie jest wykonywany natychmiast, ale serwer generuje kod do późniejszego wykonania na kliencie. Z drugiej strony notacja ${…} wymyka się jednemu poziomowi generowania programu. Wyrażenia hop.port (wiersz 5), event.data (wiersz 6) i dane wejściowe (wiersz 9 i 10) są oceniane przez program serwera zewnętrznego, a wartości, które obliczają, są wprowadzane do wygenerowanego programu klienckiego. Hop obsługuje programowanie pełnoetapowe , tj. wyrażenia ~{…} mogą być dowolnie zagnieżdżane w taki sposób, że nie tylko programy po stronie serwera mogą generować programy po stronie klienta, ale także programy po stronie klienta mogą generować inne programy po stronie klienta.
HTML można osadzić bezpośrednio w kodzie Hop. HTML wygenerowany na serwerze (linie 2-14) jest przekazywany do klienta. HTML wygenerowany na kliencie można dodać do strony za pomocą standardowego DOM API (Linia 6). Hop obsługuje dwukierunkową komunikację między działającym serwerem a działającą instancją klienta za pośrednictwem swojej standardowej biblioteki. Klient łączy się z serwerem WebSocket poprzez standardowe API HTML5 (linia 5) i wysyła bieżącą wartość wejściową (linia 10). Serwer otwiera serwer WebSocket (wiersz 17), który zwraca wartość z powrotem do klienta (wiersz 20). Tak zwane usługi, które są wykonywane na serwerze i generują wartość zwracaną klientowi, który wywołał usługę. Na przykład usługa echo (wiersz 1) tworzy stronę HTML obsługiwaną przez klienta WWW aplikacji Echo. W ten sposób kod w bloku usługi jest wykonywany na serwerze.
Aplikacja Echo w linkach
fun echo ( item ) server { item } fun main () server { page < html > < body > < form l : onsubmit = "{appendChildren(<li>{stringToXml(echo(item))}</li>, getNodeById (" lista "))}" > < wejście l : nazwa = "pozycja"
/> < button type = "submit" > Echo !</ button > </ form > < ul id = "list" /> </ body > </ html > } main ()
Łącza używają adnotacji na funkcjach, aby określić, czy działają one na kliencie, czy na serwerze (wiersz 1 i 5). Na żądanie klienta serwer wykonuje główną funkcję (wiersz 18), która konstruuje kod wysyłany do klienta. Linki umożliwiają osadzenie kodu XML (linie 7–15). Atrybuty XML z prefiksem l: są traktowane w specjalny sposób. Atrybut l:name (wiersz 10) deklaruje identyfikator, z którym związana jest wartość pola wejściowego. Identyfikator może być użyty w innym miejscu (wiersz 9). Kod do wykonania dla procedury obsługi l:onsubmit (wiersz 9) nie jest wykonywany natychmiast, ale kompilowany do JavaScript w celu wykonania po stronie klienta. Nawiasy klamrowe oznaczają kod linków osadzony w XML. Procedura obsługi l:onsubmit wysyła bieżącą wartość wejściową do serwera, wywołując echo. Element jest zwracany przez serwer i dołączany do listy odebranych elementów przy użyciu standardowych API DOM. Połączenie z serwerem (linia 9) nie blokuje klienta. Zamiast tego kontynuacja na kliencie jest wywoływana, gdy wynik wywołania jest dostępny. Interakcja klient-serwer opiera się na stylu przekazywania wznowienia: Używanie przekazywanie kontynuacji styl transformacja i defunkcjonalizacja , zdalne wywołania są realizowane poprzez przekazanie nazwy funkcji dla kontynuacji oraz danych potrzebnych do kontynuowania obliczeń.
Aplikacja Echo w ScalaLoci
@multitier obiekt Aplikacja { @peer typ Serwer <: { typ Powiązanie <: Pojedynczy [ Klient ] } @peer typ Klient <: { typ Powiązanie <: Pojedynczy [ Serwer ] } val wiadomość = on [ Klient ] { Zdarzenie [ Ciąg ] ( ) } wartość
echoMessage = na [ serwerze ] { wiadomość . asLocal } def main () = on [ Client ] { val items = echoMessage . jakoLokalny . lista val lista = Sygnał { ol ( pozycje () mapa { wiadomość => li ( wiadomość ) })
} val wp = wejście . renderuj dom . dokument . body = body ( div ( inp , button ( onclick := { () => wiadomość . fire ( inp . value ) })( "Echo!" )), list . asFrag ). renderuj } }
ScalaLoci jest językiem przeznaczonym do ogólnych systemów rozproszonych, a nie tylko do sieci, tzn. nie jest ograniczony do architektury klient-serwer. W tym celu ScalaLoci obsługuje typy równorzędne do kodowania różnych warstw na poziomie typu . Typy miejsc docelowych służą do przypisywania lokalizacji do danych i obliczeń. ScalaLoci obsługuje reaktywne wielowarstwowe – abstrakcje językowe dla programowania reaktywnego, które są umieszczane w określonych lokalizacjach – do tworzenia przepływów danych między różnymi peerami.
Aplikacja najpierw definiuje pole wejściowe (wiersz 11) za pomocą biblioteki ScalaTags. Wartość tego pola jest używana w procedurze obsługi zdarzenia kliknięcia przycisku (wiersz 15) do wywołania zdarzenia komunikatu z bieżącą wartością pola wejściowego. Wartość jest następnie przekazywana do serwera (wiersz 6) iz powrotem do klienta (wiersz 9). Na kliencie wartości zdarzenia są gromadzone przy użyciu funkcji list i odwzorowywane na listę HTML (wiersz 10). Ta lista jest następnie używana w kodzie HTML (wiersz 16) do wyświetlania poprzednich danych wejściowych.
Lista wielowarstwowych języków programowania
- Hop/Hop.js
- Spinki do mankietów
- Ur/Web
- Eliom/Ocsigen
- ScalaLoci
- StiP.js
- Scala Multi-Tier FRP
- Opa
- AmbientTalk/R
- ML5
- Wyostrzanie sieci
- Pośpiech
- Zabawa
- Koka
- Rachunek wielopoziomowy
- Szybki
- Wolta
- GWT
- Meteor
- J-Orkiestra
- Hip hop
- Rozproszony Ork
- Jif/podział
- Rozszczepienie
- SIF
- WebDSL
- Ostry
- Mobl
- Abstrakcje wysokiego poziomu do programowania w sieci Web