SlideShare a Scribd company logo
1 of 51
Download to read offline
DSL DYI
...Domain Specific Languages

       Maciek Próchniak
         mpr@touk.pl


       13 czerwca 2011
DSL - Plan



   Co to jest DSL i do czego może się przydać


   Rodzaje DSL - dlaczego wewnętrzne, statycznie typowane?


   Klocki do budowy DSL


   Co dalej? Gdzie się zatrzymać?
Maciek Próchniak




      Niedoszły topolog algebraiczny
      Kontrybutor Activiti
      Integracja: Servicemix, Camel, Drools, OSGi, BPEL...
      Rzeczy mniej przyjemne: GWT, Smartclient, ...
      Last but not least - TouK ;)
DSL


  Domain
  Chcemy móc opisać obiekty, reguły z naszej
  dziedziny

  Specific
  Nie zaprzątając sobie głowy resztą świata

  Language
  W jakimś języku (programowania)
DSL - czy nie mamy już wystarczająco dużo języków?
GPL vs. DSL
DSL - po co?




      Opisywanie reguł biznesowych
      Łatwiejesze przełożenie wymagań na kod
      Współpraca z ekspertami
      Zwiększona produktywność
Kto korzysta z DSL?




     Programiści/Deweloperzy?


     PO/Eksperci biznesowi?
Cobol fallacy




   ”Now we can get rid of programmers and have business people
   specify the rules themselves”
       - Cobol Fallacy wg. Martina Fowlera
Znajomość czynna i znajomość bierna



   Znajomość bierna:
   ”Java je jedn´ z nejpouˇ´ ejˇ´ programovac´ jazyk˚ na
                 ım          zıvanˇ sıch              ıch     u
   svˇtˇ. Podle Tiobe indexu je Java nejpopul´rnˇjˇ´ programovac´
     ee                                        a e sı             ı
   jazyk. (...) Dne 8. kvˇtna 2007 Sun uvolnil zdrojov´ kódy Javy (cca
                         e                              e
   2,5 milión˚ ˇ´dk˚ kódu) a Java bude d´le vyv´
              u ra u                      a       ıjena jako open
   source.”
        - http://cs.wikipedia.org/wiki/Java (programovac´ jazyk)
                                                           ı

   Znajomość czynna?
   To już trudniejsze...
DSL - po co?




      Opisywanie reguł biznesowych
      Łatwiejesze przełożenie wymagań na kod
      Współpraca z ekspertami
      Zwiększona produktywność
Ale przecież mamy DDD?




    Bogaty model domenowy to
    podstawa
    DSL - ”widok” na model
    domenowy
    Model domeny to
    trudniejszy fragment
Inny zestaw reguł




   Przy budowaniu DSL zwykle łamiemy ”żelazne” zasady:
       metody globalne/statyczne?
       CQS?
       prawo Demeter?
       ”małe” klasy?
Inny zestaw reguł

   Potrzebne warstwy:
DSL - ale jaki?



       zewnętrzny (external)
           SQL
           Regexp
           css
           schematy XML?
       wewnętrzny (embedded, DSEL) - jest osadzony w GPL
           Apache Camel
           Mockito
           JMock
           Rails
Dlaczego wewnętrzne?




   Dostajemy ”za darmo”:
       Parser
       Kompilator
       Wsparcie IDE
       Rozszerzanie i obsługa niestandardowych przypadków
Przykład: WS HumanTask




     Schemat XML opisu zadań do wykonania przez człowieka
     W typowym projekcie zadania są podobne
     Problem: jak zdefiniować typy właściwe dla konkretnego
     projektu
Przykład: WS BPEL




     Schemat XML opisu działania procesu biznesowego
     Konieczność ujęcia wielu rodzajów akcji
     Problem: język staje się GPL
Przykład pośredni: Drools


           Własny język definicji reguł
           Konieczność ujęcia wielu rodzajów akcji
           Korzyści: połączenie wyrażalności zewnętrznego DSL i
           możliwości Javy

 1   r u l e AcceptOrder
 2   when
 3       $ c l i e n t : C l i e n t ( s t a t u s==APPROVED)
 4       $ o r d e r : O r d e r ( s t a t u s==  NEW, c l i e n t==$ c l i e n t )
 5   then
 6       orderService . acceptOrder ( $order )
 7   end
Dlaczego statycznie typowane?




 Języki dynamiczne oferują duże
 możliwości, ale:
     Wsparcie IDE
     Możliwości odkrywania API
     Każdy projekt trafi w końcu
     do studentów...
Przykład - Apache Camel


          Implementacja wzorców EIP: router, splitter, aggregator, lista
          odbiorców, ...
          Definiowanie przepływów komunikacji
     Przykład:
 1   c l a s s JamRouteBuilder extends R o u t e B u i l d e r {
 2       public void c o n f i g u r e () {
 3           from ( ” f i l e : / tmp/ i n ” )
 4              . convertBodyTo ( S t r i n g . c l a s s )
 5              . bean ( ” r e c i p i e n t R e p o s i t o r y ” )
 6              . r e c i p i e n t L i s t ( property (” recipients ” ));
 7       }
 8   }
Płynny interfejs - klucz do sukcesu DSL



                              Płynny interfejs
 Klasyczny model obiektowy
Płynny interfejs - rozszerzony budowniczy


 1   makeOrder (NORMAL)
 2     . w i t h P r i c e ( new B i g D e c i m a l ( 2 2 . 0 0 ) )
 3     . w i t h D a t e ( ”2011−11−12” )
 4     . finish ();


 1   p u b l i c O r d e r B u i l d e r makeOrder ( OrderType t y p e ) {
 2        r e t u r n new O r d e r B u i l d e r ( t y p e ) ;
 3   }
 4   //w k l a s i e O r d e r B u i l d e r
 5   public OrderBuilder w i t h P r i c e ( BigDecimal p r i c e ) {
 6      this . price = price ;
 7      return this ;
 8   }
Płynny interfejs - problem stopu



 1   makeOrder (NORMAL)
 2     . w i t h P r i c e ( new B i g D e c i m a l ( 2 2 . 0 0 ) )
 3     . w i t h D a t e ( ”2011−11−12” )
 4     . finish ();


 1   p u b l i c Order f i n i s h ( ) {
 2      return this . build ()
 3   }
Płynny interfejs - problem stopu



 1   makeOrder (NORMAL)
 2     . w i t h P r i c e ( new B i g D e c i m a l ( 2 2 . 0 0 ) )
 3     . w i t h D a t e ( ”2011−11−12” )
 4     . withClientId (1334);

     Id klienta jest wymagane:
 1   p u b l i c Order w i t h C l i e n t I d ( long l ) {
 2      clientId = l ;
 3      return this . build ( ) ;
 4   }
Płynny interfejs - wymuszanie kolejności


 1
 2   interface ClientPhoneBuilder {
 3      S t r e e t B u i l d e r w i t h P h o n e ( S t r i n g phone ) ;
 4      S t r e e t B u i l d e r withoutPhone ( ) ;
 5   }
 6
 7   interface StreetBuilder {
 8       ClientApartmentBuilder livingOn ( String street );
 9       C l i e n t homeless ( ) ;
10   }
11   ...


 1
 2   . w i t h P h o n e ( ” 2245556 ” ) . l i v i n g O n ( ” J e r o z o l i m s k i e ” ) .
Płynny interfejs - zagnieżdżanie




   Możliwości:
       hierarchiczne buildery
       dodatkowe buildery
Zagnieżdżanie builderów - hierarchie


 1   . f i l t e r ()
 2       . x p a t h ( ” // o r d e r I d ” )
 3       . isEqualTo (15)
 4   . send ( ” http : / / . . . ” )


 1   class RouteBuilder {
 2   ...
 3   ExpressionBuilder f i l t e r () {
 4       t h i s . f i l t e r = new E x p r e s s i o n B u i l d e r ( t h i s ) ;
 5       return this . f i l t e r ;
 6   }
 7   v o i d s e n d ( S t r i n g where ) {
 8          ...
 9   }
Zagnieżdżanie builderów - hierarchie
 1   . f i l t e r ()
 2       . x p a t h ( ” // o r d e r I d ” )
 3       . isEqualTo (15)
 4   . send ( ” http : / / . . . ” )


 1   c l a s s E x p r e s s i o n B u i l d e r <T> {
 2
 3       T parent ;
 4
 5       E x p r e s s i o n B u i l d e r xpath ( S t r i n g xpath ) {
 6          t h i s . e x p r e s s i o n = new X P a t h E x p r e s s i o n ( x p a t h ) ;
 7          return this ;
 8       }
 9       T isEqualTo ( String value ) {
10          t h i s . a s s e r t i o n = new E q u a l i t y ( v a l u e ) :
11          return parent ;
12       }
13   }
Zagnieżdżanie builderów - oddzielne buildery
 1
 2   c la s s SenderRouter extends RouteBuilder {
 3      ...
 4      . filter (
 5          x p a t h ( ” // o r d e r I d ” ) . i s E q u a l T o ( 1 5 )
 6      ) . send ( ” http : / / . . . ” )
 7      ...
 8      E x p r e s s i o n B u i l d e r xpath ( S t r i n g xpath ) {
 9          r e t u r n new X P a t h B u i l d e r ( x p a t h ) ;
10      }
11   }

     Obiekt kontekstu jest lepszy niż funkcje globalne
 1   class XpathBuilder extends ExpressionBuilder {
 2   Expression isEqualTo ( String value ) {
 3     t h i s . a s s e r t i o n = new E q u a l i t y ( v a l u e ) :
 4     return build ( ) ;
 5   }
Płynny interfejs - zagnieżdżanie



       hierarchiczne buildery
           lepszy dostęp do kontekstu
           lepsze podpowiedzi IDE


       dodatkowe buildery
           prostsze
           reużywalność
           rozszerzalność
Co dalej?


     Cały czas dużo szumu syntaktycznego:
 1   from ( ” s e d a : a ” )
 2      . choice ()
 3         . when ( h e a d e r ( ” f o o ” ) . i s E q u a l T o ( ” b a r ” ) )
 4            . to (” seda : b ”)
 5         . otherwise ()
 6            . p r o c e s s ( new P r o c e s s o r ( ) {
 7                  p u b l i c v o i d p r o c e s s ( Exchange e x ) {
 8                      e x . s e t P r o p e r t y ( ” d a t e ” , new Date ( ) ) ;
 9                  }
10   });

     Tu kończą się możliwości Javy...
Scala comes to the rescue!




      ”normalny” język:
          programowanie obiektowe
          statyczne typowanie
      można programować funkcyjnie
      prosty pattern matching
      dużo lukru syntaktycznego
Scala comes to the rescue!




      uproszczenia składni, przeciążanie operatorów
      domyślne (implicit) konwersje i parametry
      funkcje i domknięcia
Uproszczenia składni



     W wielu miejscach kropki i przecinki stają się opcjonalne:
 1   order ()
 2     . s i z e ( 1 1 ) . express ( true )

     A więc:
 1      order ()
 2        s i z e 11
 3        express true
Przeciążanie operatorów


     Wszystko jest metodą
 1   c l a s s Balance ( balance : BigDecimal ) {
 2       d e f + ( toAdd : B a l a n c e ) : B a l a n c e = {
 3           new B a l a n c e ( b a l a n c e+toAdd . g e t B a l a n c e ) }
 4       def getBalance = balance
 5   }

     A więc:
 1      println
 2        ( ( new B a l a n c e ( 1 0 ) + new B a l a n c e ( 1 0 ) ) . g e t B a l a n c e ) ;
Domyślne konwersje




      Dodawanie metod do klas - monkey patching


      Języki dynamiczne robią to globalnie


      Jak można to zrobić bezpieczniej?
Domyślne konwersje
     Dodajemy możliwość autokonwersji w obrębie danej klasy:
 1   c l a s s Orders {
 2       i m p l i c i t def stringToOrder ( s t r : String ) =
 3           new O r d e r B u i l d e r ( s t r ) ;
 4   }
 5
 6   class OrderBuilder ( c l i e n t : String ) {
 7      var p r i c e : BigDecimal = 0;
 8      def w i t h P r i c e ( newPrice : BigDecimal ) =
 9        { p r i c e = newPrice ; b u i l d ; }
10      def build = . . .
11   };

     I możemy napisać:
 1   c l a s s VIPOrders extends Orders {
 2       ” c l i e n t ” withPrice 1.22
 3   }
Przekazywanie strategii - funkcje i domknięcia


     Przekazywanie wyrażeń, predykatów - Java
 1   . f i l t e r ( new E x p r e s s i o n ( ) {
 2       p u b l i c b o o l e a n e v a l u a t e ( Message message ) {
 3            r e t u r n VIP == message . g e t P r o p e r t y ( ” c l i e n t T y p e ” ) ;
 4      }
 5   }).

     Scala:
 1   . f i l t e r { e x c h a n g e =>
 2      VIP==e x c h a n g e . g e t P r o p e r t y ( ” c l i e n t T y p e ” ) }
Przekazywanie strategii - funkcje i domknięcia



     Przekazywanie wyrażeń, predykatów - Scala
 1   ” d i r e c t : b” == {  >
 2      when ( . i n == ”< h a l l o />” ) {
 3          −−> ( ”mock : b” )
 4           t o ( ”mock : c ” )
 5      } otherwise {
 6           p r o c e s s ( e x => e x . s e t P r o p e r t y ( ” d a t e ” , new Date ( ) ) )
 7      }
 8      t o ( ”mock : d” )
 9   }
1    case c l a s s     SChoiceDefinition
2     ( override        val target : ChoiceDefinition ) . . . {
3       override        def otherwise = {
4         target      . otherwise
5         this
6       }
7
8        o v e r r i d e d e f when ( f i l t e r : Exchange => Any ) = {
9           val predicate = PredicateBuilder . toPredicate ( f i l t e r )
10          t a r g e t . when ( p r e d i c a t e )
11          this
12       }
13   }
Granice czytelności i wyrażalności



    Język naturalny:
1   Stworz zamowienie
2     d l a k l i e n t a ”TouK”


         Fleksja?
         Synonimy?
         Koniugacja?
O jeden krok za daleko?


     Definiowanie
 1   class    OrderBuilder ( c l i e n t : String ) {
 2      var   nameField : S t r i n g = ””;
 3      def   name = { n a m e F i e l d = }
 4      def   with a = t h i s ;
 5   };

     By napisać
 1   c l a s s VIPOrders extends Orders {
 2       ” c l i e n t ” . w i t h a name ” a l a ” ;
 3   }
Rozwój - rozszerzanie
Rozszerzanie - przykład



           DSL do bardzo prostych procesów stanowych
           interakcje oparte na Apache Camel

 1   s t a r t ( ” d i r e c t : employee ” ) . f o r k (
 2       s t a t e ( ” h r S t a r t ” ) . to ( ” f i l e :/// hr ” )
 3           . w a i t S t a t e ( ” waitingForHR ” , ” f i l e :/// h r I n ” )
 4               . s t a t e ( ” hrEnd ” ) ,
 5       s t a t e ( ” i t S t a r t ” ) . to ( ” f i l e :/// i t ” )
 6           . waitState (” waitingForIT ” ,” f i l e :/// i t I n ”)
 7               . state (” itEnd ”)
 8   ) . s t a t e ( ” end ” ) ;
Rozszerzanie - przykład




      Trudno ”wpiąć” się ze swoimi rozszerzeniami
      Problem: Użycie zagnieżdżonych builderów
      Możliwe rozwiązania:
          Używanie oddzielnych builderów i obiektu kontekstu
          Nadpisanie pewnej części źródłowego DSL - może być
          skomplikowane
Podsumowując...




      DSL może zwiększyć czytelność i zwięzłość kodu
      Wewnętrzne DSLe w statycznie typowanych językach mają
      niski koszt budowy i nauki
      Korzystając ze Scali możemy zmniejszyć szum syntaktyczny w
      naszym DSLu
      Projektując DSL trzeba myśleć o jego rozwoju i możliwościach
      rozszerzania
Literatura
I inne zasoby




       http://weblogs.java.net/blog/carcassi/archive
       /2010/02/04/building-fluent-api-internal-dsl-java
       http://pragdave.blogs.pragprog.com/pragdave/2008/03/the-
       language-in.html
       http://www.infoq.com/articles/internal-dsls-java
Dziękuję.
Użyłem

  Zdjęć:
      http://www.flickr.com/photos/gibbons/2294375187/
      http://www.flickr.com/photos/wwworks/2472232245/
      http://www.flickr.com/photos/siomuzzz/2577041081/
      http://www.flickr.com/photos/r4n/3049253551/
      http://www.flickr.com/photos/neilwykes/3219711243/
      http://www.flickr.com/photos/donsolo/3666985941/
      http://www.flickr.com/photos/saeba/4214372479/
      http://www.flickr.com/photos/maysbusinessschool/4948659050/
      http://www.flickr.com/photos/pixelcore/91132699/
             A
  I szablonu LTEXby mcl :)

More Related Content

Viewers also liked

CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012Maciek Próchniak
 
Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Maciek Próchniak
 
Type Driven Development @ Confitura 2014
Type Driven Development @ Confitura 2014Type Driven Development @ Confitura 2014
Type Driven Development @ Confitura 2014Maciek Próchniak
 
TypeSafe NoSQL @ TopConf 2012
TypeSafe NoSQL @ TopConf 2012TypeSafe NoSQL @ TopConf 2012
TypeSafe NoSQL @ TopConf 2012Maciek Próchniak
 
Scalable database, Scalable language @ JDC 2013
Scalable database, Scalable language @ JDC 2013Scalable database, Scalable language @ JDC 2013
Scalable database, Scalable language @ JDC 2013Maciek Próchniak
 
Type Driven Development @ BoosterConf 2013
Type Driven Development @ BoosterConf 2013Type Driven Development @ BoosterConf 2013
Type Driven Development @ BoosterConf 2013Maciek Próchniak
 
Activiti - BPMN 2.0 nadchodzi
Activiti - BPMN 2.0 nadchodziActiviti - BPMN 2.0 nadchodzi
Activiti - BPMN 2.0 nadchodziMaciek Próchniak
 

Viewers also liked (7)

CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012CQRS, ES, Scala @ Confitura 2012
CQRS, ES, Scala @ Confitura 2012
 
Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010
 
Type Driven Development @ Confitura 2014
Type Driven Development @ Confitura 2014Type Driven Development @ Confitura 2014
Type Driven Development @ Confitura 2014
 
TypeSafe NoSQL @ TopConf 2012
TypeSafe NoSQL @ TopConf 2012TypeSafe NoSQL @ TopConf 2012
TypeSafe NoSQL @ TopConf 2012
 
Scalable database, Scalable language @ JDC 2013
Scalable database, Scalable language @ JDC 2013Scalable database, Scalable language @ JDC 2013
Scalable database, Scalable language @ JDC 2013
 
Type Driven Development @ BoosterConf 2013
Type Driven Development @ BoosterConf 2013Type Driven Development @ BoosterConf 2013
Type Driven Development @ BoosterConf 2013
 
Activiti - BPMN 2.0 nadchodzi
Activiti - BPMN 2.0 nadchodziActiviti - BPMN 2.0 nadchodzi
Activiti - BPMN 2.0 nadchodzi
 

Similar to DSL - DYI

Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Cloudskraqa
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychSKN Shader
 
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPROIDEA
 
Aby wąż giętki robił to co wymyśli głowa, czyli słów kilka o analizie leksyk...
Aby wąż giętki robił to co wymyśli głowa,  czyli słów kilka o analizie leksyk...Aby wąż giętki robił to co wymyśli głowa,  czyli słów kilka o analizie leksyk...
Aby wąż giętki robił to co wymyśli głowa, czyli słów kilka o analizie leksyk...Adam Przybyła
 
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NETProgramowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NETMikołaj Olszewski
 
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł GrajewskiPROIDEA
 
4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future Processing
4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future Processing4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future Processing
4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future ProcessingPROIDEA
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.jsPatryk Jar
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychMarcin Jasiński
 
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwAsynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwLuke Adamczewski
 
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...Polcode
 
100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego. 100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego. Redge Technologies
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Codesushi.co (CODESUSHI LLC)
 
Nowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programistyNowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programistyMarcinStachniuk
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPLaravel Poland MeetUp
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Natalia Stanko
 
Let's Go! - wprowadzenie do Go
Let's Go!  - wprowadzenie do GoLet's Go!  - wprowadzenie do Go
Let's Go! - wprowadzenie do GoRafal Piekarski
 
Secure Coding w praktyce.
Secure Coding w praktyce.Secure Coding w praktyce.
Secure Coding w praktyce.Semihalf
 

Similar to DSL - DYI (20)

Michał Dec - Quality in Clouds
Michał Dec - Quality in CloudsMichał Dec - Quality in Clouds
Michał Dec - Quality in Clouds
 
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnychGanymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
Ganymede - nowoczesne technologie w grach przeglądarkowych i mobilnych
 
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
 
Aby wąż giętki robił to co wymyśli głowa, czyli słów kilka o analizie leksyk...
Aby wąż giętki robił to co wymyśli głowa,  czyli słów kilka o analizie leksyk...Aby wąż giętki robił to co wymyśli głowa,  czyli słów kilka o analizie leksyk...
Aby wąż giętki robił to co wymyśli głowa, czyli słów kilka o analizie leksyk...
 
Iron Python I Dlr
Iron Python I DlrIron Python I Dlr
Iron Python I Dlr
 
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NETProgramowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
Programowanie Komponentowe: #5 Wprowadzenie do środowiska .NET
 
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
 
4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future Processing
4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future Processing4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future Processing
4Developers 2015: .NET 2015 - co nowego? - Michał Dudak, Future Processing
 
Modularny JavaScript - meet.js
Modularny JavaScript - meet.jsModularny JavaScript - meet.js
Modularny JavaScript - meet.js
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów Sparkowych
 
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketwAsynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw
 
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websock...
 
100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego. 100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego.
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
 
Nowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programistyNowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programisty
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHP
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010
 
Let's Go! - wprowadzenie do Go
Let's Go!  - wprowadzenie do GoLet's Go!  - wprowadzenie do Go
Let's Go! - wprowadzenie do Go
 
Secure Coding w praktyce.
Secure Coding w praktyce.Secure Coding w praktyce.
Secure Coding w praktyce.
 
Scala
ScalaScala
Scala
 

DSL - DYI

  • 1. DSL DYI ...Domain Specific Languages Maciek Próchniak mpr@touk.pl 13 czerwca 2011
  • 2. DSL - Plan Co to jest DSL i do czego może się przydać Rodzaje DSL - dlaczego wewnętrzne, statycznie typowane? Klocki do budowy DSL Co dalej? Gdzie się zatrzymać?
  • 3. Maciek Próchniak Niedoszły topolog algebraiczny Kontrybutor Activiti Integracja: Servicemix, Camel, Drools, OSGi, BPEL... Rzeczy mniej przyjemne: GWT, Smartclient, ... Last but not least - TouK ;)
  • 4. DSL Domain Chcemy móc opisać obiekty, reguły z naszej dziedziny Specific Nie zaprzątając sobie głowy resztą świata Language W jakimś języku (programowania)
  • 5. DSL - czy nie mamy już wystarczająco dużo języków?
  • 7. DSL - po co? Opisywanie reguł biznesowych Łatwiejesze przełożenie wymagań na kod Współpraca z ekspertami Zwiększona produktywność
  • 8. Kto korzysta z DSL? Programiści/Deweloperzy? PO/Eksperci biznesowi?
  • 9. Cobol fallacy ”Now we can get rid of programmers and have business people specify the rules themselves” - Cobol Fallacy wg. Martina Fowlera
  • 10. Znajomość czynna i znajomość bierna Znajomość bierna: ”Java je jedn´ z nejpouˇ´ ejˇ´ programovac´ jazyk˚ na ım zıvanˇ sıch ıch u svˇtˇ. Podle Tiobe indexu je Java nejpopul´rnˇjˇ´ programovac´ ee a e sı ı jazyk. (...) Dne 8. kvˇtna 2007 Sun uvolnil zdrojov´ kódy Javy (cca e e 2,5 milión˚ ˇ´dk˚ kódu) a Java bude d´le vyv´ u ra u a ıjena jako open source.” - http://cs.wikipedia.org/wiki/Java (programovac´ jazyk) ı Znajomość czynna? To już trudniejsze...
  • 11. DSL - po co? Opisywanie reguł biznesowych Łatwiejesze przełożenie wymagań na kod Współpraca z ekspertami Zwiększona produktywność
  • 12. Ale przecież mamy DDD? Bogaty model domenowy to podstawa DSL - ”widok” na model domenowy Model domeny to trudniejszy fragment
  • 13. Inny zestaw reguł Przy budowaniu DSL zwykle łamiemy ”żelazne” zasady: metody globalne/statyczne? CQS? prawo Demeter? ”małe” klasy?
  • 14. Inny zestaw reguł Potrzebne warstwy:
  • 15. DSL - ale jaki? zewnętrzny (external) SQL Regexp css schematy XML? wewnętrzny (embedded, DSEL) - jest osadzony w GPL Apache Camel Mockito JMock Rails
  • 16. Dlaczego wewnętrzne? Dostajemy ”za darmo”: Parser Kompilator Wsparcie IDE Rozszerzanie i obsługa niestandardowych przypadków
  • 17. Przykład: WS HumanTask Schemat XML opisu zadań do wykonania przez człowieka W typowym projekcie zadania są podobne Problem: jak zdefiniować typy właściwe dla konkretnego projektu
  • 18. Przykład: WS BPEL Schemat XML opisu działania procesu biznesowego Konieczność ujęcia wielu rodzajów akcji Problem: język staje się GPL
  • 19. Przykład pośredni: Drools Własny język definicji reguł Konieczność ujęcia wielu rodzajów akcji Korzyści: połączenie wyrażalności zewnętrznego DSL i możliwości Javy 1 r u l e AcceptOrder 2 when 3 $ c l i e n t : C l i e n t ( s t a t u s==APPROVED) 4 $ o r d e r : O r d e r ( s t a t u s== NEW, c l i e n t==$ c l i e n t ) 5 then 6 orderService . acceptOrder ( $order ) 7 end
  • 20. Dlaczego statycznie typowane? Języki dynamiczne oferują duże możliwości, ale: Wsparcie IDE Możliwości odkrywania API Każdy projekt trafi w końcu do studentów...
  • 21. Przykład - Apache Camel Implementacja wzorców EIP: router, splitter, aggregator, lista odbiorców, ... Definiowanie przepływów komunikacji Przykład: 1 c l a s s JamRouteBuilder extends R o u t e B u i l d e r { 2 public void c o n f i g u r e () { 3 from ( ” f i l e : / tmp/ i n ” ) 4 . convertBodyTo ( S t r i n g . c l a s s ) 5 . bean ( ” r e c i p i e n t R e p o s i t o r y ” ) 6 . r e c i p i e n t L i s t ( property (” recipients ” )); 7 } 8 }
  • 22. Płynny interfejs - klucz do sukcesu DSL Płynny interfejs Klasyczny model obiektowy
  • 23. Płynny interfejs - rozszerzony budowniczy 1 makeOrder (NORMAL) 2 . w i t h P r i c e ( new B i g D e c i m a l ( 2 2 . 0 0 ) ) 3 . w i t h D a t e ( ”2011−11−12” ) 4 . finish (); 1 p u b l i c O r d e r B u i l d e r makeOrder ( OrderType t y p e ) { 2 r e t u r n new O r d e r B u i l d e r ( t y p e ) ; 3 } 4 //w k l a s i e O r d e r B u i l d e r 5 public OrderBuilder w i t h P r i c e ( BigDecimal p r i c e ) { 6 this . price = price ; 7 return this ; 8 }
  • 24. Płynny interfejs - problem stopu 1 makeOrder (NORMAL) 2 . w i t h P r i c e ( new B i g D e c i m a l ( 2 2 . 0 0 ) ) 3 . w i t h D a t e ( ”2011−11−12” ) 4 . finish (); 1 p u b l i c Order f i n i s h ( ) { 2 return this . build () 3 }
  • 25. Płynny interfejs - problem stopu 1 makeOrder (NORMAL) 2 . w i t h P r i c e ( new B i g D e c i m a l ( 2 2 . 0 0 ) ) 3 . w i t h D a t e ( ”2011−11−12” ) 4 . withClientId (1334); Id klienta jest wymagane: 1 p u b l i c Order w i t h C l i e n t I d ( long l ) { 2 clientId = l ; 3 return this . build ( ) ; 4 }
  • 26. Płynny interfejs - wymuszanie kolejności 1 2 interface ClientPhoneBuilder { 3 S t r e e t B u i l d e r w i t h P h o n e ( S t r i n g phone ) ; 4 S t r e e t B u i l d e r withoutPhone ( ) ; 5 } 6 7 interface StreetBuilder { 8 ClientApartmentBuilder livingOn ( String street ); 9 C l i e n t homeless ( ) ; 10 } 11 ... 1 2 . w i t h P h o n e ( ” 2245556 ” ) . l i v i n g O n ( ” J e r o z o l i m s k i e ” ) .
  • 27. Płynny interfejs - zagnieżdżanie Możliwości: hierarchiczne buildery dodatkowe buildery
  • 28. Zagnieżdżanie builderów - hierarchie 1 . f i l t e r () 2 . x p a t h ( ” // o r d e r I d ” ) 3 . isEqualTo (15) 4 . send ( ” http : / / . . . ” ) 1 class RouteBuilder { 2 ... 3 ExpressionBuilder f i l t e r () { 4 t h i s . f i l t e r = new E x p r e s s i o n B u i l d e r ( t h i s ) ; 5 return this . f i l t e r ; 6 } 7 v o i d s e n d ( S t r i n g where ) { 8 ... 9 }
  • 29. Zagnieżdżanie builderów - hierarchie 1 . f i l t e r () 2 . x p a t h ( ” // o r d e r I d ” ) 3 . isEqualTo (15) 4 . send ( ” http : / / . . . ” ) 1 c l a s s E x p r e s s i o n B u i l d e r <T> { 2 3 T parent ; 4 5 E x p r e s s i o n B u i l d e r xpath ( S t r i n g xpath ) { 6 t h i s . e x p r e s s i o n = new X P a t h E x p r e s s i o n ( x p a t h ) ; 7 return this ; 8 } 9 T isEqualTo ( String value ) { 10 t h i s . a s s e r t i o n = new E q u a l i t y ( v a l u e ) : 11 return parent ; 12 } 13 }
  • 30. Zagnieżdżanie builderów - oddzielne buildery 1 2 c la s s SenderRouter extends RouteBuilder { 3 ... 4 . filter ( 5 x p a t h ( ” // o r d e r I d ” ) . i s E q u a l T o ( 1 5 ) 6 ) . send ( ” http : / / . . . ” ) 7 ... 8 E x p r e s s i o n B u i l d e r xpath ( S t r i n g xpath ) { 9 r e t u r n new X P a t h B u i l d e r ( x p a t h ) ; 10 } 11 } Obiekt kontekstu jest lepszy niż funkcje globalne 1 class XpathBuilder extends ExpressionBuilder { 2 Expression isEqualTo ( String value ) { 3 t h i s . a s s e r t i o n = new E q u a l i t y ( v a l u e ) : 4 return build ( ) ; 5 }
  • 31. Płynny interfejs - zagnieżdżanie hierarchiczne buildery lepszy dostęp do kontekstu lepsze podpowiedzi IDE dodatkowe buildery prostsze reużywalność rozszerzalność
  • 32. Co dalej? Cały czas dużo szumu syntaktycznego: 1 from ( ” s e d a : a ” ) 2 . choice () 3 . when ( h e a d e r ( ” f o o ” ) . i s E q u a l T o ( ” b a r ” ) ) 4 . to (” seda : b ”) 5 . otherwise () 6 . p r o c e s s ( new P r o c e s s o r ( ) { 7 p u b l i c v o i d p r o c e s s ( Exchange e x ) { 8 e x . s e t P r o p e r t y ( ” d a t e ” , new Date ( ) ) ; 9 } 10 }); Tu kończą się możliwości Javy...
  • 33. Scala comes to the rescue! ”normalny” język: programowanie obiektowe statyczne typowanie można programować funkcyjnie prosty pattern matching dużo lukru syntaktycznego
  • 34. Scala comes to the rescue! uproszczenia składni, przeciążanie operatorów domyślne (implicit) konwersje i parametry funkcje i domknięcia
  • 35. Uproszczenia składni W wielu miejscach kropki i przecinki stają się opcjonalne: 1 order () 2 . s i z e ( 1 1 ) . express ( true ) A więc: 1 order () 2 s i z e 11 3 express true
  • 36. Przeciążanie operatorów Wszystko jest metodą 1 c l a s s Balance ( balance : BigDecimal ) { 2 d e f + ( toAdd : B a l a n c e ) : B a l a n c e = { 3 new B a l a n c e ( b a l a n c e+toAdd . g e t B a l a n c e ) } 4 def getBalance = balance 5 } A więc: 1 println 2 ( ( new B a l a n c e ( 1 0 ) + new B a l a n c e ( 1 0 ) ) . g e t B a l a n c e ) ;
  • 37. Domyślne konwersje Dodawanie metod do klas - monkey patching Języki dynamiczne robią to globalnie Jak można to zrobić bezpieczniej?
  • 38. Domyślne konwersje Dodajemy możliwość autokonwersji w obrębie danej klasy: 1 c l a s s Orders { 2 i m p l i c i t def stringToOrder ( s t r : String ) = 3 new O r d e r B u i l d e r ( s t r ) ; 4 } 5 6 class OrderBuilder ( c l i e n t : String ) { 7 var p r i c e : BigDecimal = 0; 8 def w i t h P r i c e ( newPrice : BigDecimal ) = 9 { p r i c e = newPrice ; b u i l d ; } 10 def build = . . . 11 }; I możemy napisać: 1 c l a s s VIPOrders extends Orders { 2 ” c l i e n t ” withPrice 1.22 3 }
  • 39. Przekazywanie strategii - funkcje i domknięcia Przekazywanie wyrażeń, predykatów - Java 1 . f i l t e r ( new E x p r e s s i o n ( ) { 2 p u b l i c b o o l e a n e v a l u a t e ( Message message ) { 3 r e t u r n VIP == message . g e t P r o p e r t y ( ” c l i e n t T y p e ” ) ; 4 } 5 }). Scala: 1 . f i l t e r { e x c h a n g e => 2 VIP==e x c h a n g e . g e t P r o p e r t y ( ” c l i e n t T y p e ” ) }
  • 40. Przekazywanie strategii - funkcje i domknięcia Przekazywanie wyrażeń, predykatów - Scala 1 ” d i r e c t : b” == { > 2 when ( . i n == ”< h a l l o />” ) { 3 −−> ( ”mock : b” ) 4 t o ( ”mock : c ” ) 5 } otherwise { 6 p r o c e s s ( e x => e x . s e t P r o p e r t y ( ” d a t e ” , new Date ( ) ) ) 7 } 8 t o ( ”mock : d” ) 9 }
  • 41. 1 case c l a s s SChoiceDefinition 2 ( override val target : ChoiceDefinition ) . . . { 3 override def otherwise = { 4 target . otherwise 5 this 6 } 7 8 o v e r r i d e d e f when ( f i l t e r : Exchange => Any ) = { 9 val predicate = PredicateBuilder . toPredicate ( f i l t e r ) 10 t a r g e t . when ( p r e d i c a t e ) 11 this 12 } 13 }
  • 42. Granice czytelności i wyrażalności Język naturalny: 1 Stworz zamowienie 2 d l a k l i e n t a ”TouK” Fleksja? Synonimy? Koniugacja?
  • 43. O jeden krok za daleko? Definiowanie 1 class OrderBuilder ( c l i e n t : String ) { 2 var nameField : S t r i n g = ””; 3 def name = { n a m e F i e l d = } 4 def with a = t h i s ; 5 }; By napisać 1 c l a s s VIPOrders extends Orders { 2 ” c l i e n t ” . w i t h a name ” a l a ” ; 3 }
  • 45. Rozszerzanie - przykład DSL do bardzo prostych procesów stanowych interakcje oparte na Apache Camel 1 s t a r t ( ” d i r e c t : employee ” ) . f o r k ( 2 s t a t e ( ” h r S t a r t ” ) . to ( ” f i l e :/// hr ” ) 3 . w a i t S t a t e ( ” waitingForHR ” , ” f i l e :/// h r I n ” ) 4 . s t a t e ( ” hrEnd ” ) , 5 s t a t e ( ” i t S t a r t ” ) . to ( ” f i l e :/// i t ” ) 6 . waitState (” waitingForIT ” ,” f i l e :/// i t I n ”) 7 . state (” itEnd ”) 8 ) . s t a t e ( ” end ” ) ;
  • 46. Rozszerzanie - przykład Trudno ”wpiąć” się ze swoimi rozszerzeniami Problem: Użycie zagnieżdżonych builderów Możliwe rozwiązania: Używanie oddzielnych builderów i obiektu kontekstu Nadpisanie pewnej części źródłowego DSL - może być skomplikowane
  • 47. Podsumowując... DSL może zwiększyć czytelność i zwięzłość kodu Wewnętrzne DSLe w statycznie typowanych językach mają niski koszt budowy i nauki Korzystając ze Scali możemy zmniejszyć szum syntaktyczny w naszym DSLu Projektując DSL trzeba myśleć o jego rozwoju i możliwościach rozszerzania
  • 49. I inne zasoby http://weblogs.java.net/blog/carcassi/archive /2010/02/04/building-fluent-api-internal-dsl-java http://pragdave.blogs.pragprog.com/pragdave/2008/03/the- language-in.html http://www.infoq.com/articles/internal-dsls-java
  • 51. Użyłem Zdjęć: http://www.flickr.com/photos/gibbons/2294375187/ http://www.flickr.com/photos/wwworks/2472232245/ http://www.flickr.com/photos/siomuzzz/2577041081/ http://www.flickr.com/photos/r4n/3049253551/ http://www.flickr.com/photos/neilwykes/3219711243/ http://www.flickr.com/photos/donsolo/3666985941/ http://www.flickr.com/photos/saeba/4214372479/ http://www.flickr.com/photos/maysbusinessschool/4948659050/ http://www.flickr.com/photos/pixelcore/91132699/ A I szablonu LTEXby mcl :)