2009-01-19 12 views
12

Esto surgió en una conversación que estaba teniendo en línea, y se me ocurrió que no tengo idea de cómo se supone que funciona: muchos programadores parecen dar por hecho, de hecho, es obvio que las clases son una característica de idioma necesaria para la gestión de grandes proyectos de software.¿Cómo te ayudan las clases a administrar aplicaciones grandes?

No es obvio para mí cómo lo hacen.

Mi pregunta es, ¿cómo lo sabes? ¿Qué medidas objetivas hay que demuestren que las clases aumentan la productividad, reutilizan el código y reducen la complejidad de la producción de un programa? ¿Qué aspectos de las clases los hacen ideales para que los equipos grandes colaboren?

Y ahora, hay una pregunta que me gustaría hacer, que es algo difícil de expresar. Lo siento si me equivoco y termino confundiendo o enojando a alguien:

Objetivamente, ¿cómo sabes que el uso de clases no es la causa de que la aplicación sea grande para empezar? Es decir, ¿es posible que se haya escrito un programa con una función equivalente, con mucho menos código, lo suficientemente pequeño como para no necesitar medidas especiales para "administrarlo", utilizando alguna otra estrategia de reutilización de código? (hay muchos para elegir, como los de paradigmas de programación funcional o programación orientada a aspectos).

Ese último bit es algo que Steve Yegge ha estado insinuando en su blog. Pero soy un poco escéptico de ambos lados de la discusión, debido a la falta real de datos duros por parte de nadie, y no tengo suficiente experiencia para llegar a una conclusión por mi cuenta.

¿Qué opinas?

editar: En particular, estoy interesado en por qué muchos programadores piensan que la herencia de estilo prototípico no está a la altura de las grandes aplicaciones. Lamento que esta pregunta sea vaga: es producto de mi falta de comprensión sobre este tema.

edit2: parece haber cierta confusión sobre lo que quiero decir con programación funcional. (No creo que alguna versión de VB fuera funcional, ciertamente no versiones anteriores). Por favor, consulte el artículo de Wikipedia. http://en.wikipedia.org/wiki/Functional_programming

edit3: y permítanme enfatizar que estoy buscando medidas objetivas. Opiniones no subjetivas

Respuesta

2

La teoría de encapsulación proporciona una razón objetiva por la cual las clases son mejores que no tener clases en absoluto.

La Organización Internacional de Normalización define la encapsulación como, 'La propiedad de que la información contenida en un objeto es accesible solo a través de interacciones en las interfaces soportadas por el objeto.'

Por lo tanto, como se puede acceder a cierta información a través de estas interfaces, cierta información debe estar oculta e inaccesible dentro del objeto. 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 decisiones difíciles y decisiones que probablemente cambiarán.

Tenga en cuenta que la palabra: cambiar. El ocultamiento de información se refiere a eventos potenciales, como el cambio de decisiones de diseño difíciles en el futuro.

Considere una clase con dos métodos: método a() que es información oculta dentro de la clase, y método b() que es público y, por lo tanto, accesible directamente por otras clases.

Existe una cierta probabilidad de que un cambio futuro al método a() requiera cambios en los métodos de otras clases. También hay una cierta probabilidad de que un cambio futuro en el método b() requerirá cambios en los métodos en otras clases. Sin embargo, la probabilidad de que tales cambios de ondulación ocurran para el método a(), será generalmente menor que para el método b() simplemente porque el método b() puede depender de más clases.

Esta reducción en la probabilidad de impactos de ondulación es un beneficio clave de la encapsulación.

Considere la cantidad máxima posible de dependencias de código fuente (MPE - el acrónimo es de teoría de grafos) en cualquier programa. Extrapolando de las definiciones anteriores, podemos decir que, dados dos programas que entregan funcionalidades idénticas a los usuarios, el programa con el MPE más bajo está mejor encapsulado, y estadísticamente, el programa más bien encapsulado será más barato de mantener y desarrollar, porque el costo del cambio de potencial máximo será menor que el cambio potencial máximo al sistema menos encapsulado.

Considere, además, un lenguaje con métodos justos y sin clases y, por lo tanto, sin medios de ocultación de métodos entre sí. Digamos que nuestro programa tiene 1000 métodos. ¿Cuál es el error máximo permitido de este programa?

La teoría de encapsulación nos dice que, dado un sistema de n nodos públicos, el error máximo permitido de este sistema es n (n-1). Por lo tanto, el MPE de nuestros 1000 métodos públicos es 999,000.

Ahora vamos a dividir ese sistema en dos clases, cada una con 500 métodos. Como ahora tenemos clases, podemos elegir tener algunos métodos públicos y algunos métodos privados. Este será el caso a menos que todos los métodos sean realmente dependientes de cualquier otro método (lo cual es poco probable). Digamos que 50 métodos en cada clase son públicos. ¿Cuál sería el error máximo permitido del sistema?

La teoría de encapsulación nos dice que es: n ((n/r) -1 + (r-1) p) donde r es el número de clases, y p es el número de métodos públicos por clase. Esto le daría a nuestro sistema de dos clases un MPE de 499,000. Por lo tanto, el costo potencial máximo de un cambio en este sistema de dos clases ya es sustancialmente más bajo que el del sistema no encapsulado.

Digamos que divide su sistema en 3 clases, cada una tiene 333 clases (bueno, una tendrá 334), y nuevamente cada una con 50 métodos públicos. ¿Cuál es el MPE? Usando nuevamente la ecuación anterior, el MPE sería de aproximadamente 482,000.

Si el sistema se divide en 4 clases de 250 métodos cada una, el MPE sería 449,000.

Si parece que aumentar el número de clases en nuestro sistema siempre disminuirá su MPE, pero esto no es así. La teoría de la encapsulación muestra que el número de clases en las que el sistema debería descomponerse para minimizar el MPE es: r = sqrt (n/p), que para nuestro sistema es en realidad 4. Un sistema con 6 clases, por ejemplo, tendría un MPE de 465,666.

+0

Stellar answer. Creo que lo entiendo, pero incluso si no lo hago, creo que leer esto me ha hecho progresivamente un mejor programador. Todavía tengo esperanza para el futuro, que no dejaremos de buscar mejores formas más útiles de obtener estos beneficios de encapsulación. – Breton

2

No soy fanático de ningún paradigma de programación, pero he estado operando de manera OO por un tiempo.

Personalmente, he tenido un montón de 'a-HA!' momentos en que las clases me han ayudado a entender mejor el dominio en el que estoy trabajando.

En particular, en los casos en que existe confusión sobre por qué un sistema está funcionando mal, o qué se supone que debe hacer un sistema, las clases a menudo me obligan a pensar acerca de qué debe hacer esta parte discreta del todo, y más a menudo no conducen a la refactorización de las clases/métodos disponibles.

En resumen, la encapsulación realmente me hace una persona más feliz. ;)

Espero que ayude.

1

Prefiero clases para poder dividir un gran problema en piezas manejables que se pueden probar como unidades individuales. En mi humilde opinión, la reutilización del código está sobrevalorada. Apenas lo he visto en el lugar donde trabajo. Para mí, lo que más saco del buen OO es una buena capacidad de prueba.

El otro extremo es el uso de un montón de variables globales y mermelada de toda su lógica en public static void main (o Page_Load en ASP.NET) y llamar a métodos estáticos que requieren otros métodos estáticos y así sucesivamente ... (Me mareé en al final de la última oración.)

Lo único que rompería mi mentalidad de OO es si estaba trabajando con un lenguaje funcional puro, que es algo que no he pensado desde la universidad desafortunadamente.

6

Esta es una muy buena pregunta. Organizar el código en clases es una forma de que un equipo de desarrollo cree módulos pequeños y reutilizables. Además, estos módulos tienen interfaces expresivas y limitadas que expresan solo de qué es capaz la clase y no cómo lo hace. Cada clase es ortogonal a las demás y, por lo tanto, es altamente comprobable y modular en caso de error.

Ahora lo que acabo de describir es una escena extraña de un mundo perfecto. Pero cualquier buen desarrollador que trabaje en OOP debería esforzarse por algo como esto.

OOP es un reconocimiento de que nosotros, los desarrolladores, somos simplemente humanos y no podemos comprender todo un sistema a la vez. Así que dividimos el sistema en pequeñas partes reutilizables y nos centramos en ellas.

Tome un número de teléfono de diez dígitos de EE. UU. Como ejemplo. Es difícil recordar un número de diez dígitos en tu cabeza, así que hacemos lo que los psicólogos llaman "fragmentación". Esto significa que descomponemos mentalmente los números en trozos que podemos recordar mejor.

Entonces 1234567890 se convierte en 123-456-7890. Afortunadamente para nosotros, las compañías telefónicas también dividen estos números de la misma manera y le asignan el significado a los fragmentos. 123 es el código de área, 456 es el prefijo, y 7890 es el número de línea. Cada uno de estos trozos es como una clase, todos tienen responsabilidades, formatos y significados individuales.

Por lo tanto, en conclusión, lo mejor que puedo decir es que OOP nos permite construir sistemas grandes y escalables que tienen funcionalidad centralizada y encapsulada. Nos permite no tener que ver la imagen completa todo el tiempo y ser capaces de enfocarse en hacer una cosa y hacerlo bien.

0

Dos cosas.

La primera es la idea de que una clase es una entidad de dominio opaco. Cuando se hace correctamente, los programas orientados a objetos introducen una capa de abstracción: en la siguiente capa más alta, ordena los objetos para hacer lo que desee, en lugar de tratar con los detalles. No necesita saber cómo funcionan los objetos y las clases: solo lo que hacen. Este es un tipo de ocultación de información, y reduce la complejidad que un equipo debe tener en mente mientras trabaja.

La segunda es que la programación OO permite un tipo de reutilización de código: puede definir clases que anulan ciertos comportamientos en otras clases (herencia) o clases cuyas instancias incluyen instancias de otras clases, usándolas para lograr sus objetivos (encapsulación y composición).

Correctamente utilizando técnicas OO puede reducir la cantidad de código que necesita para administrar y reducir el número de cosas que debe tener en cuenta a medida que trabaja o mantiene el sistema. En la práctica, este enfoque no siempre funciona.

2

Creo que las clases pueden ayudar, porque corresponden al concepto cognitivo muy general de categorization, por lo que pueden ayudar a describir grandes aplicaciones de forma natural.

0

Objetivamente, ¿cómo se sabe que el uso de clases no es la causa de la aplicación ser grande para empezar?

tomar cualquier gran programa/aplicación que no fue escrito en un lenguaje orientado a objetos (por ejemplo, C, COBOL, SQL, incluso sin formato) y usted debería ser capaz de ser testigo de que el tamaño del código no se atribuye directamente al modelo de lenguaje. Para cada número de componentes C# o Java bien diseñados, altamente refinados y reutilizables, también hay un número igual de DLL C bien reutilizables, bien diseñados y altamente refinados. Por el contrario, hay un número igual de código horrible e hinchado.

El punto es que los buenos programadores pueden refinar sus diseños de sistema independientemente del idioma/plataforma.

Con respecto a OOP, al menos para mí, trae a la mesa un "potencial" - una vista del mundo de programación un poco más cerca a nuestro mundo real. Todos sabemos que nuestro mundo y este universo de materia están llenos de objetos compuestos de objetos más pequeños. Sigue haciendo zoom desde los sistemas de estrellas galatográficos hasta la molécula, el átomo y las partículas subatómicas, es realmente asombroso cómo la materia muy diferente está formada por las mismas partículas diminutas combinadas en varios patrones. Mire nuestra propia biología incluso, es alucinante a veces pensar que el 60% de nuestros cuerpos es en realidad solo agua cuando se descompone a su máxima expresión. Sin embargo, fíjate en todos los diversos sistemas y órganos que funcionan con química para mantenernos activos y vivos.

Cuando aprendemos a comprender la simplicidad (oh, en verdad ... ja, ja) de los componentes básicos que forman los sistemas del mundo real que vemos en la naturaleza cotidiana, entonces deberíamos ser capaces de comprender que el diseño y la construcción Los sistemas extremadamente complicados o sofisticados deberían comenzar con componentes pequeños que hacen muy poco por sí mismos. Y al combinarlos y unirlos lentamente en componentes cada vez más grandes, podemos obtener más funcionalidad y capacidad. Hasta que alcancemos el sistema deseado que imaginamos.

El uso (correcto) de las clases es descomponer un sistema en su máxima expresión. Como sea posible. Para que pueda ver algo a la vez y un nivel particular de abstracción y no sentirse abrumado por propósitos y lógica que no está tratando con su área de preocupación actual. Siempre que diseñe un sistema, piense en su propia anatomía; piensa cómo diseñarías el cuerpo humano. Cada vez que diseñe un sistema, piense en comenzando una nueva compañía; cuáles son las principales divisiones, los departamentos que necesita para operar el negocio. ¿Quiénes son el tipo de personal requerido para ejecutar esos departamentos? Los diversos equipos que necesitan usar e interactuar para llevar a cabo sus trabajos. ¿Cómo desglosa las operaciones comerciales en su máxima expresión para permitirte entenderlas mejor?

Cuando comprenda el principio básico de que algún objeto se compone simplemente de objetos más pequeños, estará en camino a crear células o moléculas altamente reutilizables.

0

Las clases me han sido de gran ayuda en el aspecto de que puedo trabajar en un pequeño aspecto de un proyecto complejo a la vez. Ser capaz de desacoplar un aspecto del código del gran proyecto es muy útil para que no te sientas abrumado. Al final, la cohesión entre esas clases puede darle una visión general rápida de cómo funciona un programa sin tener que lidiar con las entrañas.

En lo que se refiere al mantenimiento, es mucho más fácil ver un diagrama de clase UML y averiguar cómo se presenta todo que mirar una lista de funciones, en mi opinión.

0

Creo que al decir clases, debe significar objetos. Las clases no son más que un lugar donde puedes poner tus objetos. El paradigma de OOP es tan exitoso por una razón. Una vez que tienes ese 'aha!' momento en que piensas que finalmente has entendido el concepto de OOP, puedes comenzar a programar de una manera mucho más organizada.

He programado en Visual Basic 3 durante mucho tiempo, así que tenía mucha experiencia con la programación funcional, luego ir a VB5 y descubrir objetos fue un gran alivio porque podía relacionar entidades del mundo real en mi código , y ayudó mucho.

Esa es toda la razón, recreando entidades del mundo real en su código. Hace que la lectura y el trabajo sean más fáciles porque puedes recoger algo y hacer cosas con él o hacer cosas.

1

Probablemente sea posible sobreescribir un problema simple haciendo que sea innecesariamente complejo (OO hasta abajo). Sin embargo, para cualquier problema suficientemente grande, no creo que sea probable que el paradigma OO sea lo que causó que sea grande en primer lugar. Tomemos un sistema operativo, por ejemplo, es difícil imaginar que sea fácil de mantener (en cuanto al código) si no está escrito de una manera orientada a objetos.

1

Si tiene muchas funciones "simples" en una aplicación grande, es difícil hacer cambios en esas funciones.

  • más difícil de ver quién está utilizando la función ("si cambio de esto, ¿quién afecta?")
  • difícil de realizar cambios en las funciones sin romper el código de otras personas.

Si completa las funciones en las clases, ayuda a aislar el alcance del código. No es una bala mágica, pero ayuda.

Cuestiones relacionadas