2010-03-26 6 views
11

Tal vez sea porque he estado programando alrededor de dos semestres ahora, pero el mayor obstáculo que estoy teniendo en este momento es convertir la descripción del proyecto del profesor y los requisitos en el código real. Como actualmente estoy en Algorithms 101, básicamente hago un proceso de abajo hacia arriba, comenzando con una pizarra en blanco y dibujo las interacciones de objetos y métodos, luego las traduzco en clases y códigos.¿Cómo se pasa de una descripción de proyecto abstracta a un código real?

Pero ahora el prof ha lanzado interfaces y clases abstractas en la mezcla. Intelectualmente, puedo reconocer cómo funcionan, pero me estoy golpeando los pies tratando de descubrir cómo usar estas nuevas herramientas con el proyecto actual (simulando un servidor web).

En mis propias palabras de los profesores, mapear la descripción abstracta al código de Java es el verdadero truco. Entonces, ¿qué pasos se usan mejor para pasar del inglés (o cualquiera que sea su idioma) al código de computadora? ¿Cómo decide dónde y cuándo crear una interfaz, o utiliza una clase abstracta?

Respuesta

6

¿Qué pasos son los más adecuados para pasar de inglés (o lo que sea que sea su idioma) a código de computadora?

La experiencia es lo que te enseña a hacer esto. Si no viene naturalmente todavía (! Y no se sienta mal si no lo hace, porque se tarda mucho tiempo), hay algunas preguntas que usted puede preguntarse:

  • ¿Cuáles son los principales conceptos de ¿el sistema? ¿Cómo es que están relacionados? Si le estuviera describiendo esto a alguien más, ¿qué palabras y frases usaría? Estos pensamientos lo ayudarán a decidir qué clases son útiles para pensar.

  • ¿Qué tipo de comportamientos tienen estas cosas? ¿Existen dependencias naturales entre ellos? (Por ejemplo, LineItem no es relevante o significativo sin el contexto de Order, ni tampoco es Engine mucho uso sin Car). ¿Cómo afectan los comportamientos el estado de los otros objetos? ¿Se comunican entre sí y, de ser así, de qué manera? Estos pensamientos te ayudarán a desarrollar las interfaces públicas de tus clases.

Eso es solo la punta del iceberg, por supuesto. Para obtener más información sobre este proceso de pensamiento en general, consulte el excelente libro de Eric Evans, Domain-Driven Design.

¿Cómo decide dónde y cuándo crear una interfaz, o utiliza una clase abstracta?

No hay recetas difíciles y rápidas; Nuevamente, la experiencia es la mejor guía aquí. Dicho esto, no hay duda, algunas reglas básicas que puede seguir:

  • Si varios tipos de objetos no relacionados o significativamente diferentes todos ofrecen el mismo tipo de funcionalidad, utilizar una interfaz. Por ejemplo, si la interfaz Steerable tiene un método Steer(Vector bearing), puede haber muchas cosas diferentes que se pueden controlar: Boat s, Airplane s, CargoShip s, Car s, y más. Estas son cosas completamente sin relación. Pero todos comparten la interfaz común de poder ser dirigidos.

  • En general, intente favorecer una interfaz en lugar de una clase base abstracta. De esta forma, puede definir una única implementación que implemente N interfaces. En el caso de Java, solo puede tener una clase base abstracta, por lo que está bloqueado en una jerarquía de herencia particular una vez que dice que una clase hereda de otra.

  • Siempre que no necesite implementación desde una clase base, definitivamente preferiría una interfaz sobre una clase base abstracta. Esto también sería útil si está operando en un idioma donde la herencia no se aplica. Por ejemplo, en C#, no puede tener un struct heredado de una clase base.

+0

Sé que no hay una respuesta perfecta para esta pregunta, pero gracias por darme la mayor cantidad de ideas para pensar. – Jason

3

En general ...

  1. leído un montón de código de otras personas. Los proyectos de código abierto son geniales para eso. Respete sus licencias sin embargo.
  2. Nunca lo conseguirás perfecto. Es un proceso iterativo. No se desanime si no lo hace bien.
  3. Práctica. Práctica. Práctica.
  4. Investigar a menudo. Siga abordando proyectos/diseños cada vez más desafiantes. Incluso si hay otros fáciles.

No hay una bala mágica o algoritmo para un buen diseño.

Hoy en día salta con un diseño que creo que es decente y trabajo desde eso.

Cuando llegue el momento, implementaré la comprensión de que el resultado tendrá que refactorizarse (reescribirse) más pronto que tarde.

Dale a este proyecto tu mejor oportunidad, mantente atento a tus errores y cómo deberían haberte hecho las cosas una vez que recuperes los resultados.

Sigue haciendo esto y estarás bien.

3

Lo que realmente debe hacer es code from the top-down, not from the bottom-up. Escriba su función principal de la forma más clara y concisa que pueda utilizando API que aún no haya creado como si ya existieran. Luego, puede implementar esas API de manera similar, hasta que tenga funciones de solo unas pocas líneas. Si codifica de abajo hacia arriba, probablemente creará un montón de cosas que realmente no necesita.

En términos de cuándo crear una interfaz ... casi todo debería ser una interfaz. Cuando utiliza API que aún no existen, suponga que cada clase concreta es una implementación de alguna interfaz y usa un tipo declarado que es indicativo de esa interfaz. Su herencia debe hacerse únicamente con interfaces. Solo cree clases concretas en el fondo cuando esté proporcionando una implementación. Sugeriría evitar las clases abstractas y simplemente usar la delegación, aunque las clases abstractas también son razonables cuando dos implementaciones diferentes difieren solo ligeramente y tienen varias funciones que tienen una implementación común. Por ejemplo, si su interfaz le permite a uno iterar sobre elementos y también proporciona una función de suma, la función suma es una implementación trivial en términos de la función de iteración, por lo que sería un uso razonable de una clase abstracta. Una alternativa sería usar el patrón de decorador en ese caso.

También puede encontrar la Google Techtalk "How to Design a Good API and Why it Matters" para ser útil a este respecto. También podría estar interesado en leer algunos de mis propios software design observations.

0

Además, para el futuro próximo, puede seguir en línea para leer los conceptos básicos en domain driven design para alinearse con los escenarios del mundo real: proporciona una base sólida para la asignación de requisitos a las clases reales.

Cuestiones relacionadas