oop - programacion - ¿Es una función un ejemplo de encapsulación?
polimorfismo java (12)
Claro que lo es.
Por ejemplo, un método que opera solo en sus parámetros se consideraría "mejor encapsulado" que un método que opera con datos estáticos globales.
La encapsulación ha existido mucho antes de OOP :)
Al poner funcionalidad en una función, ¿eso solo constituye un ejemplo de encapsulación o necesita usar objetos para encapsular?
Estoy tratando de entender el concepto de encapsulación. Lo que pensé fue si voy de algo como esto:
n = n + 1
que se ejecuta en la naturaleza como parte de un gran cuerpo de código y luego tomo eso, y lo pongo en una función como esta, luego he encapsulado esa lógica de adición en un método:
addOne(n)
n = n + 1
return n
¿O es más cierto que es solo una encapsulación si estoy ocultando los detalles de addOne del mundo exterior, como si fuera un método de objeto y utilizo un modificador de acceso de privado / protegido?
El concepto abstracto de encapsulación significa que oculta los detalles de implementación. La orientación a objetos es solo un ejemplo del uso de la ecnapsulación. Otro ejemplo es el lenguaje llamado módulo-2 que usa (o usa) módulos de implementación y módulos de definición. Los módulos de definición ocultaron la implementación real y, por lo tanto, proporcionaron la encapsulación.
La encapsulación se usa cuando puedes considerar algo como una caja negra. Los objetos son una caja negra. Usted conoce los métodos que proporcionan, pero no cómo se implementan.
[EDITAR] En cuanto al ejemplo en la pregunta actualizada: depende de cuán estrecha o amplia se defina la encapsulación. Su ejemplo AddOne no oculta nada en lo que creo. Sería ocultar / encapsular la información si su variable fuera un índice de matriz y llamaría a su método moveNext y tal vez tenga otra función setValue y getValue. Esto permitiría a las personas (juntas, tal vez con algunas otras funciones) navegar su estructura y configuración y obtener variables con ellos siendo conscientes de que usa una matriz. Si tu lenguaje de programación soportara otros conceptos más ricos, podrías cambiar la implementación de moveNext, setValue y getValue al cambiar el significado y la interfaz. Para mí eso es encapsulación.
Es una cosa a nivel de componente
Mira esto :
En informática, la encapsulación es la ocultación de los mecanismos internos y las estructuras de datos de un componente de software detrás de una interfaz definida, de tal forma que los usuarios del componente (otras piezas de software) solo necesitan saber qué hace el componente, y no puede hacerse depender de los detalles de cómo lo hace. El objetivo es lograr el potencial para el cambio: los mecanismos internos del componente se pueden mejorar sin afectar a otros componentes, o el componente se puede reemplazar por uno diferente que admita la misma interfaz pública.
(No entiendo muy bien tu pregunta, avísame si ese enlace no cubre tus dudas)
No, los objetos no son necesarios para la encapsulación. En el sentido más amplio, "encapsulación" solo significa "ocultar los detalles de la vista" y, a ese respecto, un método encapsula sus detalles de implementación.
Eso en realidad no significa que puedas salir y decir que tu código está bien diseñado solo porque lo dividiste en métodos. Un programa que consta de 500 métodos públicos no es mucho mejor que el mismo programa implementado en un método de 1000 líneas.
Al crear un programa, independientemente de si usa técnicas orientadas a objetos o no, debe pensar en la encapsulación en muchos lugares diferentes: ocultar los detalles de implementación de un método, ocultar datos del código que no necesita saber al respecto , simplificando interfaces a módulos, etc.
Actualización: para responder a su pregunta actualizada, tanto "poner código en un método" como "usar un modificador de acceso" son formas diferentes de encapsular la lógica, pero cada una actúa en un nivel diferente.
Al poner el código en un método, se ocultan las líneas de código individuales que componen ese método, de modo que las personas que llaman no necesitan preocuparse acerca de cuáles son esas líneas; solo se preocupan por la firma del método.
Marcar un método en una clase como (digamos) "privado" oculta ese método para que un consumidor de la clase no tenga que preocuparse por él; solo se preocupan por los métodos públicos (o propiedades) de su clase.
Seré el primero en estar en desacuerdo con lo que parece ser la tendencia de respuesta. Sí, una función encapsula cierta cantidad de implementación. No necesita un objeto (que creo que usa para referirse a una clase).
Ver Meyers también.
Simplifiquemos esto de alguna manera con una analogía: enciende la llave de su automóvil y arranca. Sabes que hay más que solo la clave, pero no tienes que saber qué está pasando allí. Para ti, tecla giratoria = arranque del motor. La interfaz de la clave (es decir, por ejemplo, la llamada a la función) oculta la implementación del motor de arranque que hace girar el motor, etc ... (la implementación). Eso es encapsulación. Te ahorras tener que saber lo que sucede debajo del capó, y te alegra.
Si creó una mano artificial, por ejemplo, para girar la llave por usted, eso no es encapsulación. Está girando la llave con un intermediario adicional sin ocultar nada. Eso es lo que me recuerda tu ejemplo: no está encapsulando detalles de implementación, aunque ambos se logran a través de llamadas a funciones. En este ejemplo, cualquier persona que recoja su código no lo agradecerá. De hecho, serán más propensos a golpearlo con su mano artificial.
Se puede usar cualquier método que se le ocurra para ocultar información (clases, funciones, bibliotecas dinámicas, macros) para la encapsulación.
Un método no es más un ejemplo de encapsulación que un automóvil es un ejemplo de buena conducción. La encapsulación no se trata de Synax, es un problema de diseño lógico. Ambos objetos y métodos pueden presentar una buena y mala encapsulación.
La forma más sencilla de pensar es si el código oculta / abstrae los detalles de otras partes del código que no necesitan saber / preocuparse por la implementación.
Volviendo al ejemplo del automóvil: la transmisión automática ofrece una buena encapsulación: como conductor, usted se preocupa por el avance / retroceso y la velocidad. La transmisión manual es una mala encapsulación: desde la perspectiva del conductor, el engranaje específico requerido para velocidades bajas / altas generalmente es irrelevante para la intención del conductor.
El Modelo de Referencia de Procesamiento Distribuido Abierto - escrito por la Organización Internacional de Normalización - define los siguientes conceptos:
Entidad: Cualquier cosa concreta o abstracta de interés.
Objeto: un modelo de una entidad. Un objeto se caracteriza por su comportamiento y, doblemente, por su estado.
Comportamiento (de un objeto): una colección de acciones con un conjunto de restricciones sobre cuándo pueden ocurrir.
Interfaz: una abstracción del comportamiento de un objeto que consiste en un subconjunto de las interacciones de ese objeto junto con un conjunto de restricciones sobre cuándo pueden ocurrir.
Encapsulación: la propiedad de que la información contenida en un objeto solo es accesible a través de interacciones en las interfaces soportadas por el objeto.
Estos, lo apreciarás, son bastante amplios. Veamos, sin embargo, si poner funcionalidad dentro de una función puede considerarse lógicamente que constituye una encapsulación en estos términos.
En primer lugar, una función es claramente un modelo de "cosa de interés", ya que representa un algoritmo que (presumiblemente) desea ejecutar y ese algoritmo se refiere a un problema que está tratando de resolver (y por lo tanto es un modelo de él) .
¿Tiene una función un comportamiento? Ciertamente lo hace: contiene una colección de acciones (que podrían ser cualquier cantidad de sentencias ejecutables) que se ejecutan bajo la restricción de que la función debe ser llamada desde algún lugar antes de que pueda ejecutarse. Una función no puede ser llamada espontáneamente en ningún momento, sin factor causal. Suena como jerga legal? Puedes apostar. Pero vamos a arar, sin embargo.
¿Tiene una función una interfaz? Ciertamente lo hace: tiene un nombre y una colección de parámetros formales, que a su vez asignan a las declaraciones ejecutables contenidas en la función en que, una vez que se llama a una función, se entiende que el nombre y la lista de parámetros identifican de forma única la colección de ejecutables declaraciones que se ejecutarán sin que la parte llamante especifique las declaraciones reales.
¿Tiene una función la propiedad de que la información contenida en la función solo es accesible a través de interacciones en las interfaces soportadas por el objeto? Hmm, bueno, puede.
Como se puede acceder a cierta información a través de su interfaz, cierta información debe estar oculta e inaccesible dentro de la función. (La propiedad que dicha información exhibe se denomina ocultación de información, que Parnas definió argumentando que los módulos deberían diseñarse para ocultar las decisiones difíciles y las decisiones que probablemente cambien). Entonces, ¿qué información está oculta dentro de una función?
Para ver esto, primero debemos considerar la escala. Es fácil afirmar que, por ejemplo, las clases de Java se pueden encapsular dentro de un paquete: algunas de las clases serán públicas (y, por lo tanto, serán la interfaz del paquete) y otras serán de paquete privado (y, por lo tanto, ocultas en el paquete). . En la teoría de encapsulación, las clases forman nodos y los paquetes forman regiones encapsuladas, con la totalidad formando un gráfico encapsulado; el gráfico de clases y paquetes se llama tercer gráfico.
También es fácil afirmar que las funciones (o métodos) están encapsuladas dentro de las clases. Una vez más, algunas funciones serán públicas (y por lo tanto, serán parte de la interfaz de la clase) y algunas serán privadas (y por lo tanto ocultas por la información dentro de la clase). La gráfica de funciones y clases se llama el segundo gráfico.
Ahora llegamos a las funciones. Si las funciones deben ser un medio de encapsulamiento, deben contener cierta información pública para otras funciones y cierta información que está oculta por la información dentro de la función. ¿Qué podría ser esta información?
McCabe nos da un candidato. En su documento histórico sobre complejidad ciclomática, Thomas McCabe describe el código fuente donde, ''cada nodo en el gráfico corresponde a un bloque de código en el programa donde el flujo es secuencial y los arcos corresponden a las ramas tomadas en el programa''.
Tomemos el bloque McCabian de ejecución secuencial como la unidad de información que puede ser encapsulada dentro de una función. Como el primer bloque dentro de la función es siempre el primer y único bloque garantizado que se ejecutará, podemos considerar que el primer bloque es público, ya que puede ser llamado por otras funciones. Sin embargo, las otras funciones no pueden invocar todos los otros bloques (excepto en los lenguajes que permiten saltar a las funciones de flujo medio), por lo que estos bloques pueden considerarse ocultos por la información dentro de la función.
Tomando estas definiciones (quizás un poco tenues), podemos decir que sí: poner funcionalidad dentro de una función constituye una encapsulación. La encapsulación de bloques dentro de las funciones es el primer gráfico.
Sin embargo, hay una carencia. ¿Consideraría encapsulado un paquete cuyas clases eran públicas? Según las definiciones anteriores, pasa la prueba, ya que puede decirse que la interfaz del paquete (es decir, todas las clases públicas) sí ofrece un subconjunto del comportamiento del paquete a otros paquetes. Pero el subconjunto en este caso es el comportamiento del paquete completo, ya que ninguna clase está oculta por información. Por lo tanto, a pesar de satisfacer de manera reiterada las definiciones anteriores, creemos que no satisface el espíritu de las definiciones, ya que seguramente algo debe estar oculto por la información para que pueda afirmarse una encapsulación verdadera.
Lo mismo es cierto para el examen que das. Ciertamente, podemos considerar n = n + 1 como un solo bloque de McCabian, ya que (y el enunciado de retorno) son un único flujo secuencial de ejecuciones. Pero la función en la que pones esto contiene solo un bloque, y ese bloque es el único bloque público de la función, y por lo tanto no hay bloques ocultos de información dentro de tu función propuesta. Entonces puede satisfacer la definición de encapsulación, pero yo diría que no satisface el espíritu.
Todo esto, por supuesto, es académico a menos que pueda demostrar un beneficio de tal encapsulación.
Hay dos fuerzas que motivan la encapsulación: la semántica y la lógica.
La encapsulación semántica simplemente significa encapsulación basada en el significado de los nodos (para usar el término general) encapsulada. Entonces, si te digo que tengo dos paquetes, uno llamado ''animal'' y otro llamado ''mineral'', y luego te doy tres clases de perro, gato y cabra y pregunto en qué paquetes deben encapsularse estas clases, luego, dado ninguna otra información, estaría perfectamente en lo cierto al afirmar que la semántica del sistema sugeriría que las tres clases se encapsularan dentro del paquete «animal», en lugar de «mineral».
La otra motivación para la encapsulación, sin embargo, es la lógica.
La configuración de un sistema es la identificación precisa y exhaustiva de cada nodo del sistema y la región encapsulada en la que reside; una configuración particular de un sistema Java es, en el tercer gráfico, identificar todas las clases del sistema y especificar el paquete en el que reside cada clase.
Encapsular lógicamente un sistema significa identificar alguna propiedad matemática del sistema que depende de su configuración y luego configurar ese sistema para que la propiedad se minimice matemáticamente.
La teoría de encapsulación propone que todos los gráficos encapsulados expresen un número potencial máximo de bordes (MPE). En un sistema Java de clases y paquetes, por ejemplo, el MPE es el número máximo potencial de dependencias de código fuente que pueden existir entre todas las clases de ese sistema. Dos clases dentro del mismo paquete no pueden estar ocultas entre sí, por lo que ambas pueden formar deposiciones entre sí. Sin embargo, dos clases privadas de paquete en paquetes separados no pueden formar dependencias entre sí.
La teoría de encapsulación nos dice cuántos paquetes deberíamos tener para un número determinado de clases, de modo que el MPE se minimice. Esto puede ser útil porque la forma débil del Principio de Carga establece que la carga potencial máxima de transformar una colección de entidades es una función del número máximo potencial de entidades transformadas; en otras palabras, cuantas más dependencias potenciales entre usted y el código fuente tenga. sus clases, mayor será el costo potencial de hacer cualquier actualización en particular. Minimizar el MPE minimiza el costo potencial máximo de las actualizaciones.
Dadas n clases y un requisito de p clases públicas por paquete, la teoría de encapsulación muestra que la cantidad de paquetes, r, que deberíamos tener para minimizar el MPE viene dada por la ecuación: r = sqrt (n / p).
Esto también se aplica a la cantidad de funciones que debería tener, dado el número total, n, de bloques de McCabian en su sistema. Las funciones siempre tienen un solo bloque público, como mencionamos anteriormente, por lo que la ecuación para el número de funciones, r, tener en su sistema se simplifica a: r = sqrt (n).
Hay que admitir que pocos consideraron la cantidad total de bloques en su sistema cuando practican la encapsulación, pero se hace fácilmente a nivel de clase / paquete. Y además, minimizar MPE es casi completamente entuitive: se hace minimizando el número de clases públicas y tratando de distribuir uniformemente las clases sobre los paquetes (o al menos evitar tener la mayoría de los paquetes con, digamos, 30 clases y un monstruo pacakge con 500 clases, en cuyo caso el MPE interno de este último puede superar fácilmente el MPE de todos los demás).
La encapsulación implica un equilibrio entre lo semántico y lo lógico.
Todo muy divertido.
Quizás esté confundiendo la abstracción con la encapsulación, que se entiende en el contexto más amplio de la orientación a objetos.
La encapsulación incluye correctamente los tres elementos siguientes:
- Abstracción
- Implementación oculta
- División de Responsabilidad
La abstracción es solo un componente de la encapsulación. En su ejemplo, ha abstraído la funcionalidad de adición del cuerpo principal del código en el que una vez residió. Para ello, identifique algunas características comunes en el código, reconociendo un concepto (adición) sobre un caso específico (agregando el número uno a la variable n). Debido a esta capacidad, la abstracción hace que un componente encapsulado, un método o un objeto, sea reutilizable.
Igualmente importante para la noción de encapsulación es la idea de la ocultación de la implementación. Esta es la razón por la cual la encapsulación se discute en el ámbito de la orientación a objetos. La ocultación de la implementación protege un objeto de sus usuarios y viceversa. En OO, usted hace esto presentando una interfaz de métodos públicos a los usuarios de su objeto, mientras que la implementación del objeto se lleva a cabo dentro de métodos privados.
Esto tiene dos beneficios. En primer lugar, al limitar el acceso a su objeto, evita una situación en la que los usuarios del objeto pueden dejar el objeto en un estado no válido. En segundo lugar, desde el punto de vista del usuario, cuando utilizan su objeto, solo están ligeramente vinculados a él; si cambia su implementación más adelante, no se verán afectados.
Finalmente, la división de la responsabilidad, en el contexto más amplio de un diseño OO, es algo que debe considerarse para abordar la encapsulación de manera adecuada. No sirve de nada encapsular una colección aleatoria de funciones: la responsabilidad debe definirse de forma clara y lógica para que exista la menor superposición o ambigüedad posible. Por ejemplo, si tenemos un objeto Toilet, querremos aislar su dominio de responsabilidades de nuestro objeto Kitchen.
En un sentido limitado, sin embargo, tiene razón en que una función, digamos, "modulariza" alguna funcionalidad al abstraerla. Pero, como ya he dicho, la ''encapsulación'' como un término se entiende en el contexto más amplio de la orientación a objetos para aplicarla a una forma de modularización que cumpla con los tres criterios enumerados anteriormente.
en la estricta terminología orientada a objetos, uno podría sentirse tentado a decir no, una función "simple" no es lo suficientemente poderosa como para llamarse encapsulación ... pero en el mundo real la respuesta obvia es "sí, una función encapsula algún código".
para los puristas OO que se enojan con esta blasfemia, consideren una clase anónima estática sin estado y un solo método; si la función AddOne () no es encapsulación, ¡tampoco esta clase!
y para ser pedante, la encapsulación es una forma de abstracción, no viceversa. ;-)
La encapsulación es un proceso en el cual los atributos (miembro de datos) y el comportamiento (función de miembro) de un objeto en combinación entre sí como una sola entidad se refieren como clase.
Normalmente, no es muy significativo hablar de encapsulación sin referencia a las propiedades en lugar de métodos exclusivos ; puede poner controles de acceso a los métodos, sin duda, pero es difícil ver cómo va a ser eso sin sentido sin ningún dato enfocado al método encapsulado . Probablemente podrías argumentarlo valiéndolo, pero sospecho que sería tortuoso.
Así que no, lo más probable es que no uses la encapsulación solo porque pones un método en una clase en lugar de tenerlo como una función global.