oop - ejemplos - programacion orientada a objetos youtube
¿Cómo enseñar programación orientada a objetos a programadores de procedimientos? (19)
Aprendí sobre OOP durante mi educación postsecundaria. Hicieron un buen trabajo explicando los conceptos, pero fallaron por completo al explicar por qué y cuándo. La forma en que enseñaron OOP fue que absolutamente todo tenía que ser un objeto y la programación de procedimientos era malvada por alguna razón. Los ejemplos que nos estaban dando parecían exagerados, en parte porque los objetos no parecían ser la solución correcta para cada problema, y en parte porque parecía una sobrecarga innecesaria. Me hizo despreciar a OOP.
En los años transcurridos desde entonces, cada vez me gusta más OOP en situaciones en las que tiene sentido para mí. El mejor ejemplo que puedo pensar de esto es la aplicación web más reciente que escribí. Inicialmente ejecuté una base de datos única, pero durante el desarrollo decidí conectarlo a otra base de datos para importar información sobre nuevos usuarios, de modo que pudiera hacer que la aplicación los configurara automáticamente (ingrese el ID de empleado, recupere el nombre y el departamento) . Cada base de datos tenía una colección de funciones que recuperaban datos, y dependían de una conexión de base de datos. Además, quería una distinción obvia a qué base de datos pertenecía una función. Para mí, tiene sentido crear un objeto para cada base de datos. Los constructores hicieron el trabajo preliminar de configurar las conexiones.
Dentro de cada objeto, las cosas son prácticamente procedurales. Por ejemplo, cada clase tiene una función llamada getEmployeeName () que devuelve una cadena. En este punto, no veo la necesidad de crear un objeto Employee y recuperar el nombre como una propiedad. Un objeto podría tener más sentido si tuviera que recuperar varios datos sobre un empleado, pero para la cantidad pequeña de cosas que necesitaba, no parecía valer la pena.
Se me ha pedido que comience a enseñar conceptos de C # y OO a un grupo de programadores de procedimientos. He buscado ideas sobre dónde comenzar, pero estoy buscando un consenso general sobre los temas a seguir, además de temas para evitar inicialmente.
Editar
Tengo la intención de presentar la información en cuotas de 30 minutos cada semana hasta que ya no tenga sentido. Estas presentaciones están dirigidas a compañeros de trabajo en una variedad de niveles de habilidad desde principiante hasta experto.
Costo. Explique cómo, cuando se usa adecuadamente, las características del lenguaje deben permitir que el software se escriba y se mantenga por un costo menor. (por ejemplo, Foo.getBar () de Java en lugar de la barra foo-> tantas veces vista en el código C / C ++).
De lo contrario, ¿por qué lo hacemos?
Cuando pasé de orientado a procedimientos a orientado a objetos, lo primero que hice fue familiarizarme con el alcance estático.
Java es un buen lenguaje para comenzar a hacer OO porque intenta mantenerse fiel a todos los diferentes paradigmas de OO.
Un programador de procedimientos buscará cosas como puntos de entrada y salida del programa y, una vez que puedan conceptualizar que el alcance estático en una clase desechable es lo más familiar para ellos, el conocimiento florecerá a partir de ahí.
Recuerdo el momento de la bombilla bastante vívidamente. Ayúdelos a comprender los términos clave abstract, instance, static, methods y probablemente les dé las herramientas para aprender a avanzar mejor.
Defina primero un objeto, sin usar un animal tonto, forma, ejemplo de vehículo, pero con algo que ya saben. La biblioteca C stdio y la estructura FILE
. Se usa como una estructura de datos opaca con funciones definidas. Asigna eso desde un uso de procedimiento a un uso de OO e ir de allí a encapsulación, polimorfismo, etc.
El libro Conceptos, técnicas y modelos de Programación de computadoras me resultó muy útil para comprender y darme un vocabulario para analizar las diferencias en los paradigmas del lenguaje. El libro realmente no cubre Java o C # como 00 idiomas, sino los conceptos de diferentes paradigmas. Si estuviera enseñando OO, comenzaría por mostrar las diferencias en los paradigmas, luego, lentamente, las diferencias en los 00 idiomas, las cosas prácticas que pueden recoger por sí mismos haciendo trabajos de curso / proyectos.
El salto de procedimental a orientado a objetos (incluso dentro de un lenguaje, durante cuatro meses programé C ++ procedural, y las clases fueron incómodas por un tiempo después) puede aliviarse si se enfatizan los conceptos más básicos que la gente no enfatiza.
Por ejemplo, cuando aprendí OOP por primera vez, ninguno de los libros enfatizaba que cada objeto tiene su propio conjunto de miembros de datos. Estaba intentando escribir clases para la validación de entradas y cosas por el estilo, sin entender que las clases debían operar en miembros de datos, no en entradas.
Comience con las estructuras de datos de inmediato. Hacen que el paradigma de OOP parezca útil. La gente te enseña cómo hacer una clase de "Casa", pero como la mayoría de los programadores principiantes quieren hacer algo útil de inmediato, parece un desvío inútil.
Evita el polimorfismo de inmediato. La herencia está bien, pero enseñe cuando sea apropiado (en lugar de simplemente agregar a su clase base).
La sobrecarga del operador no es esencial cuando está aprendiendo por primera vez, y los administradores especiales (predeterminado, dtor, copiador y operador de asignación tienen todos sus aspectos complicados, y es posible que desee evitar eso hasta que se basen en el diseño de clase básico).
Pídales que construyan una Pila o una Lista Vinculada. No hagas nada donde el recorrido sea complicado, como un árbol binario.
Estoy un poco sorprendido de que haya programadores puramente procesales a la izquierda ;-)
Pero, como alguien que comenzó a codificar a principios de los 80 en lenguajes de procedimiento como COBOL, C y FORTRAN, recuerdo que lo que más me afectó fue la creación de instancias. El concepto de un objeto en sí mismo no era tan difícil ya que básicamente son ''estructuras con métodos adjuntos'' (miradas desde una perspectiva de procedimiento) pero manejando cómo y cuándo instanciaba un objeto - y en aquellos días sin recolección de basura - las destruía yo algunos problemas
Creo que esto surge porque, de algún modo, un programador de procedimientos generalmente puede señalar cualquier variable en su código y decir que es donde está almacenado ese elemento de datos directamente, mientras que tan pronto como crea una instancia de un objeto y asigna valores a eso, es mucho menos tangible (el uso de punteros y asignación de memoria en C es, por supuesto, similar, lo que puede ser un punto de partida útil también si sus alumnos tienen experiencia en C). En esencia, supongo que significa que su programador de procedimientos -> OOPS tiene que aprender a manejar otro nivel de abstracción en su código, y sentirse cómodo con este paso mental es más difícil de lo que parece. Por extensión, me aseguraré de que sus estudiantes se sientan completamente cómodos asignando y manejando objetos antes de ver conceptos potencialmente confusos como métodos estáticos.
Evitaría el enfoque "una bicicleta es una especie de veichle" y trataré de aplicar OO a un entorno que es bastante específico y al que ya están acostumbrados. Intenta encontrar un dominio de problemas que todos reconozcan.
Ejercita los conceptos básicos en ese dominio, pero trata de avanzar hacia un "¡guau!" o "¡Ajá!" experiencia relativamente temprana; Tuve una experiencia como esa al leer sobre " Reemplazar condicionalmente con polimorfismo " en Fowlers Refactoring , que libros similares pueden ser una buena fuente de ideas. Si no recuerdo mal, Michael Feathers Trabajar eficazmente con el código heredado contiene un capítulo sobre cómo transformar un programa de procedimiento en OO.
Hazlo por etapas.
Conceptos de alto nivel: describe qué es un objeto y lo relaciona con la vida real.
Conceptos de nivel medio: ahora que obtuvieron el objeto, intente comparar y contrastar. Muéstreles por qué la variable global es mala en comparación con un valor encapsulado en una clase. Qué ventaja pueden obtener de encapsular. Comience a presentar los tennets de OOP (encapsulación, herencia)
Conceptos de bajo nivel: profundiza en el polimorfismo y la abstracción. Muéstreles cómo pueden obtener un diseño aún mejor a través del polimorfismo y la abstracción.
Conceptos avanzados: SÓLIDO, programación de interfaz, patrones de diseño OO.
Lo mejor que puedes hacer es: ten un montón de preguntas y respuestas .
El artículo de programación procesal (PP) de Wikipedia realmente impacta donde debería comenzar:
Mientras que la programación de procedimientos usa procedimientos para operar en estructuras de datos, la programación orientada a objetos los agrupa para que un "objeto" opere en su propia estructura de datos.
Una vez que esto se entienda, creo que mucho encajará en su lugar.
En general
OOP es una de esas cosas que puede tomar tiempo para "obtener", y cada persona toma su propio camino para llegar allí. Al escribir en C #, no es como si el código gritara " ¡Estoy usando los principios de OO! " En cada línea. Es algo más sutil, como un bucle foreach
o string
concatenación de string
.
Centro de Diseño
Siempre use algo (repetidamente) antes de hacerlo .
Primero, use un objeto y demuestre las diferencias básicas de PP. Me gusta:
static void Main(string[] args)
{
List<int> myList = new List<int>();
myList.Add(1);
myList.Add(7);
myList.Add(5);
myList.Sort();
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
}
Usar objetos (y otras cosas OO) primero, antes de forzarlos a crear los suyos, lleva a la gente por el camino de "Ok, estoy haciendo algo como lo que acabo de usar", en lugar de "WTF, ¿estoy escribiendo? "
Herencia (es una trampa!)
NO gastaría mucho tiempo en la herencia. Creo que es un escollo común para las lecciones hacer una gran cosa al respecto (por lo general, hacer una jerarquía de animales cliché, como otros señalaron). Creo que es fundamental saber acerca de la herencia, para entender cómo usar .NET Framework, pero sus matices no son tan importantes.
Cuando estoy usando .NET, es más probable que me "encuentre con la herencia" cuando estoy usando .NET Framework (es decir, "¿Este control tiene una propiedad de Content
?" O "Simplemente llamaré su ToString()
método ") en lugar de cuando estoy creando mi propia clase. Muy (muy (muy)) rara vez siento la necesidad de hacer algo que imite la estructura taxonómica del reino animal.
Interfaces
Codificar a una interfaz es un concepto clave de nivel medio. Se usa en todas partes, y OOP lo hace más fácil. Ejemplos de esto son ilimitados. Construyendo el ejemplo que he mencionado anteriormente, uno podría demostrar la IComparer<int>
:
public int Compare(int x, int y)
{
return y.CompareTo(x);
}
Luego, myList.Sort(this)
para cambiar el orden de clasificación de la lista, a través de myList.Sort(this)
. (Después de hablar de this
, por supuesto)
Mejores prácticas
Dado que hay algunos desarrolladores experimentados en el grupo, una estrategia en las clases de nivel medio sería mostrar cómo funcionan las mejores prácticas en C #. Me gusta, ocultar información, el patrón del observador , etc.
Ten un montón de preguntas y respuestas
De nuevo, todos aprenden de forma ligeramente diferente. Creo que lo mejor que puedes hacer es tener un montón de preguntas y respuestas y animar a otros en el grupo a tener una discusión. En general, las personas aprenden más cuando están involucradas, y usted tiene una buena situación donde eso debería ser más fácil.
Lo que hizo que haga clic para mí fue la introducción de Refactoring y Unit Testing. La mayor parte de mi carrera de programación profesional ha sido en OO Languages, pero pasé la mayor parte escribiendo código de procedimiento. Usted llama a una función en una instancia de la clase X, y llamó a un método diferente en una instancia de la clase Y. No vi cuál era el problema con las interfaces, y pensé que la herencia era simplemente un concepto de conveniencia, y las clases fueron, en general, una forma de ayudarnos a clasificar y categorizar el código masivo. Si uno fuera lo suficientemente masoquista, podrían haber reparado fácilmente algunos de mis proyectos anteriores y poner en línea todo hasta llegar a una clase masiva. Todavía estoy muy avergonzado de lo malo que era mi código, de lo ingenua que era mi arquitectura.
Hizo clic a medias cuando revisamos el libro de refactorización de Martin Fowler, y luego hicimos clic completo cuando comenzamos a escribir pruebas de Unidad y Fitnesse para nuestro código, lo que nos obligó a refactorizar. Comience a presionar la refactorización, la inyección de dependencia y la separación del código en distintos modelos de MVC. O se hundirá, o sus cabezas explotarán.
Si alguien realmente no lo entiende, tal vez no estén desconectados por trabajar en OO, pero no creo que nadie de nuestro equipo se haya perdido por completo, así que con suerte tendrás la misma suerte.
Primero, elija un idioma como C # o Java y tenga muchas muestras para demostrar. Siempre demuéstreles el panorama general o la gran idea antes de entrar en los detalles más finos de los conceptos OO, como la abstracción o la encapsulación. Prepárese para responder muchas preguntas sobre por qué con suficientes ejemplos del mundo real.
Recomiendo echar un vistazo a los patrones de diseño de Head First que tienen ejemplos realmente agradables y fáciles de entender de diseño orientado a objetos que realmente deberían ayudar. Sin embargo, no enfatizaría mucho el aspecto de los "patrones" en este momento.
Si son buenos programadores de procedimientos y saben lo que es una estructura y un indicador de una función, ¡la parte más difícil del trabajo ya está hecha!
Creo que una conferencia de bajo nivel acerca de cómo la Programación Orientada a Objetos se puede implementar en lenguajes de procedimiento, o incluso ensamblador, podría ser genial. Luego apreciarán la cantidad de trabajo que el compilador hace por ellos; y tal vez encuentren patrones de codificación que ya conocían y habían usado previamente.
Luego, puede hablar sobre las mejores prácticas en un buen diseño orientado a objetos e introducir un poco de UML.
Y una cosa muy importante a tener en cuenta siempre es que no son estudiantes de primer año, no pasan mucho tiempo con cosas básicas porque se aburrirán.
Soy un desarrollador de OO profesionalmente, pero he tenido desarrolladores de procedimientos en mi equipo de desarrollo (estaban desarrollando el código de Matlab, por lo que funcionó). Uno de los conceptos que me gusta de la programación OO es cómo los objetos se pueden relacionar con su dominio ( http://en.wikipedia.org/wiki/Domain-driven_design ) Eric Evans escribió un libro sobre esto, pero no es un libro para principiantes por cualquier estiramiento).
Dicho esto, comenzaría mostrando conceptos de OO a un alto nivel. Intente que diseñen un automóvil, por ejemplo. La mayoría de las personas diría que un carro tiene cuerpo, motor, ruedas, etc. Explique cómo se pueden relacionar con los objetos del mundo real.
Una vez que parezcan captar ese concepto de alto nivel, comenzaría con la parte del código real y conceptos como herencia versus agregación, polimorfismo, etc.
Soy un programador intermedio de vb.net y estoy aprendiendo OOP. Una de las cosas que encuentro es que las conferencias sobre los conceptos una y otra vez son enervantes. Creo que la documentación perfecta sería una transición gradual de la programación de procedimientos a la OOP completa en lugar de tratar de obligarlos a comprender los conceptos y hacer que escriban código OOP exclusivamente utilizando todos los conceptos. De esa forma pueden jugar pequeños proyectos como "hola mundo" sin la intimidación del diseño.
Por ejemplo (esto es para principiantes de VB.NET no programadores de procedimientos avanzados).
Creo que los primeros capítulos siempre deben referirse a los conceptos generales, con solo algunos ejemplos, pero no debe forzarlos a codificar estrictamente OOP de inmediato, acostumbrarlos al idioma, para que sea natural para ellos. Cuando comencé, tenía que volver y leer el manual una y otra vez para recordar CÓMO escribir el código, pero tuve que pasar páginas y páginas de conferencias sobre conceptos. ¡Doloroso! Solo necesito recordar cómo crear una propiedad ReadOnly, o algo. Lo que sería realmente útil sería una sección del libro que sea una referencia de idioma para que pueda buscar allí cómo CÓMO escribir el código.
Luego, explica brevemente cómo las formas y todos los objetos ya son objetos que tienen métodos y cómo se comportan, y el código de ejemplo.
Luego, muéstreles cómo crear una clase y pídales que creen una clase que tenga propiedades, métodos y la nueva construcción. Luego pídales que cambien básicamente de ellos utilizando el código de procedimiento en forma o módulos, a los métodos de escritura para las clases.
Luego simplemente introduce más códigos anticipados como lo haría con cualquier lenguaje de programación. Muéstreles cómo funciona la herencia, etc. Simplemente siga expandiéndose, y permítales usar su creatividad para descubrir qué se puede hacer.
Después de acostumbrarse a escribir y usar clases, muestre cómo podrían mejorar sus clases, presentando los conceptos uno por uno en el código, modificando los proyectos existentes y mejorándolos. Una buena idea es tomar un ejemplo de proyecto en código de procedimiento y transformarlo en una mejor aplicación en OOP mostrándoles todas las limitaciones de OOP.
Ahora, después de eso, está la parte avanzada en la que se introducen algunos conceptos de POO realmente avanzados, de modo que las personas que están familiarizadas con OOP ya obtienen algún valor del libro.
Tal vez debería considerar un problema que está relacionado con el trabajo y comenzar con una implementación de procedimiento del mismo y luego trabajar (sesión por sesión) cómo hacer una implementación de OOP del mismo. Encuentro que los profesionales a menudo captan mejor los conceptos si están directamente relacionados con ejemplos reales de su propio lugar de trabajo. Los ejemplos de basura que la mayoría de los libros de texto usan son a menudo horribles de entender porque dejan al estudiante preguntándose, ¿por qué diablos querría hacer eso? Bríndeles una razón de la vida real por la que querrían hacer eso y tiene más sentido.
Enseñar refactorización
Enseñe lo básico, el mínimo básico de los principios de OO, luego enseñe Refactoring manos.
Forma tradicional: abstracciones> Jerga de la jerga> Implementación trivial> Uso práctico (¿Puedes ver la desconexión aquí? Una de estas transiciones es más difícil que las otras).
En mi experiencia, la mayoría de la educación tradicional no hace un buen trabajo para lograr que los programadores comprendan realmente los principios OO. En su lugar, aprenden un poco de la sintaxis, alguna jerga con la que tienen una vaga comprensión, y un par de ejemplos de diseño canónico que sirven como plantillas para mucho de lo que hacen. Estos son años luz del tipo de comprensión profunda del diseño e ingeniería de OO que uno desearía que obtuvieran estudiantes competentes. El resultado suele ser que el código se descompone en grandes fragmentos en lo que mejor se puede describir como bibliotecas de objetos, y el código está nominalmente unido a objetos y clases, pero está muy lejos de ser óptimo. Es muy común, por ejemplo, ver varios cientos de métodos de línea, que no son muy OO en absoluto.
Proporcione contraste para agudizar el enfoque en el valor de OO
Enseñe a los alumnos proporcionándoles las herramientas iniciales para mejorar el diseño OO del código existente, a través de la refactorización. Tome una gran cantidad de código de procedimiento, use el método de extracción un montón de veces con nombres de método significativos, determine grupos de métodos que comparten algo en común y transfiéralos a su propia clase. Reemplace el interruptor / cajas con polimorfismo. Etc. Las ventajas de esto son muchas. Le da a los estudiantes la experiencia de leer y trabajar con el código existente, una habilidad clave. Proporciona una comprensión más completa de los detalles y las ventajas del diseño OO. Es difícil apreciar los méritos de un patrón de diseño de OO particular en el vacío, pero compararlo con un estilo más procedimental o un diseño de OO más torpe pone a esos méritos en agudo contraste.
Desarrollar conocimiento a través de modelos mentales y terminología expresiva
El lenguaje y la terminología de la refactorización ayudan a los estudiantes a comprender el diseño de OO, cómo juzgar la calidad de los diseños de OO y las implementaciones a través de la idea de olores de códigos. También proporciona a los estudiantes un marco con el cual discutir los conceptos OO con sus compañeros. Sin los modelos y la terminología de, por ejemplo, una transmisión de automóvil, los mecánicos tendrían dificultades para comunicarse entre sí y comprender los automóviles. Lo mismo se aplica al diseño OO e ingeniería de software. Refactoring proporciona abundante terminología y modelos mentales (patrones de diseño, olores de códigos y refactorizaciones específicas preferidas correspondientes, etc.) para los componentes y las técnicas de ingeniería de software.
Construye una ética de la artesanía
Al enseñar a los alumnos que el diseño no es inamovible, refuerza la confianza de los alumnos en su capacidad de experimentar, aprender y descubrir. Al ensuciarse las manos se sentirán más capacitados para abordar los problemas de ingeniería del software. Esta confianza y habilidad práctica les permitirá verdaderamente ser dueños del diseño de su trabajo (porque siempre tendrán las habilidades y la experiencia para cambiar ese diseño, si así lo desean). Esta propiedad ayudará a fomentar un sentido de responsabilidad, orgullo y artesanía.
Mostrar patrones de diseño en ejemplos
Allí donde hay muchas buenas respuestas, está bien. También creo que debes usar buenos lenguajes, buenos ejemplos hábiles, pero tengo una sugerencia adicional:
Aprendí lo que significa POO, estudiando Patrones de diseño. Por supuesto, por supuesto, aprendí un lenguaje OO antes, pero hasta que estaba trabajando en Patrones de diseño, no entendía el poder de todo.
También aprendí mucho de OO-Gurus como Robert C. Martin y sus documentos realmente geniales (que se encuentran en el sitio de su compañía).
Editar: También defiendo el uso de UML (diagramas de clases) para enseñar OO / Design-Pattern.