Sistema de reserva de películas
Revisar los requisitos
- Se pretende implementar un sistema de reserva de películas en línea.
- La película representa la información básica sobre la película.
- Título, duración de la proyección, información de precios, etc.
- La proyección representa el evento real en el que la audiencia ve la película.
- Fecha de proyección, hora, número de orden, etc.
- Las personas reservan películas, pero en realidad deberían reservar una película que se esté proyectandopara ser precisos.
- Condiciones de descuento
- Disponibilidad de descuento en el precio
- Condición de orden: utilizar el número de orden de proyección para determinar la disponibilidad del descuento
- Condición de período: utilizar la hora de inicio de la proyección de la película para determinar la disponibilidad del descuento
- Política de descuentos
- Determinar la tarifa de descuento
- Política de descuento en cantidad: descuento de una cierta cantidad en la tarifa de reserva
- Política de descuento porcentual: descuento de un cierto porcentaje de la tarifa regular
- Se puede asignar una política de descuento a cada película o no asignarla, y se pueden mezclar varias condiciones de descuento.
- Si se aplica una política de descuento pero no se cumplen las condiciones de descuento, o si no se aplica una política de descuento, la tarifa no se descuenta.
Hacia la programación orientada a objetos
Colaboración, objeto, clase
- La orientación a objetos se centra en los objetos.
- No debe pensarse en qué atributos y métodos son necesarios para una clase después de decidir la clase.
- Se debe determinar qué objetos tienen qué estado y comportamiento.
- Los objetos deben verse no como entidades independientes, sino como miembros de una comunidad que colabora.
Estructura del programa que sigue la estructura del dominio
- El dominio se refiere al área en la que el usuario utiliza el programa para resolver un problema.
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fe7d22a03-4a24-40e9-8068-bd03b9fd816b%2FUntitled.png?table=block&id=3f1931fc-8ef9-470a-8189-3727146638f6&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/438;" width="2000" height="438"></span>
- En general, el nombre de la clase debe ser el mismo o al menos similar al nombre del concepto de dominio correspondiente.
- La relación entre las clases también debe hacerse lo más similar posible a la relación establecida entre los conceptos de dominio para que la estructura del programa sea fácil de entender y predecir.
Implementar la clase
- La clase se divide en interior y exterior, y para diseñar una buena clase, se debe decidir qué parte se mostrará al exterior y qué parte se ocultará.
- Los atributos del objeto se bloquean como privados y los métodos necesarios para cambiar el estado interno se abren como públicos.
- La distinción entre el interior y el exterior de la clase proporciona al programador la libertad de implementación al garantizar la autonomía del objeto.
Objeto autónomo
- El objeto debe ser un objeto autónomo con estado y comportamiento.
- El agrupamiento de datos y funciones dentro del objeto se denomina encapsulación.
- El control de acceso reduce la interferencia externa, lo que permite que el objeto decida su propio comportamiento.
- El principio de separación de interfaz e implementación es un principio clave que debe seguirse para la programación orientada a objetos.
- Interfaz pública: parte accesible desde el exterior
- Implementación: parte accesible solo desde el interior
Libertad del programador
- El papel del programador se divide en el programador de clases y el programador cliente.
- El programador de clases agrega un nuevo tipo de datos
- El programador cliente utiliza el tipo de datos agregado por el programador de clases
- Ocultar la implementación
- El programador de clases puede ocultar la implementación interna proporcionando solo las partes necesarias al programador cliente.
- El programador cliente solo necesita conocer la interfaz, por lo que puede reducir la cantidad de conocimiento.
Comunidad de objetos que colaboran
- Al expresar dinero, es mejor empaquetarlo como un objeto, como Money, en lugar de simplemente declarar una variable de tipo Long. El uso de objetos mejora la comunicación del significado y permite que el procesamiento de operaciones redundantes se realice en un solo lugar.
- La interacción entre objetos para implementar una función del sistema se denomina colaboración.
Una breve historia sobre la colaboración
- La única forma en que un objeto puede interactuar con otro objeto es enviando o recibiendo mensajes.
- Su propio método para procesar el mensaje recibido se denomina método.
- Es importante distinguir entre mensajes y métodos, y aquí es donde comienza el concepto de polimorfismo.
Obtener la tarifa de descuento
Comenzar la colaboración para calcular la tarifa de descuento
- La clase Movie no contiene la lógica detallada relacionada con la política de descuentos y la ha delegado a la interfaz DiscountPolicy. Es realmente importante utilizar la herencia, el polimorfismo y la abstracción.
Política de descuentos y condiciones de descuento
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7b9b27a5-0dac-4ba7-9552-05b7f8fbdecd%2FUntitled.png?table=block&id=3264f189-6e12-4a55-94d2-75b851320c7a&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/535;" width="2000" height="535"></span>
Herencia y polimorfismo
Dependencia en tiempo de compilación y dependencia en tiempo de ejecución
- La dependencia del código y la dependencia del momento de ejecución pueden ser diferentes.
- Cuanto más diferentes sean las dependencias entre los dos, más difícil será comprender el código, pero el código será más flexible y ampliable.
Programación por diferencia
- La herencia permite agregar nuevas clases de forma rápida y sencilla basándose en clases existentes y reutilizar la implementación de la clase principal.
- El método de crear una nueva clase agregando solo las partes diferentes de la clase principal se denomina programación por diferencia.
Herencia e interfaz
- La herencia hace que la clase hija herede todas las interfaces proporcionadas por la clase principal.
- La interfaz define una lista de mensajes que un objeto puede entender.
- Movie envía un mensaje calculateDiscountAmount a DiscountPolicy. Desde el punto de vista de Movie, no importa qué instancia de clase responde, solo importa que responda con éxito.
- Por lo tanto, tanto AmountDiscountPolicy como PercentDiscountPolicy pueden colaborar con Movie en lugar de DiscountPolicy.
- Este tipo de sustitución de la clase hija por la clase principal se denomina conversión ascendente. Esto se debe a que parece que la clase hija se convierte automáticamente al tipo de la clase principal que está en una posición superior.
Polimorfismo
- El polimorfismo es la capacidad de responder de manera diferente según el tipo de objeto cuando se recibe el mismo mensaje.
- Movie envía el mismo mensaje, pero qué método se ejecutará realmente depende de qué clase es el objeto que recibe el mensaje.
- El polimorfismo se basa en el hecho de que la dependencia en tiempo de compilación y la dependencia en tiempo de ejecución de un programa pueden ser diferentes.
- Dado que el polimorfismo determina el método a ejecutar en tiempo de ejecución, se denomina enlace diferido o enlace dinámico.
Interfaz y polimorfismo
- Si solo desea compartir la interfaz y no necesita compartir la implementación, puede usar una interfaz en lugar de una clase abstracta.
Abstracción y flexibilidad
El poder de la abstracción
- Ventajas de la abstracción
- Si solo observa la jerarquía de abstracción, puede describir la política de requisitos a alto nivel.
- El diseño se vuelve más flexible.
Diseño flexible
- La abstracción evita que el diseño se una a situaciones específicas, por lo que puede crear un diseño flexible.
Compromiso entre clase abstracta e interfaz
- Actualmente, NoneDiscountPolicy no tiene ningún problema porque el método calculateDiscountAmount() de DiscountPolicy devuelve 0 si no hay ninguna condición de descuento. Sin embargo, desde el punto de vista del usuario, debe proporcionar una política None sin ninguna política de descuento como argumento para Movie, por lo que se ha añadido.
- Por lo tanto, la clase NoneDiscountPolicy es confusa conceptualmente, por lo que es mejor modificarla como se muestra a continuación para que sea más fácil de entender.
- Como se muestra arriba, se abstrae DiscountPolicy como una interfaz y se divide en NoneDiscountPolicy, que es su implementación, y DefaultDiscountPolicy, que representa una política de descuento general.
<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F712983a9-3937-4265-82fe-66a144c44a0f%2FUntitled.png?table=block&id=f5ca651c-d03c-4a6c-97e9-7443ee5649a0&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/886;" width="2000" height="886"></span>
- Se puede pensar que agregar una interfaz solo para NoneDiscountPolicy es ineficiente en comparación con el aumento de la complejidad.
- Debe ser consciente de que todo lo relacionado con la implementación puede ser objeto de compromiso y debe diseñar teniendo eso en cuenta. Es decir, todo el código que escribe debe tener una razón justificada.
Reutilización de código
- La herencia se puede utilizar para reutilizar el código.
- Sin embargo, es mejor usar la composición que la herencia para la reutilización de código.
- En el código actual, la forma en que Movie reutiliza el código de DiscountPolicy es a través de la composición.
- Si Movie se considera la clase principal y se divide en AmountDiscountMovie y PercentDiscountMovie, se considera que se utiliza la herencia.
Herencia
- Desventajas de la herencia
- Viola la encapsulación.
- Debe conocer bien la estructura interna de la clase principal.
- Es probable que la clase hija también cambie cuando la clase principal cambie.
- Hace que el diseño sea inflexible.
- Determina la relación entre la clase principal y la clase hija en tiempo de compilación.
- Es imposible cambiar el tipo de objeto en tiempo de ejecución.
- Sin embargo, la composición permite cambiar la instancia en tiempo de ejecución a través de métodos como changeDiscountPolicy() en el lado del objeto que utiliza.
- Viola la encapsulación.
Composición
- El método de reutilizar el código solo a través de los mensajes definidos en la interfaz se denomina composición.
- Puede implementar la encapsulación y mantener un acoplamiento flexible.
- Para el polimorfismo, la herencia y la composición deben utilizarse juntas cuando se reutiliza la interfaz.
- Por ejemplo, la interfaz DiscountPolicy no tiene más remedio que usar la herencia para implementar las subimplementaciones.
Fuente
- Objeto
Comentarios0