Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
pl:miw:miw08_ruleruntimeo:mvceditor [2008/05/31 22:35]
miw
pl:miw:miw08_ruleruntimeo:mvceditor [2019/06/27 15:50] (aktualna)
Linia 1: Linia 1:
 ====== Edytor tekstu oparty o MVC ====== ====== Edytor tekstu oparty o MVC ======
  
-==== Cel ====+===== Cel =====
  
 W ramach realizacji tego przykładu konieczne było takie zmodyfikowanie gotowej aplikacji napisanej w J2SE i będącej bardzo prostą, tutorialową demonstracją wykorzystania modelu MVC, aby zastąpić implementacje Modelu z obiektów Javy na Logtalk oraz aby zmodyfikować w jak najmniejszym stopniu pozostałą część aplikacji. ​ W ramach realizacji tego przykładu konieczne było takie zmodyfikowanie gotowej aplikacji napisanej w J2SE i będącej bardzo prostą, tutorialową demonstracją wykorzystania modelu MVC, aby zastąpić implementacje Modelu z obiektów Javy na Logtalk oraz aby zmodyfikować w jak najmniejszym stopniu pozostałą część aplikacji. ​
  
-==== Stan wejściowy ====+===== Stan wejściowy ​=====
 Wejściowa aplikacja jest prostym edytorem tekstu zawierącym,​ jak widać na poniższym diagramie : Wejściowa aplikacja jest prostym edytorem tekstu zawierącym,​ jak widać na poniższym diagramie :
  
 {{:​pl:​miw:​miw08_ruleruntimeo:​figure2.gif|:​pl:​miw:​miw08_ruleruntimeo:​figure2.gif}} ​ {{:​pl:​miw:​miw08_ruleruntimeo:​figure2.gif|:​pl:​miw:​miw08_ruleruntimeo:​figure2.gif}} ​
  
-**Widok (View)** - a dokładnie dwa widoki :   +==== Widok (View) ​==== 
 + 
 + a dokładnie dwa widoki :   
   - Wyświetlający wprowadzony tekst, klasa DisplayViewPanel   - Wyświetlający wprowadzony tekst, klasa DisplayViewPanel
   - Umożliwiający wprowadzanie tekstu oraz modyfikowanie jego właściwości takich jak czcionka, rozmiar czcionki, przeźroczystość tekstu, obrót tekstu wokół osi itp, zaimplementowany jako klasa PropertiesViewPanel   - Umożliwiający wprowadzanie tekstu oraz modyfikowanie jego właściwości takich jak czcionka, rozmiar czcionki, przeźroczystość tekstu, obrót tekstu wokół osi itp, zaimplementowany jako klasa PropertiesViewPanel
  
-**Model** - służy do przechowywania wprowadzonego tekstu oraz wartości tych właściwości. Klasy modelu w projekcie to  :+==== Model ==== 
 + 
 +służy do przechowywania wprowadzonego tekstu oraz wartości tych właściwości. Klasy modelu w projekcie to  :
   - TextElementModel - przechowuje stan tekstu wyświetlanego w dokumencie, takie jak wartość tekstu, czcionka itp   - TextElementModel - przechowuje stan tekstu wyświetlanego w dokumencie, takie jak wartość tekstu, czcionka itp
   - DocumentModel - zawiera stan całego dokumentu tekstowego, czyli nazwę, wysokość, szerokość   - DocumentModel - zawiera stan całego dokumentu tekstowego, czyli nazwę, wysokość, szerokość
  
  
-**Kontroler (Controller)** -  ​służy do przekazywania do Modelu odpowiednich zmian właściwości na podstawie komunikatów nadsyłanych z Widoku, czyli generalnie odpowiada za mapowanie zmian dokonanych przez użytkownika na odpowiednie zmiany w Modelu. Kontroler został zaimplementowany w klasie DefaultController.+==== Kontroler (Controller) ​==== 
 +  
 +służy do przekazywania do Modelu odpowiednich zmian właściwości na podstawie komunikatów nadsyłanych z Widoku, czyli generalnie odpowiada za mapowanie zmian dokonanych przez użytkownika na odpowiednie zmiany w Modelu. Kontroler został zaimplementowany w klasie DefaultController.
  
 Będąc bardziej szczegółowym projekt ten używa lekko zmodyfikowanej wersji wzorca MVC, w której zmiany stanu Modelu nie są bezpośrednio propagowane do Widoku, ale są przekazywane poprzez Kontroler. Czyli projekt używa poniższej architektury : Będąc bardziej szczegółowym projekt ten używa lekko zmodyfikowanej wersji wzorca MVC, w której zmiany stanu Modelu nie są bezpośrednio propagowane do Widoku, ale są przekazywane poprzez Kontroler. Czyli projekt używa poniższej architektury :
Linia 29: Linia 35:
 Dokładny opis oraz źródła wejściowej aplikacji można znaleźć w [[pl:​miw:​miw08_ruleruntimeo#​materialy|Materiałach]]. Dokładny opis oraz źródła wejściowej aplikacji można znaleźć w [[pl:​miw:​miw08_ruleruntimeo#​materialy|Materiałach]].
  
-==== Dokonane modyfikacje ====+ 
 +===== Dokonane modyfikacje ​=====
 Jak widać architektura tego projektu sprzyjała procesowi implementacji części klas w Logtalk'​u ze względu na silne odseparowanie modułów, oraz posługiwanie się referencjami do klas abstrakcyjnych takich jak AbstractController,​ AbstractView czy AbstractModel co bardzo ułatwiało podmianę docelowej implementacji tych obiektów. Jak widać architektura tego projektu sprzyjała procesowi implementacji części klas w Logtalk'​u ze względu na silne odseparowanie modułów, oraz posługiwanie się referencjami do klas abstrakcyjnych takich jak AbstractController,​ AbstractView czy AbstractModel co bardzo ułatwiało podmianę docelowej implementacji tych obiektów.
 +
 +==== Modyfikacje Widoku ====
 +
 +Klasy Widoku, zgodnie z założeniami,​ nie uległy żadnym modyfikacjom.
 +
 +==== Modyfikacje Modelu ====
  
 Klasy Modelu tak naprawdę służą tylko do przechowywania wartości kilku właściwości i cała ich implementacja polega na polach klasy oraz getter'​ach i setter'​ach. Jesteśmy zatem w stanie bez większego problemu wymienić klasy modelu napisane w Javie na obiekty Logtalk, na zasadzie 1:1. Czyli tworzymy: Klasy Modelu tak naprawdę służą tylko do przechowywania wartości kilku właściwości i cała ich implementacja polega na polach klasy oraz getter'​ach i setter'​ach. Jesteśmy zatem w stanie bez większego problemu wymienić klasy modelu napisane w Javie na obiekty Logtalk, na zasadzie 1:1. Czyli tworzymy:
Linia 81: Linia 94:
  
 Tak naprawdę w tym przypadku kod modelu ograniczy się do importowania tej kategorii, jeden predykat służy tylko do wypisania na konsole zmiany stanu modelu. Tak naprawdę w tym przypadku kod modelu ograniczy się do importowania tej kategorii, jeden predykat służy tylko do wypisania na konsole zmiany stanu modelu.
-Niestety jako, że problematyczne okazało się wywoływanie zdarzeń Javowych bezpośrednio z kodu Prologa, niestety wymagałoby to przechowania referencji do Obiektu Kontrolera wewnątrz obiektu Logtalk, co niestety okazało się niemożliwe przy użyciu JPL, który dość dobrze radzi sobie z przechowywaniem referencji do obiektów Javy tworzonych przy użyciu JPL, natomiast niekoniecznie takich istniejących już wcześniej. +Niestety jako, że problematyczne okazało się wywoływanie zdarzeń Javowych bezpośrednio z kodu Prologa, niestety wymagałoby to przechowania referencji do Obiektu Kontrolera wewnątrz obiektu Logtalk, co niestety okazało się niemożliwe przy użyciu JPL, który dość dobrze radzi sobie z przechowywaniem referencji do obiektów Javy tworzonych przy użyciu JPL, natomiast niekoniecznie takich istniejących już wcześniej.Konieczne było zastosowanie ​pewnej modyfikacji działania Kontrolera, ale o tym poniżej. 
-Konieczne było zastosowanie ​pewnych obejść żeby zachować istniejącą architekturę aplikacji, ​ale generlanie rzecz biorąc próba realizacji takiej podmiany udała się.+ 
 + 
 +==== Modyfikacje Kontrolera ==== 
 + 
 +Drugą modyfikacją konieczną do implementacji Modelu w Logtalk'​u była implementacja Kontrolera w taki sposób, aby wykorzystując JPL będzie tworzył obiekty Logtalk oraz wywoła na nich metodę zapisującą wartość danej właściwości. Jako, że kłopotliwe okazało się przechowywanie referencji do kontrolera wewnątrz obiektu Logtalk'​a,​ co jest konieczne do ustawienia Listnera, nie można było dokładnie skopiować rozwiązania z wejściowego projektu. Zamiast tego kontroler po ustawieniu danej właściwości,​ sprawdza jej wartość i odpowiednio modyfikuje widok.  
 + 
 +Zatem architektura została zachowana, podmieniono obiekty Modelu na zasadzie 1:1 i jedyne co musiało się zmienić to implementacja Kontrolera, która była o tyle ułatwiona, że w pozostałych modułach używana jest referencja do klasy abstrakcyjnej AbstractController,​ zatem podmiana jej implementacji z DefaultController na LogtalkControler była właściwie bezbolesna. Co do implementacji kontrolera to klasa  LogtalkControler zawiera dwa bardziej interesujące fragmenty : 
 + 
 +**Konstruktor**:​ 
 +  * nawiązujemy przez JPL komunikacje z SWIProlog i  konfigurujemy runtime Logtalk'​a,​[[pl:​miw:​miw08_ruleruntimeo:​swiconfig|szczegółowy opis]]  
 +  * Tworzymy obiekty Modelu w następujący sposób :  
 +<code java> 
 + 
 +Query loadDocumentModel = new Query("​logtalk_load",​ 
 + new Term[]{new Atom("​src/​com/​sun/​example/​mvc/​model/​documentModel"​)} 
 + ); 
 +  
 + if(loadDocumentModel.hasSolution()) 
 +
 + System.out.println("​DocumentModel loaded succesfully"​);​ 
 +
 + else 
 +
 + throw new RuntimeException("​Unable to load DocumentModel"​);​ 
 +
 + 
 +</​code>​ 
 + 
 +**Metoda setModelProperty(String propertyName,​ Object newValue) ** - dokonująca właściwej zmiany w modelu a nastepnie update w Widoku. 
 + 
 +<code java> 
 + 
 +  
 + Query setLogtalkProperty ​ = null; 
 + Query getLogtalkProp = null; 
 + if (this.isDocumentModel) { 
 + setLogtalkProperty  
 + //= new Query("​documentModel::​set_property('"​ 
 ++propertyName + "',​ jpl_new('​java.lang.String',​['"​  
 ++ newValue.toString() + "'​],​ _))."​);​ 
 + = new Query("​documentModel::​set_property('"​ 
 ++propertyName + "',​ '"​ + newValue.toString() + "'​)."​);​ 
 +  
 + getLogtalkProp = new Query( 
 + "​documentModel::​get_property('"​ + propertyName + "',​ X)."​);​ 
 + }else { 
 + setLogtalkProperty = new Query("​textElementModel::​set_property('"​+propertyName + "',​ '"​ + newValue.toString() + "'​)."​);​ 
 +  
 + getLogtalkProp = new Query( 
 + "​textElementModel::​get_property('"​ + propertyName + "',​ X)."​);​ 
 +
 +  
 +  
 + if(setLogtalkProperty.hasSolution()) 
 +
 +
 + else 
 +
 + throw new RuntimeException("​Unable to set property named : " + propertyName ); 
 +
 +  
 + Variable X = new Variable("​X"​);​ 
 +  
 +  
 + if(getLogtalkProp.hasMoreElements()) 
 +
 + Object elem = getLogtalkProp.nextElement();​ 
 + if (elem instanceof Hashtable) { 
 + Hashtable<​String,​ Atom> solution = (Hashtable<​String,​ Atom>) elem; 
 +  
 + System.out.println("​Solution is " + solution.get("​X"​));​ 
 + 
 +  
 +  
 + Atom atomVal = (Atom)solution.get("​X"​);​ 
 + String strValue = atomVal.name();​  
 + Object value = strValue; 
 + try { 
 + value = java.lang.Integer.valueOf( strValue).intValue();​ 
 + } catch (Exception e) { 
 + // TODO: handle exception 
 +
 +  
 + DisplayViewPanel displayView = (DisplayViewPanel) this.registeredViews.get(0);​ 
 + PropertyChangeEvent event = new PropertyChangeEvent(this,​ propertyName,​ newValue, value); 
 + displayView.modelPropertyChange(event);​ 
 +  
 +
 +
 + 
 +</​code>​ 
 + 
 + 
 +Dzięki tym modyfikacją da się zachować pełną funkcjonalność ​aplikacji, ​jednocześnie implementując obiekty Modelu w Logtalk'​u.  
 + 
 +Źródła projektu znajdują ​się w dziale [[pl:​miw:​miw08_ruleruntimeo#​projekt|Projekt]].
  
-Widać, że podmiana klas modelu na obiekty Logtalku może się odbyć tylko poprzez modyfikacje Kontrolera (Controller) na taki, który wykorzystując JPL będzie komunikował się z Logtalk'​iem ​ i przekazywał komunikaty do Widoku (View). Zatem klasy modelu napisane w Javie de facto mogą zostać podmienione przez obiekty Logtalk na zasadzie 1:1. 
  
  
-==== Docelowe rozwiązanie ==== 
  
pl/miw/miw08_ruleruntimeo/mvceditor.1212266130.txt.gz · ostatnio zmienione: 2019/06/27 15:59 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0