SlideShare a Scribd company logo
1 of 70
Do Clipper e Delphi ao Ruby e PHP
Antes e depois dos frameworks
Pablo Dall'Oglio
@pablodalloglio fb/pablodalloglio
Adianti Solutions Ltda © Pablo Dall'Oglio #2
1994
Inicia no Brasil a execução do Plano Real
Adianti Solutions Ltda © Pablo Dall'Oglio #3
1994
Raimundos lança seu primeiro disco
Adianti Solutions Ltda © Pablo Dall'Oglio #4
1994
Século em que o Wolf ainda tinha cabelo
Adianti Solutions Ltda © Pablo Dall'Oglio #5
CA-Clipper
Sobre o Clipper
●
Compilador criado em 1985 para linguagem xBase;
●
Ideia surgiu no restaurante (Nantucket), quadro (Clipper);
●
Dados armazenados em arquivos .DBF;
●
Linguagem de execução procedural (v5.2 = 1,6Mb);
●
Durou até a versão 5.3b (1997). Não há mais suporte;
●
Existem iniciativas da comunidade (Flagship);
●
Comandos (USE, SKIP, GOTOP, GO BOTTOM, e GO #);
●
PC: 486 50 Mhz. Memória: 4Mb de RAM, HD: 512 Mb;
●
Outras tecnologias da época:Turbo Pascal, C, Basic, DataFlex.
Adianti Solutions Ltda © Pablo Dall'Oglio #6
CA-Clipper
Telas desenhadas artisticamente by hand
Adianti Solutions Ltda © Pablo Dall'Oglio #7
Procedural
CAD_CLI.PRG
@ 2,5,19,70 window "Cadastro de Clientes"
cCOD_CLI := cad_cli->COD_CLI
cNOME := cad_cli->NOME
cENDERECO := cad_cli->ENDERECO
@ 0,1 say "Codigo_____________ " + cad_cli->COD_CLI
@ 1,1 say "Nome________________" get cNOME pict "@!"
@ 2,1 say "Endereço____________" get cENDERECO
if CONFIRMA("Confirma Alteração ?",20,44)
if cad_cli->(RECLOCK())
cad_cli->COD_CLI := cCOD_CLI
cad_cli->NOME := cNOME
cad_cli->ENDERECO := cENDERECO
cad_cli->(dbunlockall())
endif
endif
Exibe e coleta
Registro trabalhado
como um objeto
Sem SQL
Persistência e concorrência
Adianti Solutions Ltda © Pablo Dall'Oglio #8
Procedural
NOTA_FISCAL.PRG
function PROCESSA_NF()
ABRE("RES_NF")
if CONFIRMA("Confirma Nota Fiscal")
res_nf->(dbappend())
if CONFIRMA("Imprimir Nota Fiscal")
PRINT_NF( cSERIE_NF, nNUM_NF, cFILE )
endif
if CONFIRMA("Imprimir Duplicata")
IMPR_DUPLICATA(nNUM_NF, cCOD_CLI)
endif
endif Funções do
User Space
Adianti Solutions Ltda © Pablo Dall'Oglio #9
Procedural
CUPOM_FISCAL.PRG
function PROCESSA_CF()
function REGISTRA_CF( nVLR_TOT_CF,... )
function SHOW_TOTAIS()
function CANCELA_ITEM( nITEM, cDESCR )
function BAIXA_ESTOQUE()
function ALTA_ESTOQUE()
function ABRE_CUPOM()
function FECHA_CUPOM( nVLR_TOT_CF, nVLR_PAGO, ... )
function CANCELA_CUPOM( lFICOUABERTO )
function VENDE_ITEM( cCODIGO, cDESCR, nQUANT, nPR_VENDA, cITEM )
function LEITURA_X()
function REDUCAO_Z()
Cadeia de dependências
não muito clara
Adianti Solutions Ltda © Pablo Dall'Oglio #10
CA-Clipper
Considerações:
●
Muito rápido e enxuto (Ex: Controle de vendas 841 Kb);
●
Não leva a organização modular, somente separação por funções;
●
Não leva a organização de nomes: Fica a cargo de cada um;
●
Programas geralmente organizados em torno de telas;
●
Não facilita o reuso: Dificuldade identificar partes para reaproveitar;
●
Suscetível à mudanças: Dificuldade em localizar dependências;
●
Diferentes aspectos no mesmo programa:
– Apresentação: @ 0,1 say "Codigo_____________ ";
– Controle: if CONFIRMA("Confirma Nota Fiscal");
– Persistência: cad_cli->(dbunlockall()).
Adianti Solutions Ltda © Pablo Dall'Oglio #11
1998
Coisas muito estranhas aconteceram
Adianti Solutions Ltda © Pablo Dall'Oglio #12
1998
Coisas muito estranhas mesmo
Adianti Solutions Ltda © Pablo Dall'Oglio #13
Delphi
Sobre o Delphi
●
Lançado pela Borland em 1995, como substituto doTurbo Pascal;
●
Assim como oTurbo Pascal, foi idealizado por Anders Hejlsberg (DN);
●
Anders Hejlsberg em 1996 move para MS, onde idealizou o C#;
●
Em 2001, foi lançado o Kylix, versão para Linux;
●
Posteriormente, a comunidade criou o Lazarus;
●
Características fortes:
– Programação visual (drag and drop);
– Programação orientada a eventos (OnClick, OnChange);
– Utilização de componentes (TButton, TEdit, TSpinButton);
●
Outras tecnologias da época:Visual Basic, Power Builder.
Adianti Solutions Ltda © Pablo Dall'Oglio #14
Delphi
Data Sources, Tabelas
usadas pelo
formulário
Mapeamento entre
objeto visual e BD
Adianti Solutions Ltda © Pablo Dall'Oglio #15
Delphi
unit untCadastro;
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, ...
type
TfrmCadastro = class(TForm)
dtbEndereco: TDatabase;
tabEndereco: TTable;
dtsEndereco: TDataSource;
tabEnderecoNome: TStringField;
dgrEndereco: TDBGrid;
Label1: TLabel;
dedCodigo: TDBEdit;
var
frmCadastro: TfrmCadastro;
implementation
Formulário:
Arquivo separado
Data Sources, Tabelas
usadas pelo
formulário
Adianti Solutions Ltda © Pablo Dall'Oglio #16
Delphi
procedure TfrmCadastro.FormCreate(Sender: TObject);
begin
dtbEndereco.Open;
tabEndereco.Open;
end;
procedure TfrmCadastro.sbnEditarClick(Sender: TObject);
begin
tabEndereco.Edit;
end;
procedure TfrmCadastro.sbnGravarClick(Sender: TObject);
begin
tabEndereco.Post;
end;
Entra em edição
Envia dados
Adianti Solutions Ltda © Pablo Dall'Oglio #17
Delphi
Considerações:
●
Fortaleceu o uso da Orientação a Objetos;
●
Consolidou o conceito de componente de interface (cápsulas);
●
Levou a uma separação entre Interface (.dfm) e Lógica (.pas);
●
Formou uma geração de programadores, acostumada à:
– Arrastar e soltar objetos na tela (drag and drop);
– Programar a lógica orientada à eventos;
– Vincular fortemente o modelo de dados à interface.
●
Não promoveu a tempo uma separação da lógica e do modelo;
●
Essa geração tem dificuldades naWeb, que é orientada à requests.
Adianti Solutions Ltda © Pablo Dall'Oglio #18
2000
No Brasil, KLB vendia mais de 1 milhão de discos...
Adianti Solutions Ltda © Pablo Dall'Oglio #19
2000
ZH
16/08/2000
Adianti Solutions Ltda © Pablo Dall'Oglio #20
2001
Adianti Solutions Ltda © Pablo Dall'Oglio #21
Início foi dureza...
<?php
// configuração
$conn = pg_connect("...");
// query
$query = 'SELECT id, nome, endereco FROM cliente WHERE id not in (...)';
// resultados
$result = pg_query($conn, $query);
if ($result)
{
// apresentação
echo '<table border="1">';
while ($row = pg_fetch_assoc($result))
{
echo '<tr>';
echo '<td>' . $row['id'] . '</td>';
echo '<td>' . $row['nome'] . '</td>';
echo '<td>' . $row['endereco'] . '</td>';
echo '</tr>';
}
echo '</table>';
}
pg_close($conn);
Business rules
Apresentação
Configuração
Adianti Solutions Ltda © Pablo Dall'Oglio #22
Design Patterns
Padrões de Projeto
“Um Pattern descreve um problema que ocorre com frequência em
nosso ambiente, e então explica a essência da solução para este
problema, de forma que tal solução possa ser utilizada milhões de
outras vezes...”
Christopher Alexander (1936 arquiteto)
Adianti Solutions Ltda © Pablo Dall'Oglio #23
MVC
MVC
●
Model
●
View
●
Controller
Adianti Solutions Ltda © Pablo Dall'Oglio #24
MVC
MVC
●
Model
●
View
●
Controller
Adianti Solutions Ltda © Pablo Dall'Oglio #25
Frameworks
Frameworks
●
Implementam vários Design Patterns;
●
Fornecem uma arquitetura (arcabouço) para novas aplicações;
●
Conjunto de classes que formam um design abstrato;
●
Genéricos para um domínio de problema;
●
Estendidos para criar APPs específicas;
●
Frozenspots: Partes fixas.
– Serviços já implementados.
●
Hotspots: Partes flexíveis;
– São invocados pelo framework.
Adianti Solutions Ltda © Pablo Dall'Oglio #26
ROR
Ruby on Rails (2004)
●
Baseado em MVC (Model-View-Controller);
●
Fornece estruturas pré-definidas para:
– Persistência (Active Record);
– Montagem de tela (ActionView);
– Controle de ação (Action Controller).
●
DRY (Don't RepeatYourself):
– Coluna = propriedade;
– Sem setters e getters.
●
Convention over configuration
– Class User = table Users
Adianti Solutions Ltda © Pablo Dall'Oglio #27
TCC
O início do interesse:
●
Em 2004:
– Havia estudado Fowler (2002);
●
Em 2005:
– Precisava de uma arquitetura para oTCC;
– Criei um framework MVC para sistemas;
– Foi batizado de Core Framework;
●
Em 2006:
– Em conversas preliminares, a Univates mostra interesse;
– Adota-o como plataforma para desenvolvimento.
Adianti Solutions Ltda © Pablo Dall'Oglio #28
Alfa (2008-)
Adianti Solutions Ltda © Pablo Dall'Oglio #29
Boom
O boom dos Frameworks:
●
PHP: Zend, CodeIgniter, Cake,
Synfony, Laravel,Yii, Prado;
●
Java: Spring, Hibernate, Castor,
Swing, SWT, Struts, JSF,Vraptor;
●
Pyton: Django,TurboGears;
●
Ruby: ROR, Rack, Cuba, Padrino;
●
Javascript: Angular, Backbone,
Ember, React, GWT, Knockout;
●
C#: .NET, Nhibernate, Castel.
Adianti Solutions Ltda © Pablo Dall'Oglio #30
Adianti
Quando surgiu o Adianti Framework:
●
Versão atual iniciou ~2008;
●
Lançado oficialmente em 2012;
●
Focado em Business apps.
Adianti Solutions Ltda © Pablo Dall'Oglio #3112ª Conferencia Latino-americana de Software Livre
Estrutura
Persistência: Active Record, Repository
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #33
Active Record (AF)
Armazenar um novo objeto (INSERT).
class Pessoa extends TRecord
{
const TABLENAME = 'tab_pessoas';
const PRIMARYKEY= 'id';
const IDPOLICY = 'max'; // {max, serial}
}
TTransaction::open('samples');
$object = new Pessoa;
$object->name = 'Maria da Silva';
$object->address = 'Rua da Conceicao';
$object->phone = '(51) 8111-2222';
$object->status = 'S';
$object->email = 'maria@email.com';
$object->store(); // armazena o objeto
TTransaction::close(); // fecha a transação.
Business Rules
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #34
Active Record (AF)
Alterar um objeto já existente (UPDATE).
TTransaction::open('samples'); // abre uma transação
$customer = Customer::find(31); // carrega o cliente 31
if ($customer) // se existe
{
$customer->phone = '51 8111-3333'; // muda o fone
$customer->store(); // armazena o objeto
}
new TMessage('info', 'Objeto atualizado');
TTransaction::close(); // fecha a transação.
INSERT OR UPDATE
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #35
Atalhos (AF)
Manipular um conjunto de objetos conforme um filtro.
$product = Product::find(2);
$products = Product::all();
$products = Product::where('name', 'like', '%Computer%')->load();
$count = User::where('age', '>', 18)->count();
$products = Product::where('name', 'like', '%tablet%')->orderBy('price');
User::where('age', '>', 100)->delete();
Product::where('name', 'LIKE', '%computer%')->take(3)->skip(3);
$contacts = Customer::find(123)->hasMany('Contact');
SQL gerado
com segurança
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #36
Active Record (ROR)
Armazenar um novo objeto (INSERT).
class User < ActiveRecord::Base
self.primary_key = "id_user"
end
user = User.new
user.name = "David"
user.occupation = "Code Artist"
user.save
// ou
user = User.create(name: "David", occupation: "Code Artist")
NOT NECESSARY
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #37
Atalhos (ROR)
Manipulando Objetos
client = Client.find(10)
users = User.all
david = User.find_by(name: 'David')
users = User.where(name: 'David', occupation: 'Code Artist')
.order(created_at: :desc)
clients = Client.where("orders_count = ?", params[:orders])
clients = Client.limit(5).offset(30)
Articles = Article.where('id > 10').limit(20).order('id asc')
Hooks e Callbacks
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #39
Callbacks (ROR)
Injetando comportamento no ciclo do objeto:
class Account < ActiveRecord::Base
before_save :setupdate, :setloggedin
private
def setupdate
self.Account_Update = Time.now
end
def setloggedin
self.Account_LoggedIn = Time.now
end
end
Callbacks:
before_save
after_save
before_update
after_update
before_destroy
after_destroy
Callbacks:
before_save
after_save
before_update
after_update
before_destroy
after_destroy
Agrega no ciclo de vida
Evita sobrescrita
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #40
Hook Methods (AF)
Injetando comportamento no ciclo do objeto:
app/model/SystemProgram.php
class SystemProgram extends TRecord
{
const TABLENAME = 'system_program';
const PRIMARYKEY= 'id';
const IDPOLICY = 'max'; // {max, serial}
public function onAfterStore( $object )
{
// ...
}
public function onAfterDelete( $object )
{
// ...
}
}
Hook Methods:
onBeforeLoad()
onAfterLoad()
onBeforeStore()
onAfterStore()
onBeforeDelete()
onAfterDelete()
Hook Methods:
onBeforeLoad()
onAfterLoad()
onBeforeStore()
onAfterStore()
onBeforeDelete()
onAfterDelete()
Agrega no ciclo de vida
Evita sobrescrita
Page Controllers
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #42
Controller (ROR)
Executando ações:
/clients/new
app/controllers/clientes_controller.rb
class ClientsController < ApplicationController
def new
end
def edit
end
def delete
end
end
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #43
Controller (AF)
Executando ações:
index.php?class=ClienteController&method=onEdit
app/control/ClienteController.php
class ClienteController extends TPage
{
function onEdit() {
// ...
}
function onDelete() {
// ...
}
}
Templates
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #45
Action View (ROR)
Apresentando templates:
app/controllers/restaurantes_controller.rb
class RestaurantesController < ApplicationController
def index
@restaurantes = Restaurante.all
end
def show
@restaurante = Restaurante.find(params[:id])
end
end
Template:
index.html.erb
Como $this->restaurantes,
Torna-a disponível para a view
Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #46
Action View (ROR)
Apresentando templates:
app/views/restaurantes/index.html.erb
<table>
<% @restaurantes.each do |restaurante| %>
<tr>
<td><%= restaurante.nome %></td>
<td><%= restaurante.endereco %></td>
<td><%= restaurante.especialidade %></td>
</tr>
<% end %>
</table>
Adianti Solutions Ltda © Pablo Dall'Oglio #47
Html Renderer (AF)
app/control/TemplateController.php
class TemplateController extends TPage
{
public function exibe()
{
$html = new THtmlRenderer('app/resources/customer.html');
TTransaction::open('samples');
$customer = Customer::find(1);
$replace = ['code' => $customer->id,
'name' => $customer->name,
'address' => $customer->address];
$html->enableSection('main', $replace);
$html->show();
TTransaction::close();
}
}
Adianti Solutions Ltda © Pablo Dall'Oglio #48
Html Renderer (AF)
<!--[main]-->
<table class="tform" style="border:1px solid #B7B7B7">
<tr> <td colspan="2">Customer data</div></td> </tr>
<tr>
<td width="50%"> ID </td>
<td width="50%"> {$id} </td>
</tr>
<tr>
<td width="50%"> Name </td>
<td width="50%"> {$name} </td>
</tr>
<tr>
<td width="50%"> Address </td>
<td width="50%"> {$address} </td>
</tr>
</table>
<!--[/main]-->
Replaces
Adianti Solutions Ltda © Pablo Dall'Oglio #49
Html Renderer (AF)
Componentes
Adianti Solutions Ltda © Pablo Dall'Oglio #51
Componentes
Representa um elemento visual, como uma cápsula;
Pode ser reaproveitado em diferentes interfaces.
$this->datagrid = new TDataGrid;
$code = new TDataGridColumn('code', ...);
$name = new TDataGridColumn('name', ...);
$this->datagrid->addColumn($code);
$this->datagrid->addColumn($name);
$act1 = new TDataGridAction(...);
$act1->setLabel('View name');
$act1->setImage('bs:search blue');
$act_group = new TDataGridActionGroup('Actions');
$act_group->addHeader('Available Options');
$act_group->addAction($act1);
$this->datagrid->addActionGroup($act_group);
Adianti Solutions Ltda © Pablo Dall'Oglio #52
Componentes
Formulário simples
class SimpleFormController extends TPage
{
private $form;
function __construct()
{
parent::__construct();
$this->form = new TQuickForm;
$this->form->setFormTitle('Quick form');
$id = new TEntry('id');
$text = new TText('text');
$this->form->addQuickField('Id', $id, 40);
$this->form->addQuickField('Text', $text, 120);
$this->form->addQuickAction('Save',
new TAction(array($this, 'onSave')), 'ico_save.png');
parent::add($this->form);
}
Adianti Solutions Ltda © Pablo Dall'Oglio #53
Componentes
Formulário simples
Adianti Solutions Ltda © Pablo Dall'Oglio #54
Comparativo
Componentes e templates:
●
Templates permitem maior liberdade de criação;
●
Templates oferecem maiores dificuldades de manutenção;
●
É fácil criar templates;
●
Use em: telas peculiares;
●
Componentes são mais limitados no aspecto visual;
●
É melhor de manter um sistema baseado em componentes;
●
É mais complexo criar um componente;
●
Use em: telas padronizadas.
Domain-Driven Design
Adianti Solutions Ltda © Pablo Dall'Oglio #56
Orientação a modelos
Aplicação orientada à SQL (BAD)
●
Inserir autor em livro
INSERT INTO autor_livro (autor_id, livro_id)
VALUES ('$autor_id', '$livro_id');
●
Retornar os itens da Nota Fiscal
SELECT * FROM nf, itens
WHERE nf.id = itens.nf_id AND nf.id = '$nf_id'
●
Percorrer dados relacionados
SELECT * FROM turma, matricula, aluno
WHERE turma.id=matricula.turma_id
AND matricula.id_aluno = aluno.id
AND turma.id = '$turma_id'
Cérebro orientado
à relações simples
chaves entre tabelas
Ver 10 piores SQL
Adianti Solutions Ltda © Pablo Dall'Oglio #57
Orientação a modelos
Aplicação orientada ao domínio (GOOD)
Utilização de
relações
mais complexas.
Modelo relacional
é consequência
XMI → {PHP, SQL}
Adianti Solutions Ltda © Pablo Dall'Oglio #58
Studio Pro
<?php
/**
* Customer Active Record
* @author <your-name-here>
*/
class Customer extends TRecord
{
public function get_city()
public function addSkill(Skill $skill)
public function getSkills()
public function load($id)
public function store()
public function delete($id = NULL)
}
?>
XML
SQL
PHP
Modelo
Astah
StarUML
Adianti Solutions Ltda © Pablo Dall'Oglio #59
Orientação a modelos
Exemplo de utilização
// carrega o filme
$filme = new Filme(5);
print $filme->distribuidor->nome;
print $filme->genero->nome;
// carrega o filme
$filme = new Filme(5);
foreach ($filme->getAtores() as $ator)
{
print $ator->nome;
}
// adiciona o ator
$ator = new Ator(10);
$filme->addAtor( $ator );
$filme->store();
LEGIBILIDADE
MAIORLazy Load
Agregação
Adianti Solutions Ltda © Pablo Dall'Oglio #60
Orientação a modelos
Aplicação orientada ao domínio (GOOD)
●
Inserir autor em livro
$livro = new Livro( 10 );
$livro->addAutor( new Autor(8) );
$livro->store();
●
Retornar os itens da Nota Fiscal
$nf = new NotaFiscal(10);
foreach ($nf->getItems() as $item) {
print $item->produto->descricao;
}
●
Percorrer dados relacionados
$turma = new Turma(10);
foreach ($turma->getMatriculas() as $matricula) {
print $matricula->aluno->nome;
}
NAVEGABILIDADE
entre relações
Cache
Adianti Solutions Ltda © Pablo Dall'Oglio #6212ª Conferencia Latino-americana de Software Livre
Utilizado em:
Carregar objeto, Salvar objeto, Excluir objeto.
class Disciplina extends TRecord
{
const TABLENAME = 'disciplinas';
const PRIMARYKEY = 'id';
const IDPOLICY = 'max';
const CACHECONTROL = 'Cache-Control-Class';
}
$turma = new Turma(10);
print $turma->disciplina->nome;
print $turma->disciplina->curso->nome;
foreach ($turma->getMatriculas() as $matricula)
{
print $matricula->aluno->nome;
print $matricula->aluno->cidade->nome;
print $matricula->aluno->cidade->estado->nome;
}
Grandes ganhos de
Performance
1/3 tempo na matrícula
Deve indicar
classe específica
Cache de objetos
Adianti Solutions Ltda © Pablo Dall'Oglio #6312ª Conferencia Latino-americana de Software Livre
Cache de objetos
Store: Ele é gravado tanto no banco de dados (a), quanto no cache (d).
Load: Tenta ler da RAM (c). Senão, carrega (b), e grava na RAM (d).
Adianti Solutions Ltda © Pablo Dall'Oglio #64
Tutor
Adianti Solutions Ltda © Pablo Dall'Oglio #65
Template
Adianti Solutions Ltda © Pablo Dall'Oglio #66
Studio Form Designer
Adianti Solutions Ltda © Pablo Dall'Oglio #67
Studio Form Designer
class TestView extends TPage
{
private $form;
function __construct()
{
parent::__construct();
$this->form = new TForm;
try {
$ui = new TUIBuilder(500,300);
$ui->setController($this);
$ui->setForm($this->form);
$ui->parseFile('app/forms/sample.form.xml');
$this->form->add($ui);
$this->form->setFields($ui->getFields());
}
catch (Exception $e) {
new TMessage('error', $e->getMessage());
}
parent::add($this->form);
Wrapper
Adianti Solutions Ltda © Pablo Dall'Oglio #68
Studio PDF Designer
Adianti Solutions Ltda © Pablo Dall'Oglio #69
Studio PDF Designer
class PDFDesignNFEView extends TPage
{
function onGenerate()
{
try
{
$designer = new TPDFDesigner;
$designer->fromXml('app/reports/nfe.pdf.xml');
$designer->generate();
$designer->SetFont('Arial', 'B', 8);
$designer->setFontColorRGB( '#4C4491' );
$designer->writeAtAnchor('bairro', 'Centro');
$designer->writeAtAnchor('municipio', 'Cidade teste');
$designer->writeAtAnchor('fone', '(11) 1234-5678');
$designer->gotoAnchorXY('details');
$designer->SetFont('Arial', '', 8);
$designer->Cell( 62, 10, '12121212', 1, 0, 'C');
$designer->Cell(140, 10, utf8_decode('Guaraná'), 1, 0, 'L');
}
//...
Wrapper
Adianti Solutions Ltda © Pablo Dall'Oglio #70
Obrigado
●
Adianti Framework:
– www.adianti.com.br/framework
●
Contato:
– www.dalloglio.net
– www.adianti.com.br
– @pablodalloglio
– @adiantisolution
●
Não esquecer de falar do Sorteio!

More Related Content

What's hot

A Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPFA Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPFoholiab
 
Introduction to CircleCI
Introduction to CircleCIIntroduction to CircleCI
Introduction to CircleCIHungWei Chiu
 
Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...
Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...
Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...Vietnam Open Infrastructure User Group
 
Linux Networking Explained
Linux Networking ExplainedLinux Networking Explained
Linux Networking ExplainedThomas Graf
 
Faster packet processing in Linux: XDP
Faster packet processing in Linux: XDPFaster packet processing in Linux: XDP
Faster packet processing in Linux: XDPDaniel T. Lee
 
Owasp mobile top 10
Owasp mobile top 10Owasp mobile top 10
Owasp mobile top 10Pawel Rzepa
 
Recon and Bug Bounties - What a great love story!
Recon and Bug Bounties - What a great love story!Recon and Bug Bounties - What a great love story!
Recon and Bug Bounties - What a great love story!Abhijeth D
 
明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化Taiji Tsuchiya
 
Configuration management with puppet
Configuration management with puppetConfiguration management with puppet
Configuration management with puppetJakub Stransky
 
gRPC と nginx による HTTP/2 サービスメッシュ構築
gRPC と nginx による HTTP/2 サービスメッシュ構築gRPC と nginx による HTTP/2 サービスメッシュ構築
gRPC と nginx による HTTP/2 サービスメッシュ構築Kazuki Ogiwara
 
Building IAM for OpenStack
Building IAM for OpenStackBuilding IAM for OpenStack
Building IAM for OpenStackSteve Martinelli
 
Passwords#14 - mimikatz
Passwords#14 - mimikatzPasswords#14 - mimikatz
Passwords#14 - mimikatzBenjamin Delpy
 
No Easy Breach DerbyCon 2016
No Easy Breach DerbyCon 2016No Easy Breach DerbyCon 2016
No Easy Breach DerbyCon 2016Matthew Dunwoody
 
Improving the performance of Odoo deployments
Improving the performance of Odoo deploymentsImproving the performance of Odoo deployments
Improving the performance of Odoo deploymentsOdoo
 
Vert.x for Microservices Architecture
Vert.x for Microservices ArchitectureVert.x for Microservices Architecture
Vert.x for Microservices ArchitectureIdan Fridman
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409稔 小林
 
Ethernetの受信処理
Ethernetの受信処理Ethernetの受信処理
Ethernetの受信処理Takuya ASADA
 

What's hot (20)

A Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPFA Kernel of Truth: Intrusion Detection and Attestation with eBPF
A Kernel of Truth: Intrusion Detection and Attestation with eBPF
 
docker.pptx
docker.pptxdocker.pptx
docker.pptx
 
eBPF Basics
eBPF BasicseBPF Basics
eBPF Basics
 
IPsec VPNとSSL-VPNの違い
IPsec VPNとSSL-VPNの違いIPsec VPNとSSL-VPNの違い
IPsec VPNとSSL-VPNの違い
 
Introduction to CircleCI
Introduction to CircleCIIntroduction to CircleCI
Introduction to CircleCI
 
Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...
Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...
Room 3 - 4 - Lê Quang Hiếu - How to be a cool dad: Leverage DIY Home Automati...
 
Linux Networking Explained
Linux Networking ExplainedLinux Networking Explained
Linux Networking Explained
 
Faster packet processing in Linux: XDP
Faster packet processing in Linux: XDPFaster packet processing in Linux: XDP
Faster packet processing in Linux: XDP
 
Owasp mobile top 10
Owasp mobile top 10Owasp mobile top 10
Owasp mobile top 10
 
Recon and Bug Bounties - What a great love story!
Recon and Bug Bounties - What a great love story!Recon and Bug Bounties - What a great love story!
Recon and Bug Bounties - What a great love story!
 
明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化
 
Configuration management with puppet
Configuration management with puppetConfiguration management with puppet
Configuration management with puppet
 
gRPC と nginx による HTTP/2 サービスメッシュ構築
gRPC と nginx による HTTP/2 サービスメッシュ構築gRPC と nginx による HTTP/2 サービスメッシュ構築
gRPC と nginx による HTTP/2 サービスメッシュ構築
 
Building IAM for OpenStack
Building IAM for OpenStackBuilding IAM for OpenStack
Building IAM for OpenStack
 
Passwords#14 - mimikatz
Passwords#14 - mimikatzPasswords#14 - mimikatz
Passwords#14 - mimikatz
 
No Easy Breach DerbyCon 2016
No Easy Breach DerbyCon 2016No Easy Breach DerbyCon 2016
No Easy Breach DerbyCon 2016
 
Improving the performance of Odoo deployments
Improving the performance of Odoo deploymentsImproving the performance of Odoo deployments
Improving the performance of Odoo deployments
 
Vert.x for Microservices Architecture
Vert.x for Microservices ArchitectureVert.x for Microservices Architecture
Vert.x for Microservices Architecture
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409
 
Ethernetの受信処理
Ethernetの受信処理Ethernetの受信処理
Ethernetの受信処理
 

Viewers also liked

Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Adianti Framework PHPConf 2013
Adianti Framework PHPConf 2013Adianti Framework PHPConf 2013
Adianti Framework PHPConf 2013Pablo Dall'Oglio
 
As novidades do PHP5 (2005)
As novidades do PHP5 (2005)As novidades do PHP5 (2005)
As novidades do PHP5 (2005)Pablo Dall'Oglio
 
Design for change: Fatores que influenciam na longevidade de um Software PHP
Design for change: Fatores que influenciam na longevidade de um Software PHPDesign for change: Fatores que influenciam na longevidade de um Software PHP
Design for change: Fatores que influenciam na longevidade de um Software PHPPablo Dall'Oglio
 
Criando relatórios com PHP - PHP Conference Brasil 2013
Criando relatórios com PHP - PHP Conference Brasil 2013Criando relatórios com PHP - PHP Conference Brasil 2013
Criando relatórios com PHP - PHP Conference Brasil 2013Pablo Dall'Oglio
 
PHP: Programando com orientação a Objetos
PHP: Programando com orientação a ObjetosPHP: Programando com orientação a Objetos
PHP: Programando com orientação a ObjetosPablo Dall'Oglio
 
Experiencias de um desenvolvedor de software livre (2005)
Experiencias de um desenvolvedor de software livre (2005)Experiencias de um desenvolvedor de software livre (2005)
Experiencias de um desenvolvedor de software livre (2005)Pablo Dall'Oglio
 
Criando aplicações com PHP-GTK
Criando aplicações com PHP-GTKCriando aplicações com PHP-GTK
Criando aplicações com PHP-GTKPablo Dall'Oglio
 
Implementando enterprise patterns com PHP
Implementando enterprise patterns com PHPImplementando enterprise patterns com PHP
Implementando enterprise patterns com PHPPablo Dall'Oglio
 
PHP Profissional - Ferramentas e Padrões
PHP Profissional - Ferramentas e PadrõesPHP Profissional - Ferramentas e Padrões
PHP Profissional - Ferramentas e PadrõesFlávio Lisboa
 
Fatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um SoftwareFatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um SoftwarePablo Dall'Oglio
 
Aula 03 - UML e Padrões de Projeto
Aula 03 - UML e Padrões de ProjetoAula 03 - UML e Padrões de Projeto
Aula 03 - UML e Padrões de ProjetoVinícius de Paula
 
Aula 02 - UML e Padrões de Projeto
Aula 02 - UML e Padrões de ProjetoAula 02 - UML e Padrões de Projeto
Aula 02 - UML e Padrões de ProjetoVinícius de Paula
 
Aula 01 - UML e Padrões de Projeto
Aula 01 - UML e Padrões de ProjetoAula 01 - UML e Padrões de Projeto
Aula 01 - UML e Padrões de ProjetoVinícius de Paula
 
Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...
Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...
Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...Pablo Dall'Oglio
 

Viewers also liked (17)

Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Design Patterns com PHP
Design Patterns com PHPDesign Patterns com PHP
Design Patterns com PHP
 
Adianti Framework PHPConf 2013
Adianti Framework PHPConf 2013Adianti Framework PHPConf 2013
Adianti Framework PHPConf 2013
 
As novidades do PHP5 (2005)
As novidades do PHP5 (2005)As novidades do PHP5 (2005)
As novidades do PHP5 (2005)
 
Design for change: Fatores que influenciam na longevidade de um Software PHP
Design for change: Fatores que influenciam na longevidade de um Software PHPDesign for change: Fatores que influenciam na longevidade de um Software PHP
Design for change: Fatores que influenciam na longevidade de um Software PHP
 
Criando relatórios com PHP - PHP Conference Brasil 2013
Criando relatórios com PHP - PHP Conference Brasil 2013Criando relatórios com PHP - PHP Conference Brasil 2013
Criando relatórios com PHP - PHP Conference Brasil 2013
 
PHP: Programando com orientação a Objetos
PHP: Programando com orientação a ObjetosPHP: Programando com orientação a Objetos
PHP: Programando com orientação a Objetos
 
Experiencias de um desenvolvedor de software livre (2005)
Experiencias de um desenvolvedor de software livre (2005)Experiencias de um desenvolvedor de software livre (2005)
Experiencias de um desenvolvedor de software livre (2005)
 
Criando aplicações com PHP-GTK
Criando aplicações com PHP-GTKCriando aplicações com PHP-GTK
Criando aplicações com PHP-GTK
 
Implementando enterprise patterns com PHP
Implementando enterprise patterns com PHPImplementando enterprise patterns com PHP
Implementando enterprise patterns com PHP
 
Frameworks PHP
Frameworks PHPFrameworks PHP
Frameworks PHP
 
PHP Profissional - Ferramentas e Padrões
PHP Profissional - Ferramentas e PadrõesPHP Profissional - Ferramentas e Padrões
PHP Profissional - Ferramentas e Padrões
 
Fatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um SoftwareFatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um Software
 
Aula 03 - UML e Padrões de Projeto
Aula 03 - UML e Padrões de ProjetoAula 03 - UML e Padrões de Projeto
Aula 03 - UML e Padrões de Projeto
 
Aula 02 - UML e Padrões de Projeto
Aula 02 - UML e Padrões de ProjetoAula 02 - UML e Padrões de Projeto
Aula 02 - UML e Padrões de Projeto
 
Aula 01 - UML e Padrões de Projeto
Aula 01 - UML e Padrões de ProjetoAula 01 - UML e Padrões de Projeto
Aula 01 - UML e Padrões de Projeto
 
Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...
Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...
Construindo ERP's com PHP: Desafios em design, manutenção segurança e perf...
 

Similar to Do Clipper e Delphi ao Ruby e PHP: Antes e depois dos frameworks

Criando software para o futuro com DDD, Arquitetura, Patterns, e Atitude
Criando software para o futuro com DDD, Arquitetura, Patterns, e AtitudeCriando software para o futuro com DDD, Arquitetura, Patterns, e Atitude
Criando software para o futuro com DDD, Arquitetura, Patterns, e AtitudePablo Dall'Oglio
 
See project - Segurança em Cloud Computing v2 FISL 11 2010
See project - Segurança em Cloud Computing v2 FISL 11 2010See project - Segurança em Cloud Computing v2 FISL 11 2010
See project - Segurança em Cloud Computing v2 FISL 11 2010Marcelo Fleury
 
Docker - minicurso utfpr 2017
Docker -  minicurso utfpr 2017Docker -  minicurso utfpr 2017
Docker - minicurso utfpr 2017Fabio Janiszevski
 
Fortes Papo Developer
Fortes Papo DeveloperFortes Papo Developer
Fortes Papo DeveloperJosé Araújo
 
Da introdução à prática com Drools Expert e Drools Flow
Da introdução à prática com Drools Expert e Drools FlowDa introdução à prática com Drools Expert e Drools Flow
Da introdução à prática com Drools Expert e Drools FlowRicardo Longa
 
Overview de Grails: O Java em alta produtividade
Overview de Grails: O Java em alta produtividadeOverview de Grails: O Java em alta produtividade
Overview de Grails: O Java em alta produtividadeCleórbete Santos
 
Migrando 4 milhões de linhas de Delphi 7 para XE7
Migrando 4 milhões de linhas de Delphi 7 para XE7Migrando 4 milhões de linhas de Delphi 7 para XE7
Migrando 4 milhões de linhas de Delphi 7 para XE7José Araújo
 
IntroduçãO Ao Desenvolvimento Web 2
IntroduçãO Ao Desenvolvimento Web   2IntroduçãO Ao Desenvolvimento Web   2
IntroduçãO Ao Desenvolvimento Web 2Maurício Linhares
 
LPUG #10 agenda e community updates - 2020-09-16
LPUG #10   agenda e community updates - 2020-09-16LPUG #10   agenda e community updates - 2020-09-16
LPUG #10 agenda e community updates - 2020-09-16Fernando Fernández
 
Introdução ao desenvolvimento web - 2 - iDez 2010
Introdução ao desenvolvimento web - 2 - iDez 2010Introdução ao desenvolvimento web - 2 - iDez 2010
Introdução ao desenvolvimento web - 2 - iDez 2010Maurício Linhares
 
See Project - Segurança em Cloud Computing FLISOL GO 2010
See Project - Segurança em Cloud Computing FLISOL GO 2010See Project - Segurança em Cloud Computing FLISOL GO 2010
See Project - Segurança em Cloud Computing FLISOL GO 2010Marcelo Fleury
 
KDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TI
KDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TIKDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TI
KDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TImarioaxavier7
 
Fatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um SoftwareFatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um SoftwarePablo Dall'Oglio
 
Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018
Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018
Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018Renato Groff
 
Programando Software Livre em C
Programando Software Livre em CProgramando Software Livre em C
Programando Software Livre em CDiego Santos
 
Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011
Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011
Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011Caio Moreno
 
Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...
Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...
Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...IT4biz IT Solutions
 
Pentaho inteligência de negócios utilizando software livre campus party 2011
Pentaho  inteligência de negócios utilizando software livre   campus party 2011Pentaho  inteligência de negócios utilizando software livre   campus party 2011
Pentaho inteligência de negócios utilizando software livre campus party 2011Campus Party Brasil
 

Similar to Do Clipper e Delphi ao Ruby e PHP: Antes e depois dos frameworks (20)

Criando software para o futuro com DDD, Arquitetura, Patterns, e Atitude
Criando software para o futuro com DDD, Arquitetura, Patterns, e AtitudeCriando software para o futuro com DDD, Arquitetura, Patterns, e Atitude
Criando software para o futuro com DDD, Arquitetura, Patterns, e Atitude
 
See project - Segurança em Cloud Computing v2 FISL 11 2010
See project - Segurança em Cloud Computing v2 FISL 11 2010See project - Segurança em Cloud Computing v2 FISL 11 2010
See project - Segurança em Cloud Computing v2 FISL 11 2010
 
Docker - minicurso utfpr 2017
Docker -  minicurso utfpr 2017Docker -  minicurso utfpr 2017
Docker - minicurso utfpr 2017
 
Fortes Papo Developer
Fortes Papo DeveloperFortes Papo Developer
Fortes Papo Developer
 
Da introdução à prática com Drools Expert e Drools Flow
Da introdução à prática com Drools Expert e Drools FlowDa introdução à prática com Drools Expert e Drools Flow
Da introdução à prática com Drools Expert e Drools Flow
 
Overview de Grails: O Java em alta produtividade
Overview de Grails: O Java em alta produtividadeOverview de Grails: O Java em alta produtividade
Overview de Grails: O Java em alta produtividade
 
Migrando 4 milhões de linhas de Delphi 7 para XE7
Migrando 4 milhões de linhas de Delphi 7 para XE7Migrando 4 milhões de linhas de Delphi 7 para XE7
Migrando 4 milhões de linhas de Delphi 7 para XE7
 
IntroduçãO Ao Desenvolvimento Web 2
IntroduçãO Ao Desenvolvimento Web   2IntroduçãO Ao Desenvolvimento Web   2
IntroduçãO Ao Desenvolvimento Web 2
 
LPUG #10 agenda e community updates - 2020-09-16
LPUG #10   agenda e community updates - 2020-09-16LPUG #10   agenda e community updates - 2020-09-16
LPUG #10 agenda e community updates - 2020-09-16
 
Introdução ao desenvolvimento web - 2 - iDez 2010
Introdução ao desenvolvimento web - 2 - iDez 2010Introdução ao desenvolvimento web - 2 - iDez 2010
Introdução ao desenvolvimento web - 2 - iDez 2010
 
See Project - Segurança em Cloud Computing FLISOL GO 2010
See Project - Segurança em Cloud Computing FLISOL GO 2010See Project - Segurança em Cloud Computing FLISOL GO 2010
See Project - Segurança em Cloud Computing FLISOL GO 2010
 
KDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TI
KDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TIKDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TI
KDE Neon & KDE Plasma: venha para o KDE e ganhe experiencia profissional em TI
 
Meetup-Churrops
Meetup-ChurropsMeetup-Churrops
Meetup-Churrops
 
Fatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um SoftwareFatores que influenciam na longevidade de um Software
Fatores que influenciam na longevidade de um Software
 
PHP Tools for Fast coding
PHP Tools for Fast codingPHP Tools for Fast coding
PHP Tools for Fast coding
 
Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018
Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018
Docker + Bancos de Dados: isto é possível? - Databases SP - Março-2018
 
Programando Software Livre em C
Programando Software Livre em CProgramando Software Livre em C
Programando Software Livre em C
 
Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011
Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011
Pentaho: Inteligência de Negócios utilizando software livre @Campus Party 2011
 
Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...
Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...
Pentaho: Inteligência de Negócios utilizando Software Livre @ Telefonica Camp...
 
Pentaho inteligência de negócios utilizando software livre campus party 2011
Pentaho  inteligência de negócios utilizando software livre   campus party 2011Pentaho  inteligência de negócios utilizando software livre   campus party 2011
Pentaho inteligência de negócios utilizando software livre campus party 2011
 

Do Clipper e Delphi ao Ruby e PHP: Antes e depois dos frameworks

  • 1. Do Clipper e Delphi ao Ruby e PHP Antes e depois dos frameworks Pablo Dall'Oglio @pablodalloglio fb/pablodalloglio
  • 2. Adianti Solutions Ltda © Pablo Dall'Oglio #2 1994 Inicia no Brasil a execução do Plano Real
  • 3. Adianti Solutions Ltda © Pablo Dall'Oglio #3 1994 Raimundos lança seu primeiro disco
  • 4. Adianti Solutions Ltda © Pablo Dall'Oglio #4 1994 Século em que o Wolf ainda tinha cabelo
  • 5. Adianti Solutions Ltda © Pablo Dall'Oglio #5 CA-Clipper Sobre o Clipper ● Compilador criado em 1985 para linguagem xBase; ● Ideia surgiu no restaurante (Nantucket), quadro (Clipper); ● Dados armazenados em arquivos .DBF; ● Linguagem de execução procedural (v5.2 = 1,6Mb); ● Durou até a versão 5.3b (1997). Não há mais suporte; ● Existem iniciativas da comunidade (Flagship); ● Comandos (USE, SKIP, GOTOP, GO BOTTOM, e GO #); ● PC: 486 50 Mhz. Memória: 4Mb de RAM, HD: 512 Mb; ● Outras tecnologias da época:Turbo Pascal, C, Basic, DataFlex.
  • 6. Adianti Solutions Ltda © Pablo Dall'Oglio #6 CA-Clipper Telas desenhadas artisticamente by hand
  • 7. Adianti Solutions Ltda © Pablo Dall'Oglio #7 Procedural CAD_CLI.PRG @ 2,5,19,70 window "Cadastro de Clientes" cCOD_CLI := cad_cli->COD_CLI cNOME := cad_cli->NOME cENDERECO := cad_cli->ENDERECO @ 0,1 say "Codigo_____________ " + cad_cli->COD_CLI @ 1,1 say "Nome________________" get cNOME pict "@!" @ 2,1 say "Endereço____________" get cENDERECO if CONFIRMA("Confirma Alteração ?",20,44) if cad_cli->(RECLOCK()) cad_cli->COD_CLI := cCOD_CLI cad_cli->NOME := cNOME cad_cli->ENDERECO := cENDERECO cad_cli->(dbunlockall()) endif endif Exibe e coleta Registro trabalhado como um objeto Sem SQL Persistência e concorrência
  • 8. Adianti Solutions Ltda © Pablo Dall'Oglio #8 Procedural NOTA_FISCAL.PRG function PROCESSA_NF() ABRE("RES_NF") if CONFIRMA("Confirma Nota Fiscal") res_nf->(dbappend()) if CONFIRMA("Imprimir Nota Fiscal") PRINT_NF( cSERIE_NF, nNUM_NF, cFILE ) endif if CONFIRMA("Imprimir Duplicata") IMPR_DUPLICATA(nNUM_NF, cCOD_CLI) endif endif Funções do User Space
  • 9. Adianti Solutions Ltda © Pablo Dall'Oglio #9 Procedural CUPOM_FISCAL.PRG function PROCESSA_CF() function REGISTRA_CF( nVLR_TOT_CF,... ) function SHOW_TOTAIS() function CANCELA_ITEM( nITEM, cDESCR ) function BAIXA_ESTOQUE() function ALTA_ESTOQUE() function ABRE_CUPOM() function FECHA_CUPOM( nVLR_TOT_CF, nVLR_PAGO, ... ) function CANCELA_CUPOM( lFICOUABERTO ) function VENDE_ITEM( cCODIGO, cDESCR, nQUANT, nPR_VENDA, cITEM ) function LEITURA_X() function REDUCAO_Z() Cadeia de dependências não muito clara
  • 10. Adianti Solutions Ltda © Pablo Dall'Oglio #10 CA-Clipper Considerações: ● Muito rápido e enxuto (Ex: Controle de vendas 841 Kb); ● Não leva a organização modular, somente separação por funções; ● Não leva a organização de nomes: Fica a cargo de cada um; ● Programas geralmente organizados em torno de telas; ● Não facilita o reuso: Dificuldade identificar partes para reaproveitar; ● Suscetível à mudanças: Dificuldade em localizar dependências; ● Diferentes aspectos no mesmo programa: – Apresentação: @ 0,1 say "Codigo_____________ "; – Controle: if CONFIRMA("Confirma Nota Fiscal"); – Persistência: cad_cli->(dbunlockall()).
  • 11. Adianti Solutions Ltda © Pablo Dall'Oglio #11 1998 Coisas muito estranhas aconteceram
  • 12. Adianti Solutions Ltda © Pablo Dall'Oglio #12 1998 Coisas muito estranhas mesmo
  • 13. Adianti Solutions Ltda © Pablo Dall'Oglio #13 Delphi Sobre o Delphi ● Lançado pela Borland em 1995, como substituto doTurbo Pascal; ● Assim como oTurbo Pascal, foi idealizado por Anders Hejlsberg (DN); ● Anders Hejlsberg em 1996 move para MS, onde idealizou o C#; ● Em 2001, foi lançado o Kylix, versão para Linux; ● Posteriormente, a comunidade criou o Lazarus; ● Características fortes: – Programação visual (drag and drop); – Programação orientada a eventos (OnClick, OnChange); – Utilização de componentes (TButton, TEdit, TSpinButton); ● Outras tecnologias da época:Visual Basic, Power Builder.
  • 14. Adianti Solutions Ltda © Pablo Dall'Oglio #14 Delphi Data Sources, Tabelas usadas pelo formulário Mapeamento entre objeto visual e BD
  • 15. Adianti Solutions Ltda © Pablo Dall'Oglio #15 Delphi unit untCadastro; uses Windows, Messages, SysUtils, Classes, Graphics, Controls, ... type TfrmCadastro = class(TForm) dtbEndereco: TDatabase; tabEndereco: TTable; dtsEndereco: TDataSource; tabEnderecoNome: TStringField; dgrEndereco: TDBGrid; Label1: TLabel; dedCodigo: TDBEdit; var frmCadastro: TfrmCadastro; implementation Formulário: Arquivo separado Data Sources, Tabelas usadas pelo formulário
  • 16. Adianti Solutions Ltda © Pablo Dall'Oglio #16 Delphi procedure TfrmCadastro.FormCreate(Sender: TObject); begin dtbEndereco.Open; tabEndereco.Open; end; procedure TfrmCadastro.sbnEditarClick(Sender: TObject); begin tabEndereco.Edit; end; procedure TfrmCadastro.sbnGravarClick(Sender: TObject); begin tabEndereco.Post; end; Entra em edição Envia dados
  • 17. Adianti Solutions Ltda © Pablo Dall'Oglio #17 Delphi Considerações: ● Fortaleceu o uso da Orientação a Objetos; ● Consolidou o conceito de componente de interface (cápsulas); ● Levou a uma separação entre Interface (.dfm) e Lógica (.pas); ● Formou uma geração de programadores, acostumada à: – Arrastar e soltar objetos na tela (drag and drop); – Programar a lógica orientada à eventos; – Vincular fortemente o modelo de dados à interface. ● Não promoveu a tempo uma separação da lógica e do modelo; ● Essa geração tem dificuldades naWeb, que é orientada à requests.
  • 18. Adianti Solutions Ltda © Pablo Dall'Oglio #18 2000 No Brasil, KLB vendia mais de 1 milhão de discos...
  • 19. Adianti Solutions Ltda © Pablo Dall'Oglio #19 2000 ZH 16/08/2000
  • 20. Adianti Solutions Ltda © Pablo Dall'Oglio #20 2001
  • 21. Adianti Solutions Ltda © Pablo Dall'Oglio #21 Início foi dureza... <?php // configuração $conn = pg_connect("..."); // query $query = 'SELECT id, nome, endereco FROM cliente WHERE id not in (...)'; // resultados $result = pg_query($conn, $query); if ($result) { // apresentação echo '<table border="1">'; while ($row = pg_fetch_assoc($result)) { echo '<tr>'; echo '<td>' . $row['id'] . '</td>'; echo '<td>' . $row['nome'] . '</td>'; echo '<td>' . $row['endereco'] . '</td>'; echo '</tr>'; } echo '</table>'; } pg_close($conn); Business rules Apresentação Configuração
  • 22. Adianti Solutions Ltda © Pablo Dall'Oglio #22 Design Patterns Padrões de Projeto “Um Pattern descreve um problema que ocorre com frequência em nosso ambiente, e então explica a essência da solução para este problema, de forma que tal solução possa ser utilizada milhões de outras vezes...” Christopher Alexander (1936 arquiteto)
  • 23. Adianti Solutions Ltda © Pablo Dall'Oglio #23 MVC MVC ● Model ● View ● Controller
  • 24. Adianti Solutions Ltda © Pablo Dall'Oglio #24 MVC MVC ● Model ● View ● Controller
  • 25. Adianti Solutions Ltda © Pablo Dall'Oglio #25 Frameworks Frameworks ● Implementam vários Design Patterns; ● Fornecem uma arquitetura (arcabouço) para novas aplicações; ● Conjunto de classes que formam um design abstrato; ● Genéricos para um domínio de problema; ● Estendidos para criar APPs específicas; ● Frozenspots: Partes fixas. – Serviços já implementados. ● Hotspots: Partes flexíveis; – São invocados pelo framework.
  • 26. Adianti Solutions Ltda © Pablo Dall'Oglio #26 ROR Ruby on Rails (2004) ● Baseado em MVC (Model-View-Controller); ● Fornece estruturas pré-definidas para: – Persistência (Active Record); – Montagem de tela (ActionView); – Controle de ação (Action Controller). ● DRY (Don't RepeatYourself): – Coluna = propriedade; – Sem setters e getters. ● Convention over configuration – Class User = table Users
  • 27. Adianti Solutions Ltda © Pablo Dall'Oglio #27 TCC O início do interesse: ● Em 2004: – Havia estudado Fowler (2002); ● Em 2005: – Precisava de uma arquitetura para oTCC; – Criei um framework MVC para sistemas; – Foi batizado de Core Framework; ● Em 2006: – Em conversas preliminares, a Univates mostra interesse; – Adota-o como plataforma para desenvolvimento.
  • 28. Adianti Solutions Ltda © Pablo Dall'Oglio #28 Alfa (2008-)
  • 29. Adianti Solutions Ltda © Pablo Dall'Oglio #29 Boom O boom dos Frameworks: ● PHP: Zend, CodeIgniter, Cake, Synfony, Laravel,Yii, Prado; ● Java: Spring, Hibernate, Castor, Swing, SWT, Struts, JSF,Vraptor; ● Pyton: Django,TurboGears; ● Ruby: ROR, Rack, Cuba, Padrino; ● Javascript: Angular, Backbone, Ember, React, GWT, Knockout; ● C#: .NET, Nhibernate, Castel.
  • 30. Adianti Solutions Ltda © Pablo Dall'Oglio #30 Adianti Quando surgiu o Adianti Framework: ● Versão atual iniciou ~2008; ● Lançado oficialmente em 2012; ● Focado em Business apps.
  • 31. Adianti Solutions Ltda © Pablo Dall'Oglio #3112ª Conferencia Latino-americana de Software Livre Estrutura
  • 33. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #33 Active Record (AF) Armazenar um novo objeto (INSERT). class Pessoa extends TRecord { const TABLENAME = 'tab_pessoas'; const PRIMARYKEY= 'id'; const IDPOLICY = 'max'; // {max, serial} } TTransaction::open('samples'); $object = new Pessoa; $object->name = 'Maria da Silva'; $object->address = 'Rua da Conceicao'; $object->phone = '(51) 8111-2222'; $object->status = 'S'; $object->email = 'maria@email.com'; $object->store(); // armazena o objeto TTransaction::close(); // fecha a transação. Business Rules
  • 34. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #34 Active Record (AF) Alterar um objeto já existente (UPDATE). TTransaction::open('samples'); // abre uma transação $customer = Customer::find(31); // carrega o cliente 31 if ($customer) // se existe { $customer->phone = '51 8111-3333'; // muda o fone $customer->store(); // armazena o objeto } new TMessage('info', 'Objeto atualizado'); TTransaction::close(); // fecha a transação. INSERT OR UPDATE
  • 35. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #35 Atalhos (AF) Manipular um conjunto de objetos conforme um filtro. $product = Product::find(2); $products = Product::all(); $products = Product::where('name', 'like', '%Computer%')->load(); $count = User::where('age', '>', 18)->count(); $products = Product::where('name', 'like', '%tablet%')->orderBy('price'); User::where('age', '>', 100)->delete(); Product::where('name', 'LIKE', '%computer%')->take(3)->skip(3); $contacts = Customer::find(123)->hasMany('Contact'); SQL gerado com segurança
  • 36. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #36 Active Record (ROR) Armazenar um novo objeto (INSERT). class User < ActiveRecord::Base self.primary_key = "id_user" end user = User.new user.name = "David" user.occupation = "Code Artist" user.save // ou user = User.create(name: "David", occupation: "Code Artist") NOT NECESSARY
  • 37. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #37 Atalhos (ROR) Manipulando Objetos client = Client.find(10) users = User.all david = User.find_by(name: 'David') users = User.where(name: 'David', occupation: 'Code Artist') .order(created_at: :desc) clients = Client.where("orders_count = ?", params[:orders]) clients = Client.limit(5).offset(30) Articles = Article.where('id > 10').limit(20).order('id asc')
  • 39. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #39 Callbacks (ROR) Injetando comportamento no ciclo do objeto: class Account < ActiveRecord::Base before_save :setupdate, :setloggedin private def setupdate self.Account_Update = Time.now end def setloggedin self.Account_LoggedIn = Time.now end end Callbacks: before_save after_save before_update after_update before_destroy after_destroy Callbacks: before_save after_save before_update after_update before_destroy after_destroy Agrega no ciclo de vida Evita sobrescrita
  • 40. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #40 Hook Methods (AF) Injetando comportamento no ciclo do objeto: app/model/SystemProgram.php class SystemProgram extends TRecord { const TABLENAME = 'system_program'; const PRIMARYKEY= 'id'; const IDPOLICY = 'max'; // {max, serial} public function onAfterStore( $object ) { // ... } public function onAfterDelete( $object ) { // ... } } Hook Methods: onBeforeLoad() onAfterLoad() onBeforeStore() onAfterStore() onBeforeDelete() onAfterDelete() Hook Methods: onBeforeLoad() onAfterLoad() onBeforeStore() onAfterStore() onBeforeDelete() onAfterDelete() Agrega no ciclo de vida Evita sobrescrita
  • 42. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #42 Controller (ROR) Executando ações: /clients/new app/controllers/clientes_controller.rb class ClientsController < ApplicationController def new end def edit end def delete end end
  • 43. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #43 Controller (AF) Executando ações: index.php?class=ClienteController&method=onEdit app/control/ClienteController.php class ClienteController extends TPage { function onEdit() { // ... } function onDelete() { // ... } }
  • 45. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #45 Action View (ROR) Apresentando templates: app/controllers/restaurantes_controller.rb class RestaurantesController < ApplicationController def index @restaurantes = Restaurante.all end def show @restaurante = Restaurante.find(params[:id]) end end Template: index.html.erb Como $this->restaurantes, Torna-a disponível para a view
  • 46. Adianti Solutions Ltda © Pablo Dall'Oglio Programando para Programadores #46 Action View (ROR) Apresentando templates: app/views/restaurantes/index.html.erb <table> <% @restaurantes.each do |restaurante| %> <tr> <td><%= restaurante.nome %></td> <td><%= restaurante.endereco %></td> <td><%= restaurante.especialidade %></td> </tr> <% end %> </table>
  • 47. Adianti Solutions Ltda © Pablo Dall'Oglio #47 Html Renderer (AF) app/control/TemplateController.php class TemplateController extends TPage { public function exibe() { $html = new THtmlRenderer('app/resources/customer.html'); TTransaction::open('samples'); $customer = Customer::find(1); $replace = ['code' => $customer->id, 'name' => $customer->name, 'address' => $customer->address]; $html->enableSection('main', $replace); $html->show(); TTransaction::close(); } }
  • 48. Adianti Solutions Ltda © Pablo Dall'Oglio #48 Html Renderer (AF) <!--[main]--> <table class="tform" style="border:1px solid #B7B7B7"> <tr> <td colspan="2">Customer data</div></td> </tr> <tr> <td width="50%"> ID </td> <td width="50%"> {$id} </td> </tr> <tr> <td width="50%"> Name </td> <td width="50%"> {$name} </td> </tr> <tr> <td width="50%"> Address </td> <td width="50%"> {$address} </td> </tr> </table> <!--[/main]--> Replaces
  • 49. Adianti Solutions Ltda © Pablo Dall'Oglio #49 Html Renderer (AF)
  • 51. Adianti Solutions Ltda © Pablo Dall'Oglio #51 Componentes Representa um elemento visual, como uma cápsula; Pode ser reaproveitado em diferentes interfaces. $this->datagrid = new TDataGrid; $code = new TDataGridColumn('code', ...); $name = new TDataGridColumn('name', ...); $this->datagrid->addColumn($code); $this->datagrid->addColumn($name); $act1 = new TDataGridAction(...); $act1->setLabel('View name'); $act1->setImage('bs:search blue'); $act_group = new TDataGridActionGroup('Actions'); $act_group->addHeader('Available Options'); $act_group->addAction($act1); $this->datagrid->addActionGroup($act_group);
  • 52. Adianti Solutions Ltda © Pablo Dall'Oglio #52 Componentes Formulário simples class SimpleFormController extends TPage { private $form; function __construct() { parent::__construct(); $this->form = new TQuickForm; $this->form->setFormTitle('Quick form'); $id = new TEntry('id'); $text = new TText('text'); $this->form->addQuickField('Id', $id, 40); $this->form->addQuickField('Text', $text, 120); $this->form->addQuickAction('Save', new TAction(array($this, 'onSave')), 'ico_save.png'); parent::add($this->form); }
  • 53. Adianti Solutions Ltda © Pablo Dall'Oglio #53 Componentes Formulário simples
  • 54. Adianti Solutions Ltda © Pablo Dall'Oglio #54 Comparativo Componentes e templates: ● Templates permitem maior liberdade de criação; ● Templates oferecem maiores dificuldades de manutenção; ● É fácil criar templates; ● Use em: telas peculiares; ● Componentes são mais limitados no aspecto visual; ● É melhor de manter um sistema baseado em componentes; ● É mais complexo criar um componente; ● Use em: telas padronizadas.
  • 56. Adianti Solutions Ltda © Pablo Dall'Oglio #56 Orientação a modelos Aplicação orientada à SQL (BAD) ● Inserir autor em livro INSERT INTO autor_livro (autor_id, livro_id) VALUES ('$autor_id', '$livro_id'); ● Retornar os itens da Nota Fiscal SELECT * FROM nf, itens WHERE nf.id = itens.nf_id AND nf.id = '$nf_id' ● Percorrer dados relacionados SELECT * FROM turma, matricula, aluno WHERE turma.id=matricula.turma_id AND matricula.id_aluno = aluno.id AND turma.id = '$turma_id' Cérebro orientado à relações simples chaves entre tabelas Ver 10 piores SQL
  • 57. Adianti Solutions Ltda © Pablo Dall'Oglio #57 Orientação a modelos Aplicação orientada ao domínio (GOOD) Utilização de relações mais complexas. Modelo relacional é consequência XMI → {PHP, SQL}
  • 58. Adianti Solutions Ltda © Pablo Dall'Oglio #58 Studio Pro <?php /** * Customer Active Record * @author <your-name-here> */ class Customer extends TRecord { public function get_city() public function addSkill(Skill $skill) public function getSkills() public function load($id) public function store() public function delete($id = NULL) } ?> XML SQL PHP Modelo Astah StarUML
  • 59. Adianti Solutions Ltda © Pablo Dall'Oglio #59 Orientação a modelos Exemplo de utilização // carrega o filme $filme = new Filme(5); print $filme->distribuidor->nome; print $filme->genero->nome; // carrega o filme $filme = new Filme(5); foreach ($filme->getAtores() as $ator) { print $ator->nome; } // adiciona o ator $ator = new Ator(10); $filme->addAtor( $ator ); $filme->store(); LEGIBILIDADE MAIORLazy Load Agregação
  • 60. Adianti Solutions Ltda © Pablo Dall'Oglio #60 Orientação a modelos Aplicação orientada ao domínio (GOOD) ● Inserir autor em livro $livro = new Livro( 10 ); $livro->addAutor( new Autor(8) ); $livro->store(); ● Retornar os itens da Nota Fiscal $nf = new NotaFiscal(10); foreach ($nf->getItems() as $item) { print $item->produto->descricao; } ● Percorrer dados relacionados $turma = new Turma(10); foreach ($turma->getMatriculas() as $matricula) { print $matricula->aluno->nome; } NAVEGABILIDADE entre relações
  • 61. Cache
  • 62. Adianti Solutions Ltda © Pablo Dall'Oglio #6212ª Conferencia Latino-americana de Software Livre Utilizado em: Carregar objeto, Salvar objeto, Excluir objeto. class Disciplina extends TRecord { const TABLENAME = 'disciplinas'; const PRIMARYKEY = 'id'; const IDPOLICY = 'max'; const CACHECONTROL = 'Cache-Control-Class'; } $turma = new Turma(10); print $turma->disciplina->nome; print $turma->disciplina->curso->nome; foreach ($turma->getMatriculas() as $matricula) { print $matricula->aluno->nome; print $matricula->aluno->cidade->nome; print $matricula->aluno->cidade->estado->nome; } Grandes ganhos de Performance 1/3 tempo na matrícula Deve indicar classe específica Cache de objetos
  • 63. Adianti Solutions Ltda © Pablo Dall'Oglio #6312ª Conferencia Latino-americana de Software Livre Cache de objetos Store: Ele é gravado tanto no banco de dados (a), quanto no cache (d). Load: Tenta ler da RAM (c). Senão, carrega (b), e grava na RAM (d).
  • 64. Adianti Solutions Ltda © Pablo Dall'Oglio #64 Tutor
  • 65. Adianti Solutions Ltda © Pablo Dall'Oglio #65 Template
  • 66. Adianti Solutions Ltda © Pablo Dall'Oglio #66 Studio Form Designer
  • 67. Adianti Solutions Ltda © Pablo Dall'Oglio #67 Studio Form Designer class TestView extends TPage { private $form; function __construct() { parent::__construct(); $this->form = new TForm; try { $ui = new TUIBuilder(500,300); $ui->setController($this); $ui->setForm($this->form); $ui->parseFile('app/forms/sample.form.xml'); $this->form->add($ui); $this->form->setFields($ui->getFields()); } catch (Exception $e) { new TMessage('error', $e->getMessage()); } parent::add($this->form); Wrapper
  • 68. Adianti Solutions Ltda © Pablo Dall'Oglio #68 Studio PDF Designer
  • 69. Adianti Solutions Ltda © Pablo Dall'Oglio #69 Studio PDF Designer class PDFDesignNFEView extends TPage { function onGenerate() { try { $designer = new TPDFDesigner; $designer->fromXml('app/reports/nfe.pdf.xml'); $designer->generate(); $designer->SetFont('Arial', 'B', 8); $designer->setFontColorRGB( '#4C4491' ); $designer->writeAtAnchor('bairro', 'Centro'); $designer->writeAtAnchor('municipio', 'Cidade teste'); $designer->writeAtAnchor('fone', '(11) 1234-5678'); $designer->gotoAnchorXY('details'); $designer->SetFont('Arial', '', 8); $designer->Cell( 62, 10, '12121212', 1, 0, 'C'); $designer->Cell(140, 10, utf8_decode('Guaraná'), 1, 0, 'L'); } //... Wrapper
  • 70. Adianti Solutions Ltda © Pablo Dall'Oglio #70 Obrigado ● Adianti Framework: – www.adianti.com.br/framework ● Contato: – www.dalloglio.net – www.adianti.com.br – @pablodalloglio – @adiantisolution ● Não esquecer de falar do Sorteio!