SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
Domain Specific Languages
Escreva menos e entenda mais com DSLs desacopladas
By /Leonardo Tumadjian @tumadjian
Sobre mim:
Formado em Análise e Desenvolvimento de Sistemas
Programador PHP desde 2009
Instrutor desde 2012
Nas horas vagas: Gamer, Biker, Shooter, Guitarrista
Evangelista da comunidade PHPSP
Víciado em séries estranhas!
Antes de começarmos:
Contribua com sua comunidade mais próxima, se tiver um
tempo ;)
Como contribuir?
Aviso!
O conteúdo desta palestra tem o intuito de ilustrar como as
DSLs podem facilitar a usabilidade de seu código, porém
devemos ter em mente que são específicos os casos, e que
devem ser analisados com muita cautela.
Referências
Alinhamento
API comando-consulta: componente ou biblioteca
ex: BrowserKit, SwiftMailer, Dispatcher, etc..
Linguagem de propósito geral: PHP, Java, C++, Ruby
Modelo Semântico: Modelo de objetos ou estrutura de dados
O que é?
“A computer programming language of limited
expressiveness focused on a particular
domain.” ―Martin Fowler
Quando usar?
Tipos de DSLs
Externas
Internas
Bancadas(Workbenches)
DSLs Externas
route
  path         /myblog/{pageId}/{commentId}
  controller   Myblog::commentsAction
  assert       pageId: "d+", commentId: "d+"
  request      GET
end
route
  path         /myblog/joinin
  controller   Myblog::processForm
  request      POST
end
DSLs Externas
// Without the External DSL
require __DIR__ . '/vendor/autoload.php';
use SymfonyComponentRoutingRoute;
$app = new SilexApplication();
$route1 = new Route('/myblog/{pageId}/{commentId}');
$route1­>setDefault('_controller', 'Myblog::commentsAction');
$route1­>setMethods(['GET']);
$route1­>setRequirement('pageId', 'd+');
$route1­>setRequirement('commentId', 'd+');
$app['routes']­>add('route1', $route1);
$route2 = new Route('/myblog/joinin');
$route2­>setDefault('_controller', 'Myblog::processForm');
$route2­>setMethods(['POST']);
$app['routes']­>add('route2', $route2);
$app­>run();
DSLs Externas Agenda
Agenda
    Appointment Dentist
        date 2016­01­15
            from 17:00
            to 18:00
    Appointment Dinner at Tiffani`s
        date 2016­12­25
            from 17:00
            to 18:00
EndAgenda
DSLs Externas
Case de sucesso de uso de DSL externa, o Behat
Scenario: List 2 files in a directory
  Given I am in a directory "test"
  And I have a file named "foo"
  And I have a file named "bar"
  When I run "ls"
  Then I should get:
    """
    bar
    foo
    """
Usabilidade:
Scenario: Some description of the scenario
  Given [some context]
  When [some event]
  Then [outcome]
DSLs Externas
// Generated class by behat command
class FeatureContext extends BehatContext
{
    private $output;
    // ...
    /** @Given /^I am in a directory "([^"]*)"$/ */
    public function iAmInADirectory($dir)
    {
        if (!file_exists($dir)) {
            mkdir($dir);
        }
        chdir($dir);
    }
    /** @Given /^I have a file named "([^"]*)"$/ */
    public function iHaveAFileNamed($file)
    {
        touch($file);
    }
    // ...
}
DSLs Internas
// Without Internal DSL
$o1 = new Order();
$customer­>addOrder($o1);
$line1 = new OrderLine(6, Product::find('TAL'));
$o1­>addLine($line1);
$line2 = new OrderLine(5, Product::find('HPK'));
$o1­>addLine($line2);
$line3 = new OrderLine(3, Product::find('LGV'));
$o1­>addLine($line3);
$line2­>setSkippable(true);
$o1­>setRush(true);
// With Internal DSL
$customer­>newOrder()
    ­>with(6, 'TAL')
    ­>with(5, 'HPK')­>skippable()
    ­>with(3, 'LGV')
    ­>priorityRush();
Font by Cal Evans: http://devzone.zend.com/777/fluent-interfaces-in-php/
Symfony Validation
use SymfonyComponentValidatorValidation;
use SymfonyComponentValidatorConstraints as Assert;
$constraint = [
    new AssertLength([
        'min' => 5,
        'max' => 20
    ]),
    new AssertNotBlank(),
    new AssertEmail()
];
$validator = Validation::createValidator();
$errors = $validator­>validate('teste@gmail.com', $constraint);
DSLs Internas
use DSLPALDSLValidator;
$fluent = new DSLValidator;
$errors = $fluent­>length(5, 20)
                 ­>notBlank()
                 ­>email()
                 ­>validate('teste@teste.com');
Symfony Validation
use SymfonyComponentValidatorValidation;
use SymfonyComponentValidatorConstraints as Assert;
$constraints = new AssertCollection([
    'nome' => [
        new AssertType('string'),
        new AssertLength(['min' => 5, 'max' => 10])
    ],
    'email' => [
        new AssertEmail()
    ],
    'sexo' => new AssertOptional([
        new AssertNotBlank(),
        new AssertChoice(['M', 'F'])
    ])
]);
$validator = Validation::createValidator();
$res = $validator­>validate([
    'nome' => 'Leonardo',
    'email' => 'teste@teste.com',
    'sexo' => 'N'
], $constraints);
DSLs Internas
use DSLPALDSLValidator;
$fluent = new DSLValidator;
$constraints = $fluent­>collection([
    'nome'  =>  $fluent
                  ­>type('string')
                  ­>length(5, 10)
                ­>end(),
    'email' =>  $fluent
                  ­>email()
                ­>end(),
    'sexo'  =>  $fluent
                  ­>notBlank()
                  ­>choice(['M', 'F'])
                  ­>optional()
                ­>end()
]);
$res = $constraints­>validate([
    'nome' => 'Leonardo',
    'email' => 'teste@teste.com',
    'sexo' => 'N'
]);
DSLs Internas
use DSLPALValidatorFactory as dsl;
$const = dsl::collection([
    'nome' => dsl::type('string')
                 ­>length(5, 10),
    'email' => dsl::email(),
    'sexo' => dsl::notBlank()
                 ­>choice(['M', 'F'])
                 ­>optional()
]);
$erros = $const­>validate([
    'nome' => 'Leonardo',
    'email' => 'teste@teste.com',
    'sexo' => 'N'
]);
Cases de sucesso:
Respect Validator: http://respect.github.io/Validation/
// Use Respect/Validation!
use RespectValidationValidator as v;
$res = v::numeric()
         ­>positive()
         ­>between(1, 255)
         ­>validate(180);
Mockery: http://docs.mockery.io
public function testGetsAverageTemperatureFromThreeServiceReadings()
{
    $service = m::mock('service');
    $service­>shouldReceive('readTemp')
            ­>times(3)
            ­>andReturn(10, 12, 14);
    $temperature = new Temperature($service);
    $this­>assertEquals(12, $temperature­>average());
}
Annotations
/**
 * @ManyToMany(targetEntity="Group", inversedBy="features")
 * @JoinTable(name="user_groups",
 *      joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@JoinColumn(name="group_id", referencedColumnName="id
 *      )
 */
private $groups;
/**
 * Inverse Side
 *
 * @ManyToMany(targetEntity="User", mappedBy="groups")
 */
private $features;
Como programar DSLs?
Sugestão de workflow
Algumas reflexões:
1. Seu Modelo Semantico é complexo?
2. Se sim, você deve saber usá-lo muito bem
3. Evite retornar objetos diferentes do modelo DSL
4. Lance sempre exceções detalhando os erros
5. Contexto completo para a execução
6. Sua DSL deve ser TODA documentada
7. Simplifique sempre, evite nome de métodos complexos
8. DSLs não são feitas só de encadeamento de métodos
Construindo DSL de Agendamento
// API Comando­consulta Calendar
use CalendarAgenda;
use CalendarAppointment;
$agenda = new Agenda;
$appoint = Appointment::create();
$appoint­>setAppointment('Dentist');
$appoint­>setDate(15, 01, 2016);
$appoint­>setFrom('17:00');
$appoint­>setTo('18:00');
$agenda­>addAppointment($appoint);
$appoint = Appointment::create();
$appoint­>setAppointment('Dinner at Tiffani`s');
$appoint­>setDate(25, 12, 2015);
$appoint­>setFrom('18:00');
$appoint­>setTo('01:00');
$agenda­>addAppointment($appoint);
Como ficará a DSL
// DSL for Calendar
use CalendarBuilder;
$builder = Builder::make();
$builder
    ­>add('Dentist')
        ­>on(1, 15, 2016)
        ­>from('17:00')
        ­>to('18:00')
    ­>add('Dinner at Tiffani`s')
        ­>on(12, 25, 2015)
        ­>from('18:00')
        ­>to('01:00')
;
$agenda = $builder­>getAgenda();
$user­>setAgenda($agenda);
O construtor
namespace Calendar;
// Construtor de Expressões / Desacoplar a DSL
class Builder
{
    /**
     * @var Agenda
     */
    protected $agenda; // keep all the appointments inside
    public function __construct(Agenda $agenda)
    {
        $this­>agenda = $agenda;
    }
    public static function make()
    {
        return new self(new Agenda);
    }
    // ...
}
Os métodos
    // ... Inside Class Builder
    public function add($name)
    {
        $this­>agenda­>addAppointment(Appointment::create());
        $this­>current()­>setAppointmentName($name);
        return $this;
    }
    public function on($month, $day, $year)
    {
        $this­>current()­>setDate($month, $day, $year);
        return $this;
    }
    protected function current()
    {
        return $this­>agenda­>getCurrent();
    }
    // ...
Retorna o objeto Agenda já configurado
    // ... Inside Class Builder
    public function getAgenda()
    {
        // Clona o objeto para retornar
        $agenda = clone $this­>agenda;
        // Limpa o iterator da propriedade $agenda
        $this­>agenda­>__construct();
        return $agenda;
    }
    // ...
Muito cuidado com referência X copia de objeto
Problemas com DSLs
1. Cacofonia de linguagem
2. Custo de construção
3. Linguagem de gueto
4. Abstração restrita
5. Difícil testar
6. Fácil fazer errado
Outros exemplos
// Sequência de funções
car('Maverik');
    engine('V8');
        cylinders('3,535');
        filter('Monster');
    color('green');
    doors(2);
// Função aninhada
car(
    'Maverik',
    engine(
        'V8',
        cylinders('3,535'),
        filter('Monster')
    ),
    color(
        'green'
    ),
    doors(
        2
    )
);
Outros exemplos
// Fecho aninhado ­ Closures
$carBuilder­>make(function ($car, $engine, $torque) {
    $car­>name = 'Maverik';
    $car­>color = 'green';
    $car­>doors = 2;
    $car­>engine(function () use ($engine, $torque) {
        $engine­>type = 'V8';
        $engine­>cylinder = '3,535';
        $engine­>torque(function () use ($torque) {
            $torque­>initial = '1000rpm'; // not real
            $torque­>final = '70000rpm'; // not real
        });
    });
});
Atenção!
Tomem muito cuidado para que isso não
aconteça com vocês
That's all folks!
Espero que tenham gostado, dúvidas?
Obrigado!
Meus contatos
About me: https://about.me/leonardotumadjian
Email me: tumadjian@gmail.com
Twitter: @tumadjian
Exemplos no Github

Contenu connexe

En vedette

Drilling machine metal woprk
Drilling machine  metal woprkDrilling machine  metal woprk
Drilling machine metal woprkgarfield Tulloch
 
Competency framework all
Competency framework allCompetency framework all
Competency framework allNaureen Khalid
 
Formatação condicional e Fixação de Áreas
Formatação condicional  e Fixação de ÁreasFormatação condicional  e Fixação de Áreas
Formatação condicional e Fixação de ÁreasPaula Peres
 
Antenna hyperthermia synopsis_abstract
Antenna hyperthermia synopsis_abstractAntenna hyperthermia synopsis_abstract
Antenna hyperthermia synopsis_abstractEshaan Verma
 
Luanne Sayag - Seh haElohim
Luanne Sayag - Seh haElohimLuanne Sayag - Seh haElohim
Luanne Sayag - Seh haElohimPulp Ark
 
Diagnóstico y tratamiento de dermatofitosis y pitiriasis versicolor
Diagnóstico y tratamiento de dermatofitosis y pitiriasis versicolorDiagnóstico y tratamiento de dermatofitosis y pitiriasis versicolor
Diagnóstico y tratamiento de dermatofitosis y pitiriasis versicolorIPN
 

En vedette (12)

Welding safety
Welding safetyWelding safety
Welding safety
 
Drilling machine metal woprk
Drilling machine  metal woprkDrilling machine  metal woprk
Drilling machine metal woprk
 
Competency framework all
Competency framework allCompetency framework all
Competency framework all
 
Formatação condicional e Fixação de Áreas
Formatação condicional  e Fixação de ÁreasFormatação condicional  e Fixação de Áreas
Formatação condicional e Fixação de Áreas
 
Antenna hyperthermia synopsis_abstract
Antenna hyperthermia synopsis_abstractAntenna hyperthermia synopsis_abstract
Antenna hyperthermia synopsis_abstract
 
Ficha técnica
Ficha técnicaFicha técnica
Ficha técnica
 
Presentación
PresentaciónPresentación
Presentación
 
Meninges lcr juanvera_18639459
Meninges lcr juanvera_18639459Meninges lcr juanvera_18639459
Meninges lcr juanvera_18639459
 
Luanne Sayag - Seh haElohim
Luanne Sayag - Seh haElohimLuanne Sayag - Seh haElohim
Luanne Sayag - Seh haElohim
 
Atlas dien tam do
Atlas dien tam doAtlas dien tam do
Atlas dien tam do
 
Ed400 users-manual
Ed400 users-manualEd400 users-manual
Ed400 users-manual
 
Diagnóstico y tratamiento de dermatofitosis y pitiriasis versicolor
Diagnóstico y tratamiento de dermatofitosis y pitiriasis versicolorDiagnóstico y tratamiento de dermatofitosis y pitiriasis versicolor
Diagnóstico y tratamiento de dermatofitosis y pitiriasis versicolor
 

Similaire à Escreva menos e entenda mais com DSLs desacopladas

Programe na Velocidade da Luz
Programe na Velocidade da LuzPrograme na Velocidade da Luz
Programe na Velocidade da LuzDaniel Polito
 
Dicas para sua carreira de Desenvolvedor PHP
Dicas para sua carreira de Desenvolvedor PHPDicas para sua carreira de Desenvolvedor PHP
Dicas para sua carreira de Desenvolvedor PHPDouglas V. Pasqua
 
DDD e PHP - TDC 2012
DDD e PHP - TDC 2012DDD e PHP - TDC 2012
DDD e PHP - TDC 2012Luís Cobucci
 
PHP Turbinado com CodeIgniter - Conisli 2011
PHP Turbinado com CodeIgniter - Conisli 2011PHP Turbinado com CodeIgniter - Conisli 2011
PHP Turbinado com CodeIgniter - Conisli 2011Evaldo Junior
 
Aula 01 - Programação Web - PHP
Aula 01  - Programação Web - PHPAula 01  - Programação Web - PHP
Aula 01 - Programação Web - PHPDalton Martins
 
Linguagens de programação 03-12-09
Linguagens de programação   03-12-09Linguagens de programação   03-12-09
Linguagens de programação 03-12-09essa
 
Linguagens de programação 03-12-09
Linguagens de programação   03-12-09Linguagens de programação   03-12-09
Linguagens de programação 03-12-09essa
 
Aula 01 introdução ao php
Aula 01   introdução ao phpAula 01   introdução ao php
Aula 01 introdução ao phpAdriano Castro
 
Linguagen..
Linguagen..Linguagen..
Linguagen..essa
 
Gerenciamento de dependências em PHP com o Composer
Gerenciamento de dependências em PHP com o ComposerGerenciamento de dependências em PHP com o Composer
Gerenciamento de dependências em PHP com o ComposerAndre Cardoso
 
#DNAD15 - Diminuindo sofrimento com código legado de linguagens não mainstreams
#DNAD15  - Diminuindo sofrimento com código legado de linguagens não mainstreams#DNAD15  - Diminuindo sofrimento com código legado de linguagens não mainstreams
#DNAD15 - Diminuindo sofrimento com código legado de linguagens não mainstreamsJacqueline Abreu
 
Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015
Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015
Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015Jacqueline Abreu
 
Apresentação da Linguagem de Programação PHP
Apresentação da Linguagem de Programação PHPApresentação da Linguagem de Programação PHP
Apresentação da Linguagem de Programação PHPLorranna Machado
 
Aula 02 - Introdução ao PHP
Aula 02 - Introdução ao PHPAula 02 - Introdução ao PHP
Aula 02 - Introdução ao PHPDaniel Brandão
 
Evolução do .NET Framework e do Visual Basic
Evolução do .NET Framework e do Visual BasicEvolução do .NET Framework e do Visual Basic
Evolução do .NET Framework e do Visual BasicRicardo Guerra Freitas
 
P01 - Como ser um desenvolvedor melhor
P01 - Como ser um desenvolvedor melhorP01 - Como ser um desenvolvedor melhor
P01 - Como ser um desenvolvedor melhorLeandro Ferreira
 

Similaire à Escreva menos e entenda mais com DSLs desacopladas (20)

Programe na Velocidade da Luz
Programe na Velocidade da LuzPrograme na Velocidade da Luz
Programe na Velocidade da Luz
 
Dicas para sua carreira de Desenvolvedor PHP
Dicas para sua carreira de Desenvolvedor PHPDicas para sua carreira de Desenvolvedor PHP
Dicas para sua carreira de Desenvolvedor PHP
 
DDD e PHP - TDC 2012
DDD e PHP - TDC 2012DDD e PHP - TDC 2012
DDD e PHP - TDC 2012
 
PHP para iniciantes - Boas Práticas
PHP para iniciantes - Boas PráticasPHP para iniciantes - Boas Práticas
PHP para iniciantes - Boas Práticas
 
PHP Turbinado com CodeIgniter - Conisli 2011
PHP Turbinado com CodeIgniter - Conisli 2011PHP Turbinado com CodeIgniter - Conisli 2011
PHP Turbinado com CodeIgniter - Conisli 2011
 
Aula 01 - Programação Web - PHP
Aula 01  - Programação Web - PHPAula 01  - Programação Web - PHP
Aula 01 - Programação Web - PHP
 
Linguagens de programação 03-12-09
Linguagens de programação   03-12-09Linguagens de programação   03-12-09
Linguagens de programação 03-12-09
 
Linguagens de programação 03-12-09
Linguagens de programação   03-12-09Linguagens de programação   03-12-09
Linguagens de programação 03-12-09
 
Aula 01 introdução ao php
Aula 01   introdução ao phpAula 01   introdução ao php
Aula 01 introdução ao php
 
Comparativo do uso de linguagens de programação e geradores de código no dese...
Comparativo do uso de linguagens de programação e geradores de código no dese...Comparativo do uso de linguagens de programação e geradores de código no dese...
Comparativo do uso de linguagens de programação e geradores de código no dese...
 
Linguagen..
Linguagen..Linguagen..
Linguagen..
 
Gerenciamento de dependências em PHP com o Composer
Gerenciamento de dependências em PHP com o ComposerGerenciamento de dependências em PHP com o Composer
Gerenciamento de dependências em PHP com o Composer
 
#DNAD15 - Diminuindo sofrimento com código legado de linguagens não mainstreams
#DNAD15  - Diminuindo sofrimento com código legado de linguagens não mainstreams#DNAD15  - Diminuindo sofrimento com código legado de linguagens não mainstreams
#DNAD15 - Diminuindo sofrimento com código legado de linguagens não mainstreams
 
Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015
Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015
Uma linguagem para chamar de minha: Criando DSLs no dia a dia - QConRio2015
 
Seminário: PHP
Seminário: PHPSeminário: PHP
Seminário: PHP
 
Apresentação da Linguagem de Programação PHP
Apresentação da Linguagem de Programação PHPApresentação da Linguagem de Programação PHP
Apresentação da Linguagem de Programação PHP
 
Aula 02 - Introdução ao PHP
Aula 02 - Introdução ao PHPAula 02 - Introdução ao PHP
Aula 02 - Introdução ao PHP
 
Evolução do .NET Framework e do Visual Basic
Evolução do .NET Framework e do Visual BasicEvolução do .NET Framework e do Visual Basic
Evolução do .NET Framework e do Visual Basic
 
Condingdojo
CondingdojoCondingdojo
Condingdojo
 
P01 - Como ser um desenvolvedor melhor
P01 - Como ser um desenvolvedor melhorP01 - Como ser um desenvolvedor melhor
P01 - Como ser um desenvolvedor melhor
 

Escreva menos e entenda mais com DSLs desacopladas