L'encapsulació és l'empaquetament d'informació (dades i funcions) en un sol component. Les característiques de l'encapsulació estan suportades en la majoria de llenguatges de programació orientats a objectes mitjançant classes, encara que existeixen altres mètodes alternatius d'implementació. Això permet amagar de forma selectiva tant atributs com mètodes per protegir el codi de la corrupció accidental. Encapsulació, herència i polimorfisme són els tres pilars de la programació orientada a objectes.

En els llenguatges de programació, l'encapsulació s'utilitza per referir-se a una de dues nocions relacionades però diferents, i algunes vegades a la combinació [1][2] de la mateixa:

  • Un mecanisme del llenguatge per a restringir l'accés a alguns dels components de l'objecte.[3][4]
  • Una construcció del llenguatge que permet agrupar les dades amb els mètodes (o altres funcions) que operen sobre aquestes dades.[5][6]

Alguns investigadors dels llenguatges de la programació utilitzen el significat del primer punt sol o amb combinació del segon punt per indicar que l'encapsulació és una característica clau en el llenguatge orientat a objectes.

La segona definició ve donada pel fet que molts llenguatges de POO no amaguen/encapsulen la informació de forma automàtica, de manera que l'ocultació d'informació que permet és part del disseny decidit pel programador.

Definició general modifica

En general, l'encapsulació és un dels 4 fonaments de la POO (programació orientada a objectes). L'encapsulació es refereix a l'agrupació de les dades amb els mètodes que operen sobre aquestes dades.[7] L'encapsulació s’utilitza per amagar els valors o l'estat d'una estructura de dades dins d'un objecte, prevenint d’aquesta manera accessos a la seva informació per part de tercers. Les classes solen tenir mètodes públics que tracten la seva informació interna, de manera que tercers (altres objectes) poden interactuar d'una forma segura amb la informació interna d’aquestes.

Aquest mecanisme no és únic de la POO. Implementacions de tipus abstractes de dades, per exemple mòduls, ofereixen una forma similar d’encapsulament. Aquesta similitud es deriva del fet que ambdues nocions es basen en el mateix fonament matemàtic d'un tipus existencial.[8]

Sigui quina sigui la combinació de dades, l'encapsulació d'una classe sobre els objectes que són creats d’aquesta prevaler durant tota la vida dels objectes. D’aquesta manera, l'estat intern d'un objecte només dependrà dels seus propis mètodes que permeten modificar el seu estat intern.

D’aquesta manera es pot fer una analogia amb la noció de càpsula, ja que no només tenca el seu contingut, sinó que a més protegeix aquest contingut de l'entorn extern.

Importància històrica modifica

El propòsit de l'encapsulació es pot resumir de la següent manera: necessari per reduir col·lisions entre variables anomenades idènticament i per agrupar mètodes i atributs (variables) que guarden una relació formant d’aquesta manera les classes.

Aquest patró de pràctica fa el codi molt més fàcil d'entendre per l’ésser humà, ja que deixa de veure un programa com milers de línies, i ara el veu com agrupacions d'agrupacions d'agrupacions de codi, de manera que pot entendre’l i anar profunditzant en aquella part del codi que li interessi sense necessitat de veure’l tot sencer.

Així doncs, l'encapsulació va tenir un paper clau en l'evolució de la programació permetent crear llenguatges de més alt nivell.

Com a mecanisme d'ocultació de la informació modifica

Sota aquesta definició, l'encapsulació significa que la representació interna d'un objecte està generalment ocult a la vista fora de la definició de l'objecte. En general, els mètodes propis només de l'objecte poden inspeccionar directament o manipular els seus camps.

Alguns llenguatges com Smalltalk o Ruby només permeten accedir a la informació interna de l'objecte mitjançant els seus propis mètodes, però la majoria (per exemple: C++, C# o Java) permeten certa llibertat per al programador sobre què està ocult, normalment mitjançant keywords com public i private. Cal destacar que segons l'ISO C++ estàndard els keywords protected private i public es refereixen a especificadors d’acces(“access specifier”) i que ells no amaguen cap informació. L'ocultació d'informació s’aconsegueix subministrant una versió compilada del codi font que està interconnectat amb un arxiu de capçelera (“header”).

Ocultant la part interna dels objectes, protegeix la seva robustesa evitant que els usuaris modifiquin les dades internes del component, deixant-les amb uns valors inconsistents. Un benefici de l'encapsulament és que pot reduir la complexitat, incrementar la robustesa, permetent al desenvolupador limitar les inter dependències entre els components.

Gairebé sempre hi ha una manera de sobreescriure aquesta protecció, normalment amb una reflexió API (Ruby, Java, C#, etc), a vegades mitjançant "name mangling" (Python) o utilitzat paraules clau especials com el friend de C++.

El següent programa escrit en C# mostra com es pot restringir l’accés a una dada posant-la de forma privada.

class Programa {
	public class Compte {
		private decimal Balanc = 500.00m;

		public decimal ComprovaBalanc() {
			return Balanc;
		}
	}

	static void Main() {
		Compte elMeuCompte = new Compte();
		decimal elMeuBalanc = elMeuCompte.ComprovaBalanc();

/* Aquest programa Main comprova l'estat del balanc a través del mètode
* Public “ComprovaBalanc” de la Classe Compte, però no pot manipular el 
* valor de Balanc */
 	}
}

A continuació, el mateix mètode en Java:

public class Empleat {
    private BigDecimal salari = new BigDecimal(50000.00); 

    public BigDecimal obtenirSalari() {
        return salari;
    } 

    public static void main() {
        Empleat e = new Empleat();
        BigDecimal sou = e.obtenirSalari();
    }
}

Exemple en PHP:

class persona {      
   var $nom;      
   public $alcada;      
   protected $seguretat_social;
   private $numero_pin; 

   function __construct($nom_persona) {      
      $this->nom = $nom_persona;      
   }      

   function set_name($nou_nom) {      
      $this->nom = $nou_nom;
   }   

   function obtenir_nom() {
      return $this->nom;
   }      
}

També és possible l'encapsulament en llenguatges antics no orientats a objectes. En c per exemple, es pot declarar una estructura en una API pública (a l’arxiu de capçalera “header”) on s’escriuen les funcions que actuen sobre les variables que no són accessibles directament.

// arxiu de capcalera "api.h" 

struct Entitat;          // Estructura oculta a l’usuari 


// Funcions de la API que operen sobre les variables

extern struct Entitat *  obrir_entitat(int id);
extern int              informacio_entitat(struct Entity *informacio);
extern void             tancar_entitat(struct Entitat *informacio);

Els usuaris criden les funcions de l'API per a crear, operar i destruir els objectes que són privats. El contingut d’aquest tipus d’objectes només són accessibles a través de les funcions de l'API, els usuaris no poden accedir directament al seu contingut. La implementació del codi per aquest tipus de funcions és la següent:

// Implementació "api.c" 

include "api.h" 

// Definició completa de l’objecte

struct Entitat {
    int     id_entitat;         // numero ID
    char    nom_entitat[20];   // nom
    ... i altres variables ...
}; 

// Implementació de les funcions de la API
struct Entitat * obrir_entitat(int id)
{ ... } 

int informacio_entitat(struct Entitat *informacio)
{ ... } 

void tancar_entitat(struct Entitat *informacio)
{ ... }<br>

Referències modifica

  1. Michael Lee Scott, Programming language pragmatics, Edition 2, Morgan Kaufmann, 2006, ISBN 0-12-633951-1, p. 481: "Encapsulation mechanisms enable the programmer to group data and the subroutines that operate on them together in one place, and to hide irrelevant details from the users of an abstraction."
  2. Nell B. Dale, Chip Weems, Programming and problem solving with Java, Edition 2, Jones & Bartlett Publishers, 2007, ISBN 0-7637-3402-0, p. 396
  3. John C. Mitchell, Concepts in programming languages, Cambridge University Press, 2003, ISBN 0-521-78098-5, p.522
  4. Pierce, Benjamin. Types and Programming Languages. MIT Press, 2002. ISBN 0-262-16209-1.  p. 266
  5. Wm. Paul Rogers, Encapsulation is not information hiding Arxivat 2013-10-29 a Wayback Machine., JavaWorld.com, 05/18/01
  6. Thomas M. Connolly, Carolyn E. Begg, Database systems: a practical approach to design, implementation, and management, Edition 4, Pearson Education, 2005, ISBN 0-321-21025-5, Chapter 25, "Introduction to Object DMBS", section "Object-oriented concepts", p. 814
  7. Rodgers, Wm. Paul. «Encapsulation is not information hiding». JavaWorld. Arxivat de l'original el 2014-06-08. [Consulta: 15 març 2014].
  8. Pierce (2002), Section 24.2 "Data Abstraction with Existentials"