Manual de Clean Code
Manual de Clean Code
Manual de Clean Code
BM Software
Contenido
GIT.............................................................................................................................3
ENTORNO DE DESARROLLO.................................................................................3
TEST UNITARIOS.....................................................................................................4
CLEAN CODE............................................................................................................5
Comentarios...........................................................................................................5
Nombres (Clases, variables y métodos)................................................................6
Métodos..................................................................................................................7
Clases....................................................................................................................8
Arquitectura............................................................................................................9
REFACTORIZACIÓN..............................................................................................10
Code Smells generales........................................................................................10
Código Smells específicos...................................................................................11
Tipos de refactorizaciones...................................................................................15
PATRONES DE SOFTWARE..................................................................................19
Creacionales........................................................................................................20
Singleton...........................................................................................................20
Factory..............................................................................................................21
Abstract Factory...............................................................................................22
Builder...............................................................................................................22
Prototype..........................................................................................................23
Estructurales........................................................................................................23
Adapter.............................................................................................................23
Brigde...............................................................................................................25
Composite:........................................................................................................25
Decorator..........................................................................................................26
Facade/Fachada...............................................................................................27
Flyweight...........................................................................................................28
Proxy.................................................................................................................28
Comportamiento...................................................................................................29
Chain of Responsability / Cadena de resposabilidades...................................29
Command / Comando......................................................................................30
Interpreter.........................................................................................................30
Iterator..............................................................................................................31
Mediator............................................................................................................32
Memento...........................................................................................................32
Observer / Observador.....................................................................................33
State.................................................................................................................34
Strategy............................................................................................................35
Template Method..............................................................................................35
Visitor................................................................................................................36
PRINCIPIOS SOLID................................................................................................37
SRP: Single Resposability Principle.................................................................37
OCP: Open/Closed Principle............................................................................37
LPS: Liskov Subtitution Principle......................................................................38
ISP: Interface Segregation Principle................................................................38
DIP: Dependency Inversion Principle...............................................................38
PRINCIPIOS LEAN (PRINCIPIO DE INVERSIÓN DE DEPENDENCIA)..............39
Principios de LEAN...........................................................................................39
GIT
Los IDEs mas usados e importantes ya vienen con cierta configuracion para
manejar git o en algunos casos es necesario installar un plugin para activarlos
ENTORNO DE DESARROLLO
TEST UNITARIOS
CLEAN CODE
Comentarios
Variables:
No escatimar en el nombre
Deben explicarse por si solos y ser claros
Nombre coherentes
Deben ser sustantivos
o int age;
o String firstName
Deben tener un proposito
o Boolean isDead
Metodos:
Deben ser verbos ya que reflejan una accion
o loadFile
o validate
Deben describir su funcion
En caso de ser booleanos
IsFinished (en caso que se manejen en ingle siempre debe ir “is”
en el nombre del metodo booleano)
Clases:
Deben ser sustantivos o frase de nombres
o Order
o XMLParser
Evitar verbos
Evitar nombres genéricos
o Data
o Loader
Generalidades a manejar
Tratar que describan el “problema”:
o No revelan intencion
Int foo = 0;
o Si describen el problema
Int age;
float amount;
Deben estar sujeto al dominio (empresa a a la que va dirigido el codigo)
o Significados especiales
o Patrones: CustomerFactury
o Implementacion de interfaces: ParserImp
o Estructura subyacente: CustomerMap, OrderList
Sean pronunciables
Tratar que no sean tan ambiguos o generen informacion erronea
o ArrayList elementos Que clase de elementos manejan
o String nameOfTheCustomerWhoHasPaid
o String nameOfTheCustomerWhoHasntPaid
Distingir que contiene
Procurar usar conectores unicos
Evitar codificaciones, prefijos
o LblClientName es un label Suele verse en Visual Studio
Aplicar la regla del ambito
o La longitud de una variable debe ser proporcional a su ámbito
o Usualmente manejar una sola letra para ciclos o datos que solo se
vayan a usar una vez
Métodos
El método deberá hacer solo una cosa y hacerla bien, debe tener una extensión
máxima de 5 líneas, además de caber en la pantalla que se esté proyectando, ser
legible u en casos extremos su longitud deberá ser de 24 líneas de código.
En cuestión de parámetros este deberá tener como máximo 3 y que no sean
booleanos ya que son muy propensos a dar error, estos tampoco deberán servir
para validar un switch/case, tampoco manejo de datos nulos, ni usar Out
1. In Solo es de entrada su valor no cambia al terminar la llamada
2. Out solo de salida, su valor puede cambiar al terminar la llamada
3. In/out tanto de entrada como de salida
En caso que un método maneja más de una responsabilidad este se le deberá
aplicar la refactorización extract until you drop, es decir extraer la responsabilidad
de más y separarla en un método nuevo
Evitar la programacion defensiva la cual consta de validar siempre que los
parametros que pasamos estan pasando de manera correcta o deseada ya que
estos valores deben venir validados desde antes
Evitar el tratar de alterar la ejecucion normal de la app, ademas de evitar usar los
comandos break, continue y return en funciones grandes y se hacen aceptables
en metodos pequeños
Ademas que los errores deben manejarse por un try-cath y los switch se pueden
reemplazar por una refactorizacion, realizar una llamada al metodo que es y no
confirmar dicha llamada
Clases
Las clases deben tener responsabilidades pequeñas y por lo general debe ser solo
1, si es necesario cambiar la funcionalidad de la clase debe ser por un motivo
razonable e incluso deben tener cohesión entre clases y aun así no deben
solaparse entre ellas mismas
Las características de buenas clases son tener pocos atributos y estos deben ser
usados por todos métodos.
Se deben controlar de manera correcta los cambios que se realicen en la clase,
manejar riesgos tales como errores, al añadir más responsabilidades o cambiar la
responsabilidad que ya tiene la clase; es necesario que la clase este protegida y
de ser posible manejar interfaces.
Un error común es el uso innecesario de métodos SET y GET y en muchos casos
todos estos métodos no son usados.
Estructura de datos vs objetos:
1. Se disitnguen según
a. La que exponen
b. La que ocultan
2. DTO y registros activos Mapean datos de una BD
a. DTO: datos
b. Registrar activos: datos con metodos para gestionar registros
Una forma de medir la cualidad de una buena encapsulacion es usando LA LEY
DE DEMÉTER, ejemplo:
El método F de una clase C solo puede llamar:
Métodos de de la clase C
Objetos creados por el método F
Objetos pasados como argumentos al método F
Objetos contenidos en atributos de la clase C
Arquitectura
Una buena arquitectura se logra identificar gracias a que sus elementos son
fáciles de localizar, además que en caso alguno de necesitar un cambio en alguna
parte de la arquitectura esta no afectará al desarrollo del programa, haciendo que
el programa sea más fácil de testear.
Cabe recalcar que una buena arquitectura siempre está abierta al cambio hasta el
final del desarrollo del programa o proyecto y la mejor forma de lograrlo es retrasar
ciertas decisiones (Frameworks, BD, Bootsrap, entornos, etc. ya que son solo
herramientas) así maximizando el número de opciones
Los casos de uso son el TODO de la arquitectura y estos no deben mezclar se con
la UI, BD, etc.
Manejar un buen sistema de particionado tales como:
1. Business objects: Entities
a. Entidades independientes de la app, representan elementos del
dominio, pero no mapean exactamente la base de datos
2. Use Case: controls / Interactor
a. Son los metodos mas especificos de la app , los casos de uso
3. UI object: boundaries
a. Frontera entre la arquitectura y el exterior
b. Son mecanismo de entrega
c. Comunican los casos de uso con la UI y la BD
REFACTORIZACIÓN
“Es más complicado escribir código que entienda otra persona que lo entienda
una maquina ya que cualquier idiota puede hacer”
Este tipo de códigos suelen identificarse por el código repetido (copy/paste), hay
abstracciones ni herencia además de no haber unas reglas de negocio claras y ser
un software procedimental.
Otras características a destacar son:
El código es rígido, lo cual genera que sea difícil realizar un cambio este y
en caso de necesitar uno puede obligar hacer modificaciones a módulos
independientes, este no permite estimar con precisión los tiempos
necesarios para introducir cambios
Fragilidad: El sistema presenta cambios inesperados, es decir, a veces
sirve a veces no, el sistema se puede romper al momento de presentar
cambios e incluso si se cambia una parte del sistema y en cierta parte de
este algo se daña
Viscosidad: Hay varias formas de realizar un cambio, pero estos pueden
alterar el diseño planeado para el sistema, resulta más fácil usar HACKS
que realizar cambios que realmente ayuden al sistema e incluso es más
fácil meter “la pata” que acertar al momento de realizar ciertos cambios y
por ende se necesita más tiempo para compilar, hacer test unitarios, etc.
Inmovilidad: El sistema contiene partes que se pueden usar en otros
sistemas, pero estos no se pueden separar, el esfuerzo y riesgo de separar
las partes es demasiado alto para correr el riesgo
Complejidad innecesaria: El código y el diseño de este presenta un
problema a futuro, se usa código muerto (métodos, atributos y variables que
no se usan en ningún momento), el código presente áreas inaccesibles
además de funcionalidades no solicitudes
Opacidad: El diseño resulta algo difícil de entender y el código algo difícil
de entender
Uso de múltiples lenguajes o idiomas
o HTML/JavaScript/CSS
o Java/XML/HTML/JSON
o Ingles/español
El comportamiento del sistema no es obvio o lo esperado de este y no
maneja casos excepcionales o extremos: datos vacíos, negativos, etc.
Haciendo que el sistema no sea capaz de responder a estos datos
Algunos aspectos del código tales como:
o Espaciado inconsistentes
o Indentacion incorrecto
o No seguir convenciones
o Los métodos no siguen un orden
Los datos de configuración no están en un nivel alto y no se encuentran
separados del código
Son problemas de manera que se dan en ciertas partes del código que puede ser
más fácil de solucionar e incluso ya se han hablado de ellos anteriormente
Los comentarios no deben existir a no ser que sea muy necesario
Los métodos largos, recordemos que un método solo debe hacer una cosa
y tener como máximo en lo posible 5 líneas de código y en casos extremos
hasta 24, en caso que el método este manejando más de una
responsabilidad se le deberá aplicar las siguientes refactorizaciones, que se
explicaran más adelante
o Extract Method
o Replace Temp with Query
o Replace Method with Method Object
El manejo de muchos parametros, recordemos que deben ser como
maximo 3, y en caso que haya mas se debera realizar las siguientes
refactorizaciones:
o Introduce Parameter Object
o Replace Parameter with Method Call
Para el código repetitivo o duplicado se debería realizar las siguientes
refactorizaciones:
o Extract Method
o Pull up
o Substitute Algorithm
Código desordenado o clutter, constructores de mas setters, getters,
toString, etc sin necesitarlo o incluso sin usarlos realmente, se recomienda
usar la encapsulación
Los imports son demasiados e incluso son de la misma “rama”, es preferible
usar todo un import a tenerlo repetido varias veces para algo en especifico
.
Condicionales muy complejas, tratar de cambiarlas por polimorfismo o
patrones Strategy , las negaciones son muy dificiles de leer por ende es
mejor tener operaciones, para este tipo de situaciones se recomienda el
uso de Extract Method
Explosión combinatoria, esto ocurre cuando tenemos partes de código que
realizan la misma operación, pero con distintos datos o comportamientos,
para esto se recomienda el uso de interfaces y la refactorización se llama
extract interfaces
Clases muy largas, recordemos que las clases no deben ser excesivamente
largar y en caso de ser así cuentan con muchas responsabilidades, se
recomienda las siguientes refactorizaciones
o Extract class
o Introduce parameter Object
Los nombres que no indican alguna función en específico o nombres que
no tiene que ver con su función, se aplica la refactorización de RENAME y
al código muerto (recordando que el código muerto es código que no se
está usando, pero existen) se aplica la refactorización llamada DELETE
No se debe pensar el en futuras situaciones ya que esto sería una
generalidad de código y estaría mal visto
Uso de atributos temporales u opcionales, clases con muchos campos
opcionales o innecesarios, para esto se recomienda la creación de una
clase en específico que maneje dichos datos
La existencia de clases similares, pero con distintas interfaces, este tipo de
clases similares se pueden llegar a generalizar, renombrando o creando
una superclase y así reduciendo la duplicidad, las refactorizaciones
recomendadas son:
o Rename
o Move Method
o Extract Superclass
Uso de valores primitivos, estos se usan de manera excesiva para la
manipulación de datos y es más conveniente extraer una clase para ellos,
se recomienda el uso de la refactorización Replace Data Value with
Object o Introduce Parameter Object
Clases de datos, por lo general las clases deberían mostrar un
comportamiento, no solo almacenar datos
o Encapsulate Field
o Encapsulate Collection
o Move Method
Agrupaciones de datos, los datos de distintas clases aparecen siempre
juntas, quiza haya que agruparlas en una clase
o Extract Class
o Introduce Parameter Object
Herencia rechazada, se aplica la herencia pero resulta que no se usan los
métodos heredados en la subclase, o si los usamos pero en efecto distinto
o Replace Inheritance with Delegation
Intimidad inapropiada Se trata de que las clases sepan mucho uno de las
otras. No deberian haber interdependencia(trabajen juntas pero la una sin
saber de la otra)
o Move Method
o Move Field
Exposicion indecente, evitar en lo posible que las clases muestren mas de
lo necesario
o Encapsulate
Envidia, los metodos que hacen un uso muy extensivo de otra clase quiza
no estan tan donde deberian
o Move Methods
o Extract Method
Clases vagas, clases que tienen poca importancia y pueden ser integradas
a otras
o Inline class
Cadenas de mensajes, si se ven una secuencia de llamadas y uso de
temporales, es muy probable que exista una dependencia muy fuerte
o Hide Delegate
Intermediario, cuando una clase acaba delegando todas las acciones quiza
no tiene sentido que siga existiendo
o Hide Delegate
Cambio divergente, al realizar cambios en la clase nos damos cuenta que
se hacen en apartados muy dispares, quizas la clase haga demasiadas
cosas
o Extract class
o Extract Superclass/Extract subclass
Cirugia escopeta, cuando se realiza un cambio en una clase requiere
cambiar michas otras clases relacionadas
o Move Field
o Move Method
Herencias paralelas, cada vez que se hace un subclase tiene que hacer
otra subclase en otro punto, deben unirse
o Move Field
o Move Method
Librerias incompletas, cuando necesitamos un método en concreto que no
se encuentra en la libreria
o Introduce Foreign Method
o Introduce Local Method
Solucucion expandida, para conseguir algo en concreto necesitamos un
monton de clases distintas, se debe simplificar el diseño
Tipos de refactorizaciones
Cabe recalcar que a medida que se vaya refactorizando un código puede que este
cambie y haya ciertas incongruencias entre los tipos de refactorización, es algo
normal ya que el código mantiene en un estado cambiante y ningún tipo es una
solución fija para el problema que este en el momento
Convertir parámetros en Sustituir una lista de Reducir el número Codigo mas legible
objetos parámetros por un de parámetros de Reducir el número de
objeto los métodos parametros
Evitar duplicidad de
código en parámetros,
comprobaciones
Replace Temp with Query Las expreciones que Eliminar variables Codigo legible
se guardan en temporales y servir Reutilizacion de
variables temporales como preparacion a expreciones
se extraen como Extract Method Facilitar la extraccion
métodos de metodos
Introduce Explaining Sustituir una Aclarar el Codigo/Condicionales
Variable expresion compleja significado de mas legibles
por una variable expresiones Aclara el proposito de
complicadas las expreciones
Split Temporary Variable Cambiar una variable Procupar asignar a Codigo mas legible
temporal que se cada elemento del Una resposabilidad
reutiliza para código un unico única para cada
distintos fines en un proposito variable
método Evita efectos
inesperados
Facilita el extract
methods
Borrar las asignaciones a Evitar que se Evitar el descontrol Asignar un proposito
parámetros asignen valores a un del valor de ese unico a los parametros
parametro de un párametro Evitar efectos
método inesperados
Reemplazar método con el Extraer un método Facilitar que se Codigo mas legible
objeto del método complejo lleno de pueda simplificar el Aislar un método
variables a una clase método complejo
especifica convertiendo Facilitar el Extract
variables en Method
campos de la clase Simplifica las clases
PATRONES DE SOFTWARE
Los elementos de software que describen un problema y aportan una solución
reutilizable para el mismo
Un patrón de software se compone de 3 componentes:
Nombre
Problema/Escenario
Soluciones
Consecuencias
A su vez existen distintos tipos de patrones:
Creacionales
Estructurales
De comportamiento
Creacionales
Singleton
Nos permite garantizar que solamente exista una instancia de una clase,
ocultando el constructor y solo permitiendo un punto de acceso a su instancia
única
Escenarios generales:
Se requiere que una clase tenga únicamente una instancia
Se precisa un acceso controlado a una instancia única a través de un único
punto llamada
Cuando la instancia única debe ser extendida mediante una subclase y los
clientes deben ser capaces de hacerlo sin modificar el código de la clase
base
Factory
Define un interface para crear un objeto, pero deja en mano de las subclases que
clase concreta instanciar. Este patron por tanto, deja en manos de las subclases la
creacion de instancias
Escenarios generales:
Cuando los sistemas deben ser capaces de utilizar diferentes familias de
objetos
Las familias de objetos deben ser utilizadas juntas y queremos reforzar
esta condicion
Cuando la creacion, conposicion y representacion de instancias debe
ser independiente del sistema que las utiliza
Cuando las clases concretas deben ser desacopladas de los clientes
Para realizar una publicacion de librerias sin exponer los detalles de la
implementacion, unicamente los interfaces
Abstract Factory
Escenarios generales:
Es una evolucion del patron Factory, por tanto se puede aplicar en escenarios
similares
Hay varias jerarquias de subclases
Puede implementarse usando metodos factory o con Prototype
Builder
Escenarios generales
Los algoritmo de creacion de objetos deben ser desacopladas del sistema,
ademas de las partes que los componen y de como se ensamblan
Se precisan de multiples fromas de algoritmos de creación
El proceso de construccion debe permitir diferentes representaciones del
objeto que se crea
Se necesita poder añadir nueva funcionalidad de creacion sin que se cambie el
código principal
Prototype
Escenarios generales
Objetos o estructura de objetos deben ser identicos o deben paracerse a otros
objetos ya existentes
Las clases que deben crearse se especifican en tiempo de ejecucion
Cuando la creacion, composicion y representacion de los objetos debe
desacoplarse del sistema
La creacion inicial de cada objeto es una operación costosa
En los objetos existen un número limitado de combinaciones de estados.Por
tanto compesa definir unos prototipos y clonarlos, ajustanto eses estado
posteriormente
Estructurales
Adapter
Convierte el interface de una clase en otro interface que se ajusta mas a lo que
precisa el cliente. Este patron permite que clases que eran incompatibles puedan
relacionarse
Escenarios generales:
Necesitamos usar una clase existente que no cumpla con los requerimientos
de una interface
Necesitas crear una clase reutilizable que sea capaz de interactuar con clases
no relacionadaso imprevistas, en definitiva, clases incompatibles
Necesita el acceso a multiples subclases pero es mas práctico adaptar el
interface de la clase base que crear subclases de las mismas para poder
usarlas
Brigde
Escenarios generales:
Las abstracciones y las implementaciones no deben estar vinculadas en el
momento de compilar o ejecutar.
Las abstracciones y las implementaciones deberían ser extensibles, y además,
de manera independiente.
Los cambios en la implementación de una abstracción no debe afectar a los
clientes.
Los detalles de implementación deben ocultarse al cliente.
Necesitas compartir una implementación entre muchos objetos y quieres
ocultarlo a los clientes
Composite:
Escenarios generales:
Poder añadir nuevas responsabilidades a los objetos de manera dinámica y de
forma transparente.
No se pueden crear subclases para conseguir modificaciones.
Las implementaciones deben poder desacoplarse de las responsabilidades y
los comportamientos.
Una funcionalidad específica no puede residir en una clase base o en la parte
alta de la jerarquía de clases.
Cuando se tiende a crear una jerarquía de clases demasiado grande para
cubrir todas las posibles variantes de funcionalidad a base de crear
extensiones.
Facade/Fachada
Escenarios generales
Se precisa interface simple para dar acceso a un sistema complejo.
Los sistemas y subsistemas se deben organizar en capas dando acceso de
una a otra través de fachadas.
Existen muchas dependencias entre la implementación del sistema y los
clientes y se precisa desacoplarlos.
Flyweight
Escenarios generales:
Se utilizan muchos objetos similares y su coste es elevado
La mayor parte del estado del objeto puede aislarse
En lugar de utilizar muchos objetos, usamos y reutilizamos unos pocos
modificando su estado.
La identidad de cada objeto no es relevante y la aplicación no depende de ello.
Proxy
Nos permite ofrecer un objeto por delante de otro para controlar el acceso al
mismo.
Escenarios generales:
Se necesita un control de acceso al objeto original y deben proveerse distintos
derechos de acceso.
El objeto representado es externo al sistema.
Se requiere funcionalidad añadida cuando se accede a un objeto: contadores
de acceso, registros de acceso, control de bloqueo, etc.
Se precisa crear objetos costosos bajo demanda
Comportamiento
Escenarios generales:
Muchos objetos pueden responder a una petición, no se sabe cuál de ellos es
a prioridad y no se precisa que esa petición sea responsabilidad de un único
objeto.
Un conjunto de objetos, deberían ser capaces de responder a una petición en
tiempo de ejecución, sin necesidad de especificar uno en concreto.
Se puede asumir que una petición no sea respondida o tratada.
Command / Comando
Encapsula una petición como un objeto, permitiendo parametrizar los clientes con
distintas peticiones, además de encolar o registrar peticiones e incluso dar opción
a revertir peticiones.
Escenarios generales:
Se precisa registrar un histórico de peticiones.
Las peticiones pueden ser transferidas de un proceso a otro.
Las peticiones deben ser soportadas en tiempo u orden variable.
Se necesita desacoplar a quien lanza la petición de quien la soporta.
Se precisa funcionalidad de callback, es decir, poder pasar como parámetro un
método a ejecutar. En POO aplicamos este patrón para poder tener callbacks.
Interpreter
Escenarios generales
Se requiere acceder a un conjunto de elementos sin necesidad de acceder a
toda la estructura.
Se necesita un interface único para recorrer la estructura.
Existen diferencias entre los detalles de implementación de varios iteradores,
es decir, se precisa soporte para la iteración polimórfica.
Mediator
Escenarios generales
La comunicación entre un conjunto de objetos está bien definida y es compleja.
La dependencia entre ellos no tiene estructura concreta o es difícil de entender.
Existen demasiadas relaciones y se precisa un punto único para el control o la
comunicación.
Es difícil reutilizar un objeto porque tiene referencias y comunicación con otros
objetos.
Un comportamiento que se reparte entre muchas clases necesita ser
personalizado sin hacer subclases.
Memento
Permite sacar una instantánea del estado de un objeto para externalizarlo,
guardarlo o recuperarlo más adelante, todo ello sin desencapsular el mismo.
Escenarios generales
Cuando el estado interno de un objeto debe poder ser salvado para ser
recuperado más adelante.
Los límites de la encapsulación deben preservarse.
Se precisa si al exponer el estado a través de interfaces se acaba exponiendo
la implementación
Observer / Observador
Define una dependencia uno a varios entre objetos de tal manera que cuando el
estado de un objeto cambia, todos los elementos dependientes son notificados y
cambian de manera automática.
Escenarios generales
Los cambios de estado en uno o más objetos debe afectar al comportamiento
de otros objetos.
Se precisan capacidad de broadcasting entre objetos.
Se requiere que los objetos no tengan que preocuparse de la propagación de
mensajes o notificaciones.
Cuando un objeto precisa cambiar otros, pero no sabemos quienes o no
podemos asumirlo previamente. Y por supuesto, no queremos acoplamiento.
Cuando una abstracción tiene dos aspectos dependientes. Si encapsulamos
esos aspectos en objetos separados podemos variarlos y reutilizarlos de forma
separada.
State
Escenarios generales
El comportamiento de un objeto debe ser regido por su estado y debe poder
hacerlo en tiempo de ejecución.
Condiciones complejas vinculan ese comportamiento a su estado. Pueden
existir estructuras condicionales cuyas ramas se procurarán separar en
diferentes clases.
La transición entre los estados de un objeto debe ser explícita.
Strategy
Nos permite definir una familia de algoritmos, encapsulando cada uno de ellos y
haciéndolos intercambiables. Este patrón nos permite que un algoritmo puede
variar de forma dinámica en el uso que hacen los clientes.
Escenarios generales
Se requieren muchas versiones o variantes de un algoritmo.
Se aplica cuando la única diferencia entre muchas clases relacionadas es su
comportamiento.
El comportamiento de una clase debe definirse en tiempo de ejecución.
Los algoritmos utilizan datos a los que el código no queda expuesto.
Existen sentencias condicionales complejas y difíciles de mantener.
Template Method
Representa una operación que debe ser efectuada en los elementos de una
estructura de objeto. Nos permite definir un nuevo método u operación sin
necesidad de cambiar las clases de los elementos en los que actúa.
Escenarios generales
Se necesita cuando una estructura de objetos debe tener múltiples
operaciones no relacionadas.
Se precisa ejecutar operaciones sobre clases concretas de una estructura de
objetos
La estructura de objetos no puede cambiar, pero si las operaciones que se
hacen sobre ellos.
Se necesita cuando las operaciones deben ser aplicables en múltiples
estructuras de objetos que implementen los mismos conjuntos de interfaces.
PRINCIPIOS SOLID
Son principios basados en POO que permiten tener un código más limpio,
mantenible y extensible
Cada letra es un principio y cada uno de estos principios cuenta con una
definición:
Single Responsability Principle
Open/Closed Principle
Liskov Subtitution Principle
Interface Segregation Principle
Dependencia Inversión Principle
Principio
Las clases deben ser pequeñas en responsabilidades
Una clase de tener una única responsabilidad dentro de todo el proyecto
Si se cambia algo, solo debería haber una razón
Puede haber mas de un rol usando la clase
Problemas:
Si se cambia algo afectará a otros
Tiene más acoplamientos, dependencias y es sensible a cambios
OCP: Open/Closed Principle
Principio
Un módulo de software debe estar abierto a extensiones y cerrado a
modificaciones.
o Abierto: debería ser fácil cambiar el comportamiento del módulo
o Cerrado: ese comportamiento se debería poder cambiar sin
modificar el módulo
Basta con escribir un buen módulo
Las modificaciones se basan añadir nuevo código, no en modificar el
módulo.
Problemas
Es difícil en sistemas grandes
Principio
Si S es un subtipo de T, los objetos de tipo T en un programa pueden ser
intercambiados por objetos de tipo S sin alterar ninguna de sus
propiedades.
Ejemplos el cuadrado y un rectangulo / Carro electrico o gasolina
ISP: Interface Segregation Principle
Principios
Los clientes no deberían implementar interfaces que no utilicen
Es preferible crear muchos pequeños interfaces que sean implementados
por clientes específicos.
Problemas
Demasiados accesos no deseados
DIP: Dependency Inversion Principle
Principios
Los módulos de alto nivel, deben depender de abstracciones, no de los
módulos de bajo nivel.
Las abstracciones, no deben depender de los detalles de bajo nivel. Los
módulos de bajo nivel, también deben depender de abstracciones.
Elementos de un sistema
Módulos de alto nivel, lógica de negocio
Módulos de bajo nivel, detalles
PRINCIPIOS LEAN (PRINCIPIO DE INVERSIÓN DE
DEPENDENCIA)