Por qué Cervantes programaba mejor que tú

Post on 12-Apr-2017

1,355 views 4 download

transcript

Por qué Cervantesprogramaba mejor que tú

Javier Acero @jacegu http://javieracero.com

1999

Code Quality!!

Code Quality!!

Business Value!!

2000

2001

2011

The Land That Scrum ForgotRobert C. Martin

NDC 2011

Por qué Cervantesprogramaba mejor que tú

Cervantesprogramaba

Por qué Cervantesprogramaba mejor que tú

Cervantesprogramaba

@author

escritura

“Comunicar a alguien por escrito algo”

lenguaje

“Conjunto de reglas y signos que permiten la comunicación con un

ordenador”

0110001001100101011100110110000100100000011011010110100100100000011000100111001001101001011011000110110001100001011011100111010001100101001000000110001101110101011011000110111100100000011011010110010101110100110000111010000101101100011010010110001101101111

besa mi brillante culo metálico

0110001001100101011100110110000100100000011011010110100100100000011000100111001001101001011011000110110001100001011011100111010001100101001000000110001101110101011011000110111100100000011011010110010101110100110000111010000101101100011010010110001101101111

evolución de los lenguajes

evolución de los lenguajes

evolución de los lenguajes

potencia

evolución de los lenguajes

potencia legibilidad

segment .text global two_complementtwo_complement: enter 0,0 pusha mov eax, [ebp+12] neg eax mov [ebp+8], eax popa leave ret

private void updateComputer(Node n, Map<String,Computer> byNameMap, Set<Computer> used) {

Computer c;c = byNameMap.get(n.getNodeName());

    if (c!=null) {c.setNode(n);

    } else {if(n.getNumExecutors()>0) {

computers.put(n,c=n.createComputer());if (!n.holdOffLaunchUntilSave && AUTOMATIC_SLAVE_LAUNCH) {

RetentionStrategy retentionStrategy = c.getRetentionStrategy();

if (retentionStrategy != null) {retentionStrategy.start(c);

        } else {c.connect(true);

        }}

}}used.add(c);

}

100% humanos

¿realmente programamos para las

máquinas?

W.T.F.

“aquel que agrada a la persona que lo lee”

wehrwirtschaftsführer

rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz

subjetiva

principios

Single Responsibility Principle

Open Closed Principle

Liskov Substitution Principle

Dependency Inversion Principle

Interface Segregation Principle

Law of Demeter

Duplication

Cohesion

Information hiding

KISS

YAGNI

DRY

GRASPSimple Design

Least Surprise

Design Patterns

Uniform Access

Auto-documentation

Dependencies Simmetry

Expresiveness

Naming

“aquel que cumple todos los principios”

W.T.F.

private void updateComputer(Node n, Map<String,Computer> byNameMap, Set<Computer> used) {

Computer c;c = byNameMap.get(n.getNodeName());

    if (c!=null) {c.setNode(n);

    } else {if(n.getNumExecutors()>0) {

computers.put(n,c=n.createComputer());if (!n.holdOffLaunchUntilSave && AUTOMATIC_SLAVE_LAUNCH) {

RetentionStrategy retentionStrategy = c.getRetentionStrategy();

if (retentionStrategy != null) {retentionStrategy.start(c);

        } else {c.connect(true);

        }}

}}used.add(c);

}

good code

You know you are working on good code when each routine you read turns out to be pretty much what you expected.

You can call it beautiful when the code also makes it look like the language was made for the problem.

Good code is simple and direct. Good code reads like well-written prose.

Good code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control.

legibilidad

*creencia personal

la mejor forma de escribir buen código es centrarse en la

legibilidad*

defectos

defectos

1. Acoplamiento

defectos

1. Acoplamiento

2. Duplicación

defectos

1. Acoplamiento

2. Duplicación

3. Ausencia de encapsulación

defectos

1. Acoplamiento

2. Duplicación

3. Ausencia de encapsulación

4. Complejidad innecesaria

defectos

for (final ConfiguracionCanal c : mensaje.getSolicitud().getServicio().getConfiguracionesCanal()) {if (mensaje.getCanal().equals(c. getCanal())) {configuracion = c;

}}

mensaje.configuracionDeCanal()

MensajeSolicitud

Servicio Canal

ConfiguracionCanal

correspondiente a

de

a través de

subliminal slide

getters & settersareevil

las 4 cualidades del diseño simple

1. Pasa todos los tests

2. Minimiza la duplicación

3. Maximiza la claridad

4. Tiene los mínimos elementos

las 4 cualidades del diseño simple

oh wait...¿y los tests?

def d(b)eval"def #{b} end"end;d't(m,&a)puts"\e[0;3#{a.call ? "2":"1"}m#{m}\e[0m"';d'a(e)e';d'ae(e,d)e==d';d'ai(e,a)a.include? e'

def d(b)eval"def #{b} end"

end

d 't(m,&a)puts"\e[0;3#{a.call ? "2":"1"}m#{m}\e[0m"'

d 'a(e)e'

d 'ae(e,d)e==d'

d 'ai(e,a)a.include? e'

t '(red): testing that assert equals fails' do ae(1,2)

end

t '(green): testing that assert equals works' doae(2,2)

end

twittestthe ruby test framework

that fits in a tweet!!

las 4 cualidades del diseño simple

1. Pasa todos los tests

las 4 cualidades del diseño simple

1. Pasa todos los tests

2. Minimiza la duplicación

las 4 cualidades del diseño simple

1. Pasa todos los tests

2. Minimiza la duplicación

3. Maximiza la claridad

las 4 cualidades del diseño simple

1. Pasa todos los tests

2. Minimiza la duplicación

3. Maximiza la claridad

4. Tiene los mínimos elementos

las 4 cualidades del diseño simple

todo repercute en la legibilidad

def d(b)eval"def #{b} end"

end

d 'a(e)e'

d 'ae(e,d)e==d'

d 'ai(e,a)a.include? e'

d 't(m,&a)puts"\e[0;3#{a.call ? "2":"1"}m#{m}\e[0m"'

def d(b)eval"def #{b} end"

end

d 'a(e)e'

d 'ae(e,d)e==d'

d 'ai(e,a)a.include? e'

d 't(m,&a)puts"\e[0;3#{a.call ? "2":"1"}m#{m}\e[0m"'

def d(b)eval"def #{b} end"

end

d 'a(e)e'

d 'ae(e,d)e==d'

d 'ai(e,a)a.include? e'

d 't(m,&a)puts"\e[0;3#{a.call ? "2":"1"}m#{m}\e[0m"'

d 'a(e)e'

d 'ae(e,d)e==d'

d 'ai(e,a)a.include? e'

def assert(value) return value == trueend

def assert_equal(value, expected) return value == expectedend

def assert_includes(value, container) return container.include? valueend

def d(b)eval"def #{b} end"

end

d 'a(e)e'

d 'ae(e,d)e==d'

d 'ai(e,a)a.include? e'

d 't(m,&a)puts"\e[0;3#{a.call ? "2":"1"}m#{m}\e[0m"'

d 't(m,&a)puts"\e[0;3#{a.call ? "2":"1"}m#{m}\e[0m"'

def test(message, &assert) puts "\e[0;3#{assert.call ? "2":"1"}m#{message}\e[0m"end

¿legible?

legibilidad sí,pero...

¿cuánta?

si el test pasaimprimir en verde el nombre del test

sinoimprimir en rojo el nombre del test

def test(test_name, &test) if test.passes?

print_in GREEN, test_name else print_in RED, test_name end

end

el buen código es...

“aquel que hace obvio lo que está pasando”

Good code always looks like it was written by someone who cares.

Good code is code left by someone who cares deeply about the craft.

muchas gracias

Kent Beck: http://www.flickr.com/photos/26420411@N02/3062930943/

Opposing Armies: http://www.flickr.com/photos/ahounslea/4873239128

Ward Cunningham: http://www.flickr.com/photos/joshb/2247556208/

Uncle Bob: http://www.flickr.com/photos/koss/3250213001/

Balance: http://www.flickr.com/photos/classblog/5136926303/

Futurama pictures and WTFs/minute draws were found on google searches.

Hand drawings of Grady Booch, Ward Cunningham and Michael Feathers were taken from the Clean Code ebook.

credits