SlideShare una empresa de Scribd logo
1 de 29
Descargar para leer sin conexión
10
CLASES
Organización de una
clase
• Public static constants

• Private static constants

• Private instance variables

• Public functions

• Private utilities called by a public function right after
Clases pequeñas
• La primera regla es que las clases deben ser
pequeñas.

• La segunda regla es que deben ser más pequeñas
que eso.
Nombres de las clases
• Describe la responsabilidad que cumple.

• Si no podemos deducir un nombre concreto, es
demasiado grande.

• Cuanto más ambiguo es el nombre, más probable
es que tenga varias responsabilidades (ej.
Processor o Manafer
SRP: Single
Responsibility Principle
• Un método/función/clase/módulo/microservicio
solo cambia por un, y solo un, motivo (no significa
“tiene una sola responsabilidad”).

• Agrupa lo que cambia por el mismo motivo.

• Uno de los conceptos más importantes en el
diseño OO.
SRP: Single
Responsibility Principle
• Objetivo principal en el manejo de la complejidad:

• Organizarla para que sepamos dónde buscar
para encontrar las cosas.

• Necesidad de comprender solo la complejidad
directamente afectada en un momento dado.

• Muchas clases pequeñas, no pocas muy grandes.
Cohesión
"Pon junto lo que cambia junto”, "pon junto lo que
cambia con la misma frecuencia".
Cohesión
• Grado de utilización de las variables de instancia
por parte de los métodos. 

• Cohesión alta == métodos y variables de la clase
son dependientes y actúan como una unidad
lógica.

• Mantener la cohesión conlleva tener muchas clases
pequeñas.

• Separamos las clases cuando pierden cohesión.
Aislar los cambios
• El cambio es algo constante.

• Cada cambio supone el riesgo de que el resto del
sistema deje de funcionar.

• Organizamos las clases para reducir el riesgo de
cambiar cosas.

• Modificar una clase introduce un riesgo.
OCP: Open/Closed
principle
• Las clases deben estar abiertas a extensión y
cerradas a modificación.

• No cambies la implementación, permite que se
extienda.
OCP: Open/Closed
principle
The Shape Abstraction
Consider the following example. We have an application that must be able to draw circles
and squares on a standard GUI. The circles and squares must be drawn in a particular
order. A list of the circles and squares will be created in the appropriate order and the pro-
gram must walk the list in that order and draw each circle or square.
In C, using procedural techniques that do not conform to the open-closed principle,
we might solve this problem as shown in Listing 1. Here we see a set of data structures
that have the same first element, but are different beyond that. The first element of each is
a type code that identifies the data structure as either a circle or a square. The function
DrawAllShapes walks an array of pointers to these data structures, examining the type
code and then calling the appropriate function (either DrawCircle or DrawSquare).
Listing 1
Procedural Solution to the Square/Circle Problem
enum ShapeType {circle, square};
struct Shape
{
ShapeType itsType;
};
struct Circle
{
ShapeType itsType;
double itsRadius;
Point itsCenter;
};
The Shape Abstraction
The function DrawAllShapes does not conform to the open-closed principl
because it cannot be closed against new kinds of shapes. If I wanted to extend this functio
struct Square
{
ShapeType itsType;
double itsSide;
Point itsTopLeft;
};
//
// These functions are implemented elsewhere
//
void DrawSquare(struct Square*)
void DrawCircle(struct Circle*);
typedef struct Shape *ShapePointer;
void DrawAllShapes(ShapePointer list[], int n)
{
int i;
for (i=0; i<n; i++)
{
struct Shape* s = list[i];
switch (s->itsType)
{
case square:
DrawSquare((struct Square*)s);
break;
case circle:
DrawCircle((struct Circle*)s);
break;
}
}
}
Listing 1 (Continued)
Procedural Solution to the Square/Circle Problem
OCP: Open/Closed
principle
Thus the problem of finding and understanding all the places where the new shape needs
to be added can be non-trivial.
Listing 2 shows the code for a solution to the square/circle problem that conforms to
the open-closed principle. In this case an abstract Shape class is created. This abstract
class has a single pure-virtual function called Draw. Both Circle and Square are
derivatives of the Shape class.
Note that if we want to extend the behavior of the DrawAllShapes function in
Listing 2 to draw a new kind of shape, all we need do is add a new derivative of the
Listing 2
OOD solution to Square/Circle problem.
class Shape
{
public:
virtual void Draw() const = 0;
};
class Square : public Shape
{
public:
virtual void Draw() const;
};
class Circle : public Shape
{
public:
virtual void Draw() const;
};
void DrawAllShapes(Set<Shape*>& list)
{
for (Iterator<Shape*>i(list); i; i++)
(*i)->Draw();
}
Acoplamiento
“Si cambio en un sitio también tengo que cambiar en
el otro”.
Aislarse del cambio
• Necesidades cambian -> código cambia

• Si una clase depende de detalles concretos, está
en riesgo si esos detalles cambian.

• Si tengo bajo acoplamiento, los elementos de
nuestro sistema están mejor aislados unos de otros
y por tanto, del cambio.
DIP: Dependency
Inversion Principle
• Las clases deben depender de abstracciones, no
de detalles.

• ¿Quién manda? Si un cambio en el mandado, hace
que cambies el que manda, invierte la
dependencia.
Resumen
• Todo tiene que ver con razonar sobre el cambio.

• El SRP es "el método/función/clase/modulo/microservicio solo cambia por un
motivo" (el SRP no significa "tiene una sola responsabilidad" eso no significa nada).

• La cohesión es "pon junto lo que cambia junto", "pon junto lo que cambia con la
misma frecuencia".

• El acoplamiento ocurre cuando "si cambio en un sitio tambien tengo que cambiar en
el otro".

• Organizar el código correctamente a nivel de cambio impacta en la velocidad que
desarrollo si lo pienso a nivel de módulo (conjunto de clases y funciones). Esto es,
intento agrupar clases que:

- tienen mucha interacción entre si (cohesión).

- hay pocos motivos externos que los hacen cambiar (acoplamiento).

- cambian por un solo motivo.
Resumen
• Quiero valor temprano porque me da feedback y retorna la
inversión antes:

• y el feedback reduce el riesgo de desviarme y aumenta las
posibilidades de entregar software valioso $$$

• esto implica desarrollo iterativo e incremental

• lo cuál significa básicamente que creo algo y lo CAMBIO
constantemente

• así que mi principal preocupación es razonar sobre cómo
cambian las cosas.
Resumen
• CUIDADO: el objetivo no es predecir el cambio. Eso implica preparar el código
para cosas que igual no pasan. Pierdo el tiempo y genero complejidad.

• el objetivo es que cuando sepa el cambio que quiero hacer, pueda reorganizar la
menor cantidad de código posible y hacer el cambio. 

• es como tener organizado un cajón en el que no sabes qué vas a tener que
coger de él, pero sabes que cuando tengas que coger algo "está todo a mano”.

• Si no hay duplicidad, cuando cambio algo no lo tengo que cambiar en varios
sitios

• Si hay pocas dependencias, cuando cambio algo no se rompen las cosas en
mil sitios....

• Para que este "todo a mano" y sea fácil de entender hace falta: naming,
buenas abstracciones, y una gestión explícita y aislada de los side-effects.
Resumen
• Principios que me ayudan a razonar sobre cómo organizar el código en función del cambio:

• SRP - agrupa lo que cambia por el mismo motivo

• OCP - no cambies la implementación, permite que se extienda

• LSP - permite cambiar las clases hijas por las padres y que siga teniendo sentido

• ISP - si tengo que cambiar la interfaz de una cosa, que no tenga métodos mezclados de otras cosas

• DIP: ¿quién manda? Si un cambio en el mandado, hace que cambies el que manda, invierte la dependencia.

• Law of demeter, local retention, encapsulation, tell don´t ask: <--- oculta los detalles, así si cambias los
detalles solo lo tienes que cambiar en un sitio.

• El diseño de código va sobre hacer desarrollar más barato (menos costoso, menos dinero). 

• En desarrollo iterativo/incremental, el coste de programar es el coste de cambiar.

• Razona sobre el coste.

• Indirectamente aumentarás la velocidad a la que aportas valor. (mejorando el flow = valor/coste)
11
SISTEMAS
Separar el proceso de construcción
del sistema de su uso
• Separar el proceso de inicio, cuando los objetos de
la aplicación se construyen y las dependencias
están "conectadas", de la lógica de ejecución de
después del arranque.

• Necesitamos un sitio centralizado donde abordar la
construcción y resolver las dependencias. Una
estrategia posible es generar todo desde main para
después pasárselo a la aplicación.
Separar el proceso de construcción
del sistema de su uso
• Patrón Factoría Abstracta

• Separar en una clase la responsabilidad de crear un
objeto concreto para esconder los detalles de la creación.

• Inyección de dependencias

• Aplicación de Inversión de Control (IoC) al manejo de
dependencias.

• Un objeto no es responsable de instanciar sus
dependencias, lo delega a un sistema autorizado
(normalmente main o un contenedor autorizado).
Escalando
• Desarrollo iterativo e incremental, no bien hecho a
la primera.

• Implementar las historias de hoy, refactorizar y
expandir el sistema para implementar las historias
de mañana.

• Un sistema software no es un sistema físico. Su
arquitectura puede crecer incrementalmente, SI
mantenemos la correcta separación de conceptos.
Test Driven Architecture
• Una arquitectura óptima consiste en dominios
modularizados de conceptos.

• Los diferentes dominios están conjuntamente
integrados con la mínima interferencia de
herramientas. Esta arquitectura puede ser guiada
por los tests, igual que el código.
Pospón decisiones
hasta el último momento
responsable
Usa los estándares
sabiamente, cuando añadan
un valor demostrable
Lenguaje específico
de tu dominio
Diseño simple
“Usa la cosa más simple que pueda funcionar”
SIGUIENTE
12- Emergence

13 - Concurrency

Más contenido relacionado

La actualidad más candente

Patrones de diseño II
Patrones de diseño IIPatrones de diseño II
Patrones de diseño IIjjegonzalezf
 
Patrones diseno software
Patrones diseno softwarePatrones diseno software
Patrones diseno softwarejjegonzalezf
 
ProgramacióN Orientada A Objetos
ProgramacióN Orientada A ObjetosProgramacióN Orientada A Objetos
ProgramacióN Orientada A ObjetosPatricio Abad
 
Sesion2 Php Oo Y Mysql
Sesion2 Php Oo Y MysqlSesion2 Php Oo Y Mysql
Sesion2 Php Oo Y MysqlHugo Flores
 
Patrones de diseño de software
Patrones de diseño de softwarePatrones de diseño de software
Patrones de diseño de softwareIker Canarias
 
Sesion 15 patrones de diseño
Sesion 15 patrones de diseñoSesion 15 patrones de diseño
Sesion 15 patrones de diseñoJulio Pari
 
Patrones de diseño - Henry Vallejo
Patrones de diseño - Henry VallejoPatrones de diseño - Henry Vallejo
Patrones de diseño - Henry Vallejo2008PA2Info3
 
Implementación y adaptación de patrones de diseño
Implementación y adaptación de patrones de diseñoImplementación y adaptación de patrones de diseño
Implementación y adaptación de patrones de diseñoJu Pe
 
Guia1 programacion de-procesos_concurrentes-hilos
Guia1 programacion de-procesos_concurrentes-hilosGuia1 programacion de-procesos_concurrentes-hilos
Guia1 programacion de-procesos_concurrentes-hilosharoldhicc
 
Patrones de diseño y frameworks
Patrones de diseño y frameworksPatrones de diseño y frameworks
Patrones de diseño y frameworksDaniel Cam Urquizo
 
Patrones de diseño
Patrones de diseñoPatrones de diseño
Patrones de diseñoKelly Cuervo
 

La actualidad más candente (20)

Patrones de diseño II
Patrones de diseño IIPatrones de diseño II
Patrones de diseño II
 
Patrones diseno software
Patrones diseno softwarePatrones diseno software
Patrones diseno software
 
ProgramacióN Orientada A Objetos
ProgramacióN Orientada A ObjetosProgramacióN Orientada A Objetos
ProgramacióN Orientada A Objetos
 
Sesion2 Php Oo Y Mysql
Sesion2 Php Oo Y MysqlSesion2 Php Oo Y Mysql
Sesion2 Php Oo Y Mysql
 
Patrones de diseño de software
Patrones de diseño de softwarePatrones de diseño de software
Patrones de diseño de software
 
Sesion 15 patrones de diseño
Sesion 15 patrones de diseñoSesion 15 patrones de diseño
Sesion 15 patrones de diseño
 
JAVA ORIENTADO A OBJETOS - INTRODUCCIÓN
JAVA ORIENTADO A OBJETOS - INTRODUCCIÓNJAVA ORIENTADO A OBJETOS - INTRODUCCIÓN
JAVA ORIENTADO A OBJETOS - INTRODUCCIÓN
 
Tema5
Tema5Tema5
Tema5
 
Patrones de diseño - Henry Vallejo
Patrones de diseño - Henry VallejoPatrones de diseño - Henry Vallejo
Patrones de diseño - Henry Vallejo
 
Implementación y adaptación de patrones de diseño
Implementación y adaptación de patrones de diseñoImplementación y adaptación de patrones de diseño
Implementación y adaptación de patrones de diseño
 
Presentación poo
Presentación pooPresentación poo
Presentación poo
 
POO
POOPOO
POO
 
Conceptos poo
Conceptos pooConceptos poo
Conceptos poo
 
Guia1 programacion de-procesos_concurrentes-hilos
Guia1 programacion de-procesos_concurrentes-hilosGuia1 programacion de-procesos_concurrentes-hilos
Guia1 programacion de-procesos_concurrentes-hilos
 
Patrones de diseño y frameworks
Patrones de diseño y frameworksPatrones de diseño y frameworks
Patrones de diseño y frameworks
 
Patrones de diseño
Patrones de diseñoPatrones de diseño
Patrones de diseño
 
06 patrones
06 patrones06 patrones
06 patrones
 
Introduccion
IntroduccionIntroduccion
Introduccion
 
4 manejo de_metodos
4 manejo de_metodos4 manejo de_metodos
4 manejo de_metodos
 
Intro
IntroIntro
Intro
 

Similar a 10 clases para un diseño de software limpio

Similar a 10 clases para un diseño de software limpio (20)

Tc2 301403 21
Tc2 301403 21Tc2 301403 21
Tc2 301403 21
 
G#1.gutierrez.quirumbay.cinthya.johanna.software ii.1
G#1.gutierrez.quirumbay.cinthya.johanna.software ii.1G#1.gutierrez.quirumbay.cinthya.johanna.software ii.1
G#1.gutierrez.quirumbay.cinthya.johanna.software ii.1
 
Presentacion De La Primera Unidad 2
Presentacion De La Primera Unidad 2Presentacion De La Primera Unidad 2
Presentacion De La Primera Unidad 2
 
Paradigmas programacion rufino
Paradigmas programacion rufinoParadigmas programacion rufino
Paradigmas programacion rufino
 
PROGRAMACIÓN ORIENTADA A OBJETOS
PROGRAMACIÓN ORIENTADA A OBJETOSPROGRAMACIÓN ORIENTADA A OBJETOS
PROGRAMACIÓN ORIENTADA A OBJETOS
 
6070_TRECALDE_00288.ppt
6070_TRECALDE_00288.ppt6070_TRECALDE_00288.ppt
6070_TRECALDE_00288.ppt
 
Modelo entidad relación Rojas
Modelo entidad relación RojasModelo entidad relación Rojas
Modelo entidad relación Rojas
 
¿A qué huele tu código? Afinando nuestro olfato
¿A qué huele tu código? Afinando nuestro olfato¿A qué huele tu código? Afinando nuestro olfato
¿A qué huele tu código? Afinando nuestro olfato
 
Programación Orientada a Objetos
Programación Orientada  a ObjetosProgramación Orientada  a Objetos
Programación Orientada a Objetos
 
Compendio u1
Compendio u1Compendio u1
Compendio u1
 
Manual de java_2
Manual de java_2Manual de java_2
Manual de java_2
 
manual 9
manual 9manual 9
manual 9
 
Manual de java 3
Manual de java 3Manual de java 3
Manual de java 3
 
MANUAL DE JAVA 2
MANUAL DE JAVA 2MANUAL DE JAVA 2
MANUAL DE JAVA 2
 
Manual de java 3
Manual de java 3Manual de java 3
Manual de java 3
 
Manual de java 2
Manual de java 2Manual de java 2
Manual de java 2
 
MANUAL DE JAVA 3
MANUAL DE JAVA 3MANUAL DE JAVA 3
MANUAL DE JAVA 3
 
Manual de java 3
Manual de java 3Manual de java 3
Manual de java 3
 
Unidad 1_Programacion Orientada a Objetos
Unidad 1_Programacion Orientada a ObjetosUnidad 1_Programacion Orientada a Objetos
Unidad 1_Programacion Orientada a Objetos
 
Buenasprcticas
BuenasprcticasBuenasprcticas
Buenasprcticas
 

Más de 540deg

Katayuno TCR (test && commit || revert)
Katayuno TCR (test && commit || revert)Katayuno TCR (test && commit || revert)
Katayuno TCR (test && commit || revert)540deg
 
Test doubles
Test doublesTest doubles
Test doubles540deg
 
Clean code 9
Clean code 9Clean code 9
Clean code 9540deg
 
Clean code 7-8
Clean code 7-8Clean code 7-8
Clean code 7-8540deg
 
Clean code 4-6
Clean code 4-6Clean code 4-6
Clean code 4-6540deg
 
Clean code 1-3
Clean code 1-3Clean code 1-3
Clean code 1-3540deg
 
Arquitectura hexagonal
Arquitectura hexagonalArquitectura hexagonal
Arquitectura hexagonal540deg
 

Más de 540deg (7)

Katayuno TCR (test && commit || revert)
Katayuno TCR (test && commit || revert)Katayuno TCR (test && commit || revert)
Katayuno TCR (test && commit || revert)
 
Test doubles
Test doublesTest doubles
Test doubles
 
Clean code 9
Clean code 9Clean code 9
Clean code 9
 
Clean code 7-8
Clean code 7-8Clean code 7-8
Clean code 7-8
 
Clean code 4-6
Clean code 4-6Clean code 4-6
Clean code 4-6
 
Clean code 1-3
Clean code 1-3Clean code 1-3
Clean code 1-3
 
Arquitectura hexagonal
Arquitectura hexagonalArquitectura hexagonal
Arquitectura hexagonal
 

10 clases para un diseño de software limpio

  • 2. Organización de una clase • Public static constants • Private static constants • Private instance variables • Public functions • Private utilities called by a public function right after
  • 3. Clases pequeñas • La primera regla es que las clases deben ser pequeñas. • La segunda regla es que deben ser más pequeñas que eso.
  • 4. Nombres de las clases • Describe la responsabilidad que cumple. • Si no podemos deducir un nombre concreto, es demasiado grande. • Cuanto más ambiguo es el nombre, más probable es que tenga varias responsabilidades (ej. Processor o Manafer
  • 5. SRP: Single Responsibility Principle • Un método/función/clase/módulo/microservicio solo cambia por un, y solo un, motivo (no significa “tiene una sola responsabilidad”). • Agrupa lo que cambia por el mismo motivo. • Uno de los conceptos más importantes en el diseño OO.
  • 6. SRP: Single Responsibility Principle • Objetivo principal en el manejo de la complejidad: • Organizarla para que sepamos dónde buscar para encontrar las cosas. • Necesidad de comprender solo la complejidad directamente afectada en un momento dado. • Muchas clases pequeñas, no pocas muy grandes.
  • 7. Cohesión "Pon junto lo que cambia junto”, "pon junto lo que cambia con la misma frecuencia".
  • 8. Cohesión • Grado de utilización de las variables de instancia por parte de los métodos. • Cohesión alta == métodos y variables de la clase son dependientes y actúan como una unidad lógica. • Mantener la cohesión conlleva tener muchas clases pequeñas. • Separamos las clases cuando pierden cohesión.
  • 9. Aislar los cambios • El cambio es algo constante. • Cada cambio supone el riesgo de que el resto del sistema deje de funcionar. • Organizamos las clases para reducir el riesgo de cambiar cosas. • Modificar una clase introduce un riesgo.
  • 10. OCP: Open/Closed principle • Las clases deben estar abiertas a extensión y cerradas a modificación. • No cambies la implementación, permite que se extienda.
  • 11. OCP: Open/Closed principle The Shape Abstraction Consider the following example. We have an application that must be able to draw circles and squares on a standard GUI. The circles and squares must be drawn in a particular order. A list of the circles and squares will be created in the appropriate order and the pro- gram must walk the list in that order and draw each circle or square. In C, using procedural techniques that do not conform to the open-closed principle, we might solve this problem as shown in Listing 1. Here we see a set of data structures that have the same first element, but are different beyond that. The first element of each is a type code that identifies the data structure as either a circle or a square. The function DrawAllShapes walks an array of pointers to these data structures, examining the type code and then calling the appropriate function (either DrawCircle or DrawSquare). Listing 1 Procedural Solution to the Square/Circle Problem enum ShapeType {circle, square}; struct Shape { ShapeType itsType; }; struct Circle { ShapeType itsType; double itsRadius; Point itsCenter; }; The Shape Abstraction The function DrawAllShapes does not conform to the open-closed principl because it cannot be closed against new kinds of shapes. If I wanted to extend this functio struct Square { ShapeType itsType; double itsSide; Point itsTopLeft; }; // // These functions are implemented elsewhere // void DrawSquare(struct Square*) void DrawCircle(struct Circle*); typedef struct Shape *ShapePointer; void DrawAllShapes(ShapePointer list[], int n) { int i; for (i=0; i<n; i++) { struct Shape* s = list[i]; switch (s->itsType) { case square: DrawSquare((struct Square*)s); break; case circle: DrawCircle((struct Circle*)s); break; } } } Listing 1 (Continued) Procedural Solution to the Square/Circle Problem
  • 12. OCP: Open/Closed principle Thus the problem of finding and understanding all the places where the new shape needs to be added can be non-trivial. Listing 2 shows the code for a solution to the square/circle problem that conforms to the open-closed principle. In this case an abstract Shape class is created. This abstract class has a single pure-virtual function called Draw. Both Circle and Square are derivatives of the Shape class. Note that if we want to extend the behavior of the DrawAllShapes function in Listing 2 to draw a new kind of shape, all we need do is add a new derivative of the Listing 2 OOD solution to Square/Circle problem. class Shape { public: virtual void Draw() const = 0; }; class Square : public Shape { public: virtual void Draw() const; }; class Circle : public Shape { public: virtual void Draw() const; }; void DrawAllShapes(Set<Shape*>& list) { for (Iterator<Shape*>i(list); i; i++) (*i)->Draw(); }
  • 13. Acoplamiento “Si cambio en un sitio también tengo que cambiar en el otro”.
  • 14. Aislarse del cambio • Necesidades cambian -> código cambia • Si una clase depende de detalles concretos, está en riesgo si esos detalles cambian. • Si tengo bajo acoplamiento, los elementos de nuestro sistema están mejor aislados unos de otros y por tanto, del cambio.
  • 15. DIP: Dependency Inversion Principle • Las clases deben depender de abstracciones, no de detalles. • ¿Quién manda? Si un cambio en el mandado, hace que cambies el que manda, invierte la dependencia.
  • 16. Resumen • Todo tiene que ver con razonar sobre el cambio. • El SRP es "el método/función/clase/modulo/microservicio solo cambia por un motivo" (el SRP no significa "tiene una sola responsabilidad" eso no significa nada). • La cohesión es "pon junto lo que cambia junto", "pon junto lo que cambia con la misma frecuencia". • El acoplamiento ocurre cuando "si cambio en un sitio tambien tengo que cambiar en el otro". • Organizar el código correctamente a nivel de cambio impacta en la velocidad que desarrollo si lo pienso a nivel de módulo (conjunto de clases y funciones). Esto es, intento agrupar clases que:
 - tienen mucha interacción entre si (cohesión).
 - hay pocos motivos externos que los hacen cambiar (acoplamiento).
 - cambian por un solo motivo.
  • 17. Resumen • Quiero valor temprano porque me da feedback y retorna la inversión antes: • y el feedback reduce el riesgo de desviarme y aumenta las posibilidades de entregar software valioso $$$ • esto implica desarrollo iterativo e incremental • lo cuál significa básicamente que creo algo y lo CAMBIO constantemente • así que mi principal preocupación es razonar sobre cómo cambian las cosas.
  • 18. Resumen • CUIDADO: el objetivo no es predecir el cambio. Eso implica preparar el código para cosas que igual no pasan. Pierdo el tiempo y genero complejidad. • el objetivo es que cuando sepa el cambio que quiero hacer, pueda reorganizar la menor cantidad de código posible y hacer el cambio.  • es como tener organizado un cajón en el que no sabes qué vas a tener que coger de él, pero sabes que cuando tengas que coger algo "está todo a mano”. • Si no hay duplicidad, cuando cambio algo no lo tengo que cambiar en varios sitios • Si hay pocas dependencias, cuando cambio algo no se rompen las cosas en mil sitios.... • Para que este "todo a mano" y sea fácil de entender hace falta: naming, buenas abstracciones, y una gestión explícita y aislada de los side-effects.
  • 19. Resumen • Principios que me ayudan a razonar sobre cómo organizar el código en función del cambio: • SRP - agrupa lo que cambia por el mismo motivo • OCP - no cambies la implementación, permite que se extienda • LSP - permite cambiar las clases hijas por las padres y que siga teniendo sentido • ISP - si tengo que cambiar la interfaz de una cosa, que no tenga métodos mezclados de otras cosas • DIP: ¿quién manda? Si un cambio en el mandado, hace que cambies el que manda, invierte la dependencia. • Law of demeter, local retention, encapsulation, tell don´t ask: <--- oculta los detalles, así si cambias los detalles solo lo tienes que cambiar en un sitio. • El diseño de código va sobre hacer desarrollar más barato (menos costoso, menos dinero).  • En desarrollo iterativo/incremental, el coste de programar es el coste de cambiar. • Razona sobre el coste. • Indirectamente aumentarás la velocidad a la que aportas valor. (mejorando el flow = valor/coste)
  • 21. Separar el proceso de construcción del sistema de su uso • Separar el proceso de inicio, cuando los objetos de la aplicación se construyen y las dependencias están "conectadas", de la lógica de ejecución de después del arranque. • Necesitamos un sitio centralizado donde abordar la construcción y resolver las dependencias. Una estrategia posible es generar todo desde main para después pasárselo a la aplicación.
  • 22. Separar el proceso de construcción del sistema de su uso • Patrón Factoría Abstracta • Separar en una clase la responsabilidad de crear un objeto concreto para esconder los detalles de la creación. • Inyección de dependencias • Aplicación de Inversión de Control (IoC) al manejo de dependencias. • Un objeto no es responsable de instanciar sus dependencias, lo delega a un sistema autorizado (normalmente main o un contenedor autorizado).
  • 23. Escalando • Desarrollo iterativo e incremental, no bien hecho a la primera. • Implementar las historias de hoy, refactorizar y expandir el sistema para implementar las historias de mañana. • Un sistema software no es un sistema físico. Su arquitectura puede crecer incrementalmente, SI mantenemos la correcta separación de conceptos.
  • 24. Test Driven Architecture • Una arquitectura óptima consiste en dominios modularizados de conceptos. • Los diferentes dominios están conjuntamente integrados con la mínima interferencia de herramientas. Esta arquitectura puede ser guiada por los tests, igual que el código.
  • 25. Pospón decisiones hasta el último momento responsable
  • 26. Usa los estándares sabiamente, cuando añadan un valor demostrable
  • 28. Diseño simple “Usa la cosa más simple que pueda funcionar”