@danielvlopes @jeffrydegrande - static.eventials.com · rest ddd spike pair prog. continuous deploy...

Post on 09-Dec-2018

223 views 0 download

transcript

...

@danielvlopes @jeffrydegrande

SOFTWARE DEVLOPMENTDA FORMA CERTA !!!

Move code into controller☑

Rails BEST PRACTICES gem

Move code into model☑Rep. ivars with local vars☑Not use time_ago_in_words☑Dry bundler in capistrano☑Hash Syntax☑

SH*T HAPPENS

FORA DE CONTROLE

COMPORTAMENTO DA EQUIPE

COMPORTAMENTO INDIVIDUAL

COMPORTAMENTO INDIVIDUAL

TDD BDD TAFT DRY

NOSQL

RUBY

FUNCTIONAL

OOP

MVC

REST DDD

SPIKE

PAIR PROG.

CONTINUOUS DEPLOY

CONTINUOUS DEPLOY

RAILS CONT. INTEGRATION

FAST TESTS PRESENTERS

DISTRIBUTED

TDD BDD TAFT DRY

NOSQL

RUBY

FUNCTIONAL

OOP

MVC

REST DDD

SPIKE

PAIR PROG.

CONTINUOUS DEPLOY

CONTINUOUS DEPLOY

RAILS CONT. INTEGRATION

FAST TESTS PRESENTERS

DISTRIBUTEDDRY & AUTOMAÇÃO

<h2>Cadastrar nova pessoa</h2>

<%= form_for @person, :remote => true do |f| %>

<fieldset> <%= f.label :number, "Qual o número de registro?" %> <br/> <%= f.text_field :number, :autofocus => true, :size => 25 %> </fieldset>

<fieldset> <%= f.label :created_at, "Data de cadastro:" %> <br/> <%= f.text_field :created_at, :disabled => true, :size => 10 %> </fieldset>

<fieldset> <%= f.label :start_date, "Início:" %> <%= f.text_field :start_date, :size => 10 %> e <%= f.label :start_date, "Fim:" %> <%= f.text_field :created_at, :size => 10 %> </fieldset>

<fieldset> <%= f.label "Informe nº do processo desta pessoa" %> <br/> <%= f.text_field :process_number, :size => 20, :maxlength => 20 %> </fieldset><% end %>

%h2 Cadastrar nova pessoa

= form_for @person, :remote => true do |f|

%fieldset = f.label :number, "Qual o número de registro?" %br = f.text_field :number, :autofocus => true, :size => 25

%fieldset = f.label :created_at, "Data de cadastro:" %br = f.text_field :created_at, :disabled => true, :size => 10

%fieldset = f.label :start_date, "Início:" = f.text_field :start_date, :size => 10 e = f.label :start_date, "Fim:" = f.text_field :created_at, :size => 10

%fieldset = f.label "Informe nº do processo desta pessoa" %br = f.text_field :process_number, :size => 20, :maxlength => 20

%h2 - if resource.persisted? = t 'title.edit', :resource_name => resource_class.model_name.human - else = t 'title.new.male', :resource_name => resource_class.model_name.human

= form_for @person, :remote => true do |f|

%fieldset = f.label :number, "Qual o número de registro?" %br = f.text_field :number, :autofocus => true, :size => 25, , :disabled => !resource.updatable?

%fieldset = f.label :created_at, "Data de cadastro:" %br = f.text_field :created_at, :disabled => !resource.updatable?, :size => 10

%fieldset = f.label :start_date, "Início:" = f.text_field :start_date, :size => 10

e

= f.label :start_date, "Fim:" = f.text_field :created_at, :size => 10

%fieldset = f.label "Informe nº do processo desta pessoa" %br = f.text_field :process_number, :size => 20, :maxlength => 20, :disabled => !resource.updatable?

%h2 - if resource.persisted? = t 'title.edit', :resource_name => resource_class.model_name.human - else = t 'title.new.male', :resource_name => resource_class.model_name.human

= form_for @person, :remote => true do |f|

%fieldset = f.label :number, "Qual o número de registro?" %br = f.text_field :number, :autofocus => true, :size => 25

%fieldset = f.label :created_at, "Data de cadastro:" %br = f.text_field :created_at, :disabled => true, :size => 10

%fieldset = f.label :start_date, "Início:" = f.text_field :start_date, :size => 10

e

= f.label :start_date, "Fim:" = f.text_field :created_at, :size => 10

%fieldset = f.label "Informe nº do processo desta pessoa" %br = f.text_field :process_number, :size => 20, :maxlength => 20

%h2 - if resource.persisted? = t 'title.edit', :resource_name => resource_class.model_name.human - else = t 'title.new.male', :resource_name => resource_class.model_name.human

= semantic_form_for resource, :remote => true do |f| = f.inputs do = f.input :number, :input_html => { :autofocus => true, :size => 25, :maxlength => 20, :disabled => !resource.updatable? } = f.input :created_at, :as => :string, :input_html => { :disabled => true, :size => 10, ... = f.input :start_date, :as => :string, :input_html => { :size => 10, :disabled => !resource.updatable? } = f.input :end_date, :as => :string, :input_html => { :size => 10, :disabled => !resource.updatable? } = f.input :number_process, :input_html => { :size => 20, :maxlength => 20, :disabled => !resource.updatable? }

VIEW? DRY !

MANUTENÇÃO

CRIAÇÃO1º

=== LANÇAMENTO ===

ADAPTAÇÃO

DESCOBERTA

EVOLUÇÃO

TDD BDD TAFT DRY

NOSQL

RUBY

FUNCTIONAL

OOP

MVC

REST DDD

SPIKE

PAIR PROG.

CONTINUOUS DEPLOY

CONTINUOUS DEPLOY

RAILS CONT. INTEGRATION

FAST TESTS PRESENTERS

DISTRIBUTEDTDD & BDD

describe "#release" do context "an occupied bed" do

before do bed.status = :occupied end

context 'when normal' do before do bed.extra = false end

it "should make it available" do bed.release bed.should be_available end end

context 'when extra' do before do bed.extra = true end

it "should disable it" do bed.release bed.should_not be_enabled end end

endend

CONVENÇÕES

describe "#release" do context "an occupied bed" do

before do bed.status = :occupied end

context 'when normal' do before do bed.extra = false end

it "should make it available" do bed.release bed.should be_available end end

context 'when extra' do before do bed.extra = true end

it "should disable it" do bed.release bed.should_not be_enabled end end

endend

CONVENÇÕES

describe "status of bed" do

it "becomes available when releasing a normal bed" do bed.status = :occupied bed.extra = false bed.release bed.should be_available end

it "is disabled when releasing an extra bed" do bed.status = :occupied bed.extra = true bed.release bed.should_not be_enabled end

end

describe "status of bed" do

#### OCUPAÇÃO (availabe, occupied)

it "becomes available when releasing a normal bed" do bed.status = :occupied bed.extra = false bed.release bed.should be_available end

#### STATUS (enabled / disabled)

it "is disabled when release an extra bed" do bed.status = :occupied bed.extra = true bed.release bed.should_not be_enabled end

end

it { should validate_presence_of :street} it { should validate_presence_of :number}

it 'should validate presence of number complement if have complement and is not a house' do subject.should_not validate_presence_of :number_complement

subject.complement = Complement::HOUSE subject.should_not validate_presence_of :number_complement

subject.complement = Complement::APARTMENT subject.should validate_presence_of :number_complement end

it 'to_s should be the street name, number and neighborhood name' do subject.street = Street.new(:name => "amazonas", :street_type => StreetType::AVENIDA) subject.street.neighborhood = Neighborhood.new(:name => "centro") subject.number = '100'

subject.to_s.should == 'AVENIDA AMAZONAS, 100 - CENTRO' end

it 'number should be greather than or equal 0' do subject.number = -100 subject.should have(1).errors_on(:number)

subject.number = 100 subject.should have(:no).errors_on(:number) end

it { should validate_presence_of :street} it { should validate_presence_of :number}

it 'should validate presence of number complement if have complement and is not a house' do subject.should_not validate_presence_of :number_complement

subject.complement = Complement::HOUSE subject.should_not validate_presence_of :number_complement

subject.complement = Complement::APARTMENT subject.should validate_presence_of :number_complement end

it 'to_s should be the street name, number and neighborhood name' do subject.street = Street.new(:name => "amazonas", :street_type => StreetType::AVENIDA) subject.street.neighborhood = Neighborhood.new(:name => "centro") subject.number = '100'

subject.to_s.should == 'AVENIDA AMAZONAS, 100 - CENTRO' end

it 'number should be greather than or equal 0' do subject.number = -100 subject.should have(1).errors_on(:number)

subject.number = 100 subject.should have(:no).errors_on(:number) end

T.A.T.F.T.

AUTOMATED TESTS / BDD / TDD

AUTOMATED TESTS / BDD / TDD

Aprox. 25 min p/ rodar

testes dependentesfalsa confiançafalhas intermitentes

testando áreas desnecessárias

AUTOMATED TESTS / BDD / TDD

Aprox. 25 min p/ rodar

testes dependentesfalsa confiançafalhas intermitentes

testando áreas desnecessárias

O QUE EU DEVO TESTAR?

Kent Beck

“... my philosophy is to test as little as possible to reach a given level of confidence ...

If I don’t typically make a kind of mistake, I don’t test for it ...”

OUTRO CENÁRIO

Outro cenário

• 3 anos em desenvolvimento• App Rails 2.3 • Várias apps C++• Zero testes• Quantidade gigante de duplicação• Problemas graves de arquitetura • Performance caminhando para a morte

AUTOMATED TESTS

ACCEPTANCE TESTS

BABY STEPS

AUTOMATED TESTS

ACCEPTANCE TESTS

BABY STEPS

TESTE MANUAL

BIG STEPS + REWRITES PARCIAIS

AUTO. TEST APÓS RAILS 3

def new @thing = Thing.new(params_for_testing) respond_with @thingend

def params_for_testing if Rails.env.development? { name: "blaah" } else {} endend

TESTE MANUAL

EXCELENTES RESULTADOS

TDD BDD TAFT DRY

NOSQL

RUBY

FUNCTIONAL

OOP

MVC

REST DDD

SPIKE

PAIR PROG.

CONTINUOUS DEPLOY

CONTINUOUS DEPLOY

RAILS CONT. INTEGRATION

FAST TESTS PRESENTERS

DISTRIBUTEDPATTERNS & PRINCÍPIOS

LAW OF DEMETER

VISITORFACADE

OBSERVERPRESENTER

SINGLE RESPONSIBILITY

COMPOSITION

MVC

MOVE

MEDIATOR

PROXY

CHRISTOPHER ALEXANDER

Padrões e práticas atemporais derivadas de 2.000 anos de

arquitetura.

“ The most disastrous thing about programming: extracting patterns from today's programming practices ennobles them in a way they don't deserve ”

Alan Kay

http://bit.ly/Mg6u3K

COMPORTAMENTO DA EQUIPE

AgileTM

AgileTM

Time e cliente na mesma páginamantendo flexibilidade

Equipe

Cod. conduta

SUCESSO=

SPRINTS DE 2 SEMANAS .

5 PONTOS P/ PESSOA .

CONTINUOUS DELIVERY .

BURNDOWN CHART .

☑☑☑☑

Boas práticas

BACKLOG DETALHADO .☑

FAIL

Por que funciona para alguns mas não funciona para mim ?

DREYFUS MODEL

http://pragprog.com/book/ahptl/pragmatic-thinking-and-learning

visão do contexto

1 - NOVICES

* pouca experiência* sem interesse em aprender* preocupados objetivo imediato.* Não conseguem inferir os passos * Mas conseguem seguir uma lista

Exemplo, um cozinheiro aprendiz, imposto de renda...

1 - NOVICES

2 - ADVANCED BEGINERS

* alguma experiência, * infere alguns principios

Mas

* não quer o big picture * Problemas geram desespero.

ex. CEO meeting w/ projections.

1 - NOVICES

2 - ADVANCED BEGINERS

3 - COMPETENT

* infere padrões baseado em modelos anterirores* consegue enfretar problemas q nunca aconteceram.* consegue procurar e ouvir conselhos* noções de ações associadas a objetivos* mas ainda com dificuldade de identificar onde focar* e precisa de planejamento extensivo

Normalmente descrito como o cara que tem inciativa na equipe.

1 - NOVICES

2 - ADVANCED BEGINERS

3 - COMPETENT

4 - PROFICIENT* Precisa do big-picture* Pois tem uma visão holistica * Alta capacidade de focar por importância* Consegue aprender com situações dos outros* Mas adaptando ao contexto * Com grande capacidade de auto-correção

1 - NOVICES

2 - ADVANCED BEGINERS

3 - COMPETENT

4 - PROFICIENT

5 - EXPERTNão possui necessidade de regras, guidelines ou máximasEntende a situação como um todo intuitivamenteBaseando sua intuição vasta experiênciaTem visão do que é possívelConsegue transpor dificuldades em novos problemasAge quase como mágica

Ex. Médico

AGORA, SABEMOS AS RAZÕES

vamos refletir...

PRÁTICAS sem contexto

apropriado resultam em

DÓGMAS

DOGMAS são oriundos de equipes com pouca experiência.

DÓGMAS levam a falha técnica.

e com EGO inflado tudo

é feito CERTO DE PRIMEIRA

EM EQUIPES SEM EXPERIÊNCIA,

ITERAÇÃO

EVOLUÇÃOé diferente de

mas

RUÍDO c/ coisas

triviais esconde que

SOFTWARE É DIFÍCIL

e o

EVOLUÇÃOmas

tem custos !

TIME MULTI-DISCIPLINAR

EVOLUÇÃO+

IMPOSSÍVEL FALHA TÉCNICA

Já falhas como empreendimento já é outra história.

@danielvlopes @jeffrydegrande

MUITO OBRIGADO