Seguro que siendo desarrolladores de software todos hemos oído los términos de acoplamiento y cohesión. Para quien no le suene, el término “acoplamiento” hace alusión al grado de dependencia que tienen dos unidades de software y la “cohesión” tiene que ver con la forma en la que agrupamos unidades de software en una unidad mayor.

31901945494_bd24c12961_z
coupling!

¿Y todo esto a qué viene? Cuando estamos desarrollando, refactorizando, tenemos test y vamos a modificar el código que tenemos por delante tenemos que tomar decisiones: ¿En base a qué tomamos esas decisiones? Unas veces pueden ser principios de diseño de orientación a objetos, otras basándonos en libros como “clean code”, “refactoring patterns”,… basándonos en patrones de diseño, basándonos en nuestra experiencia (buena o mala), o basándonos en los principios SOLID, o a code smell o incluso sobre la base de Kent Beck(¿qué haría Kent Beck aquí?)… al final tomamos decisiones basándonos en todo lo que hemos aprendido hasta el momento y de nuestra intuición.

Este post está basado en la charla de Alfredo Casado “Acoplamiento & Connascence” del meetup Software Craftsmanship Madrid

A la hora de tomar decisiones es bueno tener herramientas que nos guíe durante el camino, ya que normalmente siempre nos guiamos por cosas como: ha quedado un código muy elegante, eso no cumple SOLID, este código está demasiado acoplado a esta librería, ha quedado el código muy sucio,… al final como ya hemos dicho antes no solo debemos tener en cuenta nuestra intuición, sino herramientas como el  “Connascence” o “grado de acoplamiento”

Hoy vamos a hablar de los tipos de connascence (o grado de acoplamiento), y de como podemos usarlos como herramienta para evaluar nuestro diseño en términos, de “Coupling & Cohesion”. La idea es tener una serie de “métricas”, herramientas, o como queramos llamarlas para que nuestras decisiones de diseño no se basen solo en nuestra intuición y podamos argumentar por qué hemos tomado una decisión u otra.

Definición de Connascence

El término connascence no es algo nuevo, aparece en un paper de 1992 de Meilir Page-Jones llamado “Comparing Techniques by Means of Encapsulation and Connascence.” y en el libro What Every Programmer Should Know about Object-Oriented Design. Como comentado antes el connascence tiene que ver con el acoplamiento.

Así pues, el connascence entre dos componentes software A y B quiere decir que: Si se realiza un cambio en A se requiere un cambio en B con el fin de que todo el sistema siga funcionando, o que un cambio va a requerir que se modifiquen A y B juntos para que todo el sistema siga funcionando. En otras palabras, existe una relación entre los 2 elementos software que hace que tengan que modificarse ambos para que el sistema siga funcionando.

Tipos de connascence

Page-Jones distingue varios tipos de connascence y los clasifica en Estáticos, que puede ser evaluado por la estructura léxica del código, o dinámico, cuando depende de la ejecución del código.

Connascence de Nombre – Connascence of Name (CoN)

Cuando varios componentes deben estar de acuerdo con el nombre de la entidad.

var count int;
count := 10;

Por ejemplo nombres de variables o nombres de métodos: Si un nombre de un método cambia, los elementos que llaman a este método deben cambiarse para usar el nuevo nombre.

Connascence de tipo – Connascence of Type (CoT)

Cuando varios componentes deben estar de acuerdo en los tipos de una entidad.

var text string;
text := 10; //ups!

Por ejemplo, si un método cambia el tipo de su argumento de un entero a una cadena, los llamadores de ese método deben cambiarse para pasar un argumento diferente que antes.

Connascence de Significado – Connascence of Meaning (CoM)

Cuando varios componentes deben ponerse de acuerdo en el significado de valores particulares.

int strcmp ( string $str1 , string $str2 )

Por ejemplo, el entero 0 significa “false” y el 1 representa “true”. O por ejemplo strcmp que devuelve < 0 si str1 es menor que str2; > 0 si str1 es mayor que str2 y 0 si son iguales.

Connascence de posición Connascence of Position (CoP)

Cuando varios componentes deben estar de acuerdo en el orden de los valores.

function getUserInfo(){
    //name, email, year_birth, is_admin
    return ['juan', 'juan@email.com', 1978, false];
}

function createUser($name, $country, $email, $phone)

Por ejemplo, en la llamada a un método los parámetros tienen que tener un orden determinado.

function calculateImageSize($url){
    $width = ...
    $heigh = ...
    return [$width, $height];
}

list($width, $height) = calculateImageSize('url/img');;

O cuando hay que ponerse de acuerdo en como se devuelven los valores de una función ¿Creéis que la función calculateImageSize devuelve los valores de manera correcta? ¿No sería mejor crear 2 funciones o devolver un objeto?

Connascence de Algoritmo – Connascence of Algorithm (CoA)

Cuando varios componentes deben estar de acuerdo en un algoritmo.

function hash($clearPassword)
{
return md5($clearPassword);
}

Por ejemplo en un algoritmo de autenticación, ambos lados deben tener el mismo algoritmo de hashing o la autenticación fallará.

Connascence de Ejecución – Connascence of Execution (CoE)

Cuando el orden de ejecución es importante.

$email = new Email();
$email->setRecipient('foo@example.com');
$email->setSender('my@domain.com');
$email->send();
$email->setSubject('hello world');

Por ejemplo cuando creamos un objeto y este no funciona justo después de hacer el new, sino que hay que setearle valores como es el caso.

Connascence de tiempo – Connascence of Timing (CoT)

Cuando la sincronización de multiples componentes es importante.

timeout = 200;
socket.writeRequest(data);
answer = socket.readResponse(timeout);

Connascence de Valores – Connascence of Values (CoV)

Cuando existen restricciones sobre los posibles valores que pueden tomar algunos elementos compartidos.

class Article { 
    const DRAFT = 1; 
    const PUBLISHED = 2; 
    private $text; 
    public $state; 

    public function __construct($text) 
    { 
        $this->text = $text; $this->state = self::DRAFT; 

    } 

    public function publish() 
    { 
        $this->state = self::PUBLISHED; 
    } 
} 

    function testArticle() 
    { 
    $article = Article("Test Contents"); assertEqual($article->state, Article::DRAFT); $article->publish(); 
    assertEqual($article->state, Article::PUBLISHED); 
    }

Por ejemplo, cuando varios elementos deben ponerse de acuerdo sobre el estado de un objeto.

Connascence de entidad – Connascence of Identity (CoI)

Cuando varios componentes deben referenciar al mismo objeto

class Producer implements Runnable 
{   
    public static Queue myQueue;   
    public void run() {     
        myQueue.put(37);   
    } 
} 

class Consumer implements Runnable 
{   
    public void run() {     
        int item = Producer.myQueue.get();     
        processItem(item);   
    } 
}

Conclusiones

Como hemos dicho antes la idea del connascence sirve para hablar con propiedad a la hora de argumentar nuestras decisiones, del mismo modo nos da una escala con la que medir el grado de acoplamiento entre componentes.

captura-de-pantalla-2017-02-12-a-las-10-32-17

Si bien es cierto que no existe aun mucha documentación sobre connascence, por poco van saliendo charlas, artículos y post sobre este término.

Referencias

Anuncios

Un comentario en “Connascence, otra manera de hablar de acoplamiento y cohesión

Comenta la entrada

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s