¿Algún consejo para resolver el problema this?Diseño orientado a objetos Entrevista
Respuesta
Bueno, aquí hay uno bueno que se me ocurrió - la utilización primordial programación orientada a objetos, subclase y superclase:
namespace Animals{
// base class Animal
class Animal{
public void eat(Food f){
}
}
class Carnivore extends Animal{
public void eat(Meat f){
}
}
class Herbivore extends Animal{
public void eat(Plant f){
}
}
class Omnivore extends Animal{
public void eat(Food f){
}
}
}
namespace Food{
// base class Food
class Food{
}
class Meat extends Food{
}
class Plant extends Food{
}
}
puedo crear subclases herbívoro, carnívoro y omnívoro del animal superclase y reemplazar el método eat
con el tipo de comida que realmente puede comer.
Así:
Plant grass = new Plant();
Herbivore deer = new Herbivore();
deer.eat(grass); // ok
Plant grass2 = new Plant();
Carnivore tiger = new Carnivore();
tiger.eat(grass2); // not ok.
Meat deer2 = new Meat();
tiger.eat(deer2); // ok
Pues bien, el problema final es que, cuando se especifica que es un deer
Herbivore
, no se puede hacer un Meat
para tiger
para comer. Sin embargo, al final del día, esto debería ser suficiente para resolver el problema de la entrevista sin dejar dormido al entrevistador.
Downvoted, porque ha clasificado a un venado como animal en un lugar y como alimento en otro. La misma instancia de ciervo puede ser ambas cosas; el tigre puede atacar al ciervo mientras come sus arbustos pacientemente. –
Sé que ese es un problema que he estado tratando de resolver aquí. Tendré que crear una nueva clase y hacer que Deer pueda ir de 2 maneras. Recuerde: solo downvote si la publicación es completamente inútil y no vale la pena que los demás la vean y probablemente debería tener una mejor respuesta. – mauris
Modelo incorrecto: Si le dan Hierba al Tigre, ella regresará al método 'come()' predeterminado para todos los animales. Debe agregar una función que arroje una excepción (o arroje al cuidador del zoológico) si intenta alimentar a Grass to the Tiger. –
No hay una mejor solución. Es posible que desee hacer de esta una wiki de la comunidad, ya que generalmente es la práctica aceptada para preguntas subjetivas.
Pienso en lo que realmente sería la mejor clase para las jerarquías, y trato de descubrir qué significa "lo mejor" en ese contexto.
Todo lo que hay Cosas, que podría tener un atributo de Nombre. Pero todo lo que hay en algún nivel es comida; si puede comer algo, algo puede comerlo. Podría hacer que Food sea la clase padre, y darle un método que devuelva un valor booleano para verificar si el objeto parámetro puede comer el objeto actual.
Así,
class Food {
boolean canBeEatenBy(Food hungryObject)
String name
}
Eso parece la jerarquía de clases más simple que se ajusta a todo lo que pueda necesitar en un primer paso?
Dicho esto, la parte más importante en la mayoría de las preguntas de la entrevista es la sensación que se tiene para el entrevistado, no tanto la respuesta exacta que dan.
Double dispatch, ¿quizás?
Hay un cartel maravilloso para la Liskov Substitution Principle que dice: "Si se ve como un pato, grazna como un pato, pero necesita baterías, es probable que tenga el abstracción mal." Y esa es la respuesta rápida: algunos de los objetos pueden ser tanto animales como alimentos, por lo tanto, a menos que esté dispuesto a seguir la ruta de la herencia múltiple, entonces el esquema de clasificación es incorrecto.
Una vez que ha superado ese obstáculo, el resto es abierto, y puede incorporar otros principios de diseño. Por ejemplo, podría agregar una interfaz IEdible que permita consumir objetos. Puede ir orientado a los aspectos y agregar decoradores para carnívoros y herbívoros, y eso permitiría el consumo de solo la clase correcta de objetos.
El punto es ser capaz de pensar sobre sus pies, ver y explicar varios aspectos de un problema, y comunicarse bien. Y tal vez no para atascarse en una limitación de "una respuesta correcta".
He aquí algunos pensamientos sobre esta cuestión entrevista:
Estoy de acuerdo con Cylon Gato: (., Incluso si se trata de las interfaces de Java del mismo tipo) Este tipo de abstracción no funciona bien sin la herencia múltiple
lo haría crear dos formas de herencia:
Animal:
- carnívoro
- Su bivore
Alimentación:
- carne
- vegetal
El método de "comer" de los dos tipos de animales (estoy haciendo caso omiso de omnívoros, insectívoros, y muchos otros tipos) estaría especializado en los diferentes tipos de alimentos. Si estamos usando un lenguaje como Java, entonces Food sería una interfaz.
Le diría que se rasque eso. Es una abstracción horrible. Sin mencionar que no tenemos ningún contexto. Las abstracciones no surgen de la nada, o de una "idea" de lo que es "correcto". Muéstreme qué problema está tratando de resolver primero, para que podamos evaluar esta abstracción.
Si no se proporciona ningún contexto, entonces asumiré/compensaré el mío: querrás algunos tipos de objetos para poder comer otros tipos de objetos. Nada más y nada menos.
Hacer una interfaz de Eatable
(o se le puede llamar Food
, si lo desea), y puesto que no tenemos el contexto de lo que nunca, voy a asumir que es un programa de consola juguete, que sólo impresiones:
<X> ate <Y>
, así que todo lo que necesitamos para esta interfaz es un método getFoodName()
.
Para la comprobación de errores, puede crear un grupo de isXFoodType
métodos, por ejemplo, isGrassFoodType()
, isMeatFoodType()
, etc. implementación de Eat(Eatable e)
El Cow
's comprobaría para isGrassFoodType()
, y cuando falla, grabados:
"Cow can't eat " + e.getFoodName()
Alan Kay, quien acuñó el término "programación orientada a objetos", ha dicho "OOP para mí solo significa mensajería, retención y protección local y ocultamiento del proceso de estado, y enlace extremo de todas las cosas".
Tratando de solucionar este "problema" en el modelo de datos me suena a lo contrario de la vinculación tardía: ¿por qué necesita el compilador para hacer cumplir esto? No me preocuparía cambiar el modelo en absoluto. Si le pasan algo que no puede comer, lanza una excepción, ¡como en la vida real, casi!
Cualquier animal es alimento, cualquier vegetal es alimento. Y, de hecho, un tigre puede ser comido por una vaca. (El prurigo lumbar de la enfermedad priónica se transmite al alimentar el tejido neural de las ovejas infectadas con ovejas no infectadas).
Puede tener una jerarquía de especies, ala Linnaeus, tanto animal como vegetal.Cada especie es un Singleton, y tiene un List<Species>
que registra su dieta típica. Elimine la jerarquía de Alimentos por completo, solo confunde las cosas.
Y, si su único problema es registrar la dieta para cada especie, entonces las múltiples clases de Especies son innecesarias. Solo tiene una única clase de Especie con el nombre de la especie como una variable de instancia y el List<Species>
como otro.
Si esperas que el sistema sea muy grande, te sugiero que subclases plantas/carne y herbívoro/carnívoro/omnívoro.
Asegúrese de que el sistema tenga una interfaz estándar para todas las plantas/animales llamada getFoodName() y getFoodType(), puede aplicar esto creando una clase principal para plantas/animales llamada species.
El problema que vería con la planta de subclasificación/carne y carnívoro/herbívoro es que una suricata es carnívora pero es probable que no pueda comer un rinoceronte (puede haber un mejor ejemplo), por lo que se necesitan algunas restricciones " Como carne, comes plantas ".
Si no fuera a ser increíblemente grande y quisieras ser neurótico al respecto, podrías almacenar enumeraciones estáticas de alimentos permitidos para cada subclase de animal. Así que el tigre podría almacenar ciervos, antílopes, etc.
La comida debería ser una interfaz, por lo tanto, las plantas y los animales también podrían ser alimentos.
resumen La clase de animal debe tener el método de comer que tome la comida como parámetro.
subclases de Animal: carnívoro, herbívoro y omnívoro deben tener su propia versión de comer.
Por ejemplo, para Carnivore:
private void eat(Food food)
{
if(food instanceof Animal)
{
happilyEat();
}
else
{
sniff&TurnAway();
}
}
Los problemas resueltos.
Pero para un mejor diseño, Carnivore, Herbivore y Omnivore también deberían ser interfaces, ya que no son la forma correcta de etiquetar a los animales.
Esto es fácil con los genéricos en C# BTW:
public class Food
{
}
public abstract class Animal<T> : Meat where T:Food
{
public abstract void Eat(T food);
}
public class Herbivore : Animal<Plant>
{
public override void Eat(Plant food)
{
Console.WriteLine("Herbivore eats plants.");
}
}
public class Omnivore : Animal<Food>
{
public override void Eat(Food food)
{
Console.WriteLine("Omnivore eats food.");
}
}
public class Carnivore : Animal<Meat>
{
public override void Eat(Meat food)
{
Console.WriteLine("Carnivore eats meat.");
}
}
public class Plant : Food
{
}
public class Meat : Food
{
}
public class Cow : Herbivore
{
}
public class Tiger : Carnivore
{
}
public class Human : Omnivore
{
}
Uso:
var human = new Human();
var tiger = new Tiger();
var cow = new Cow();
var plant = new Plant();
human.Eat(cow);
tiger.Eat(human);
cow.Eat(tiger); // this doesn't compile
tiger.Eat(plant); // neither does this
- 1. Diseño orientado a objetos con Ruby
- 2. Pregunta de diseño orientado a objetos
- 3. Problema de diseño orientado a objetos
- 4. Javascript orientado a objetos
- 5. Diseño orientado a objetos para la aplicación PHP
- 6. pregunta de diseño orientado a objetos para la aplicación gui
- 7. Diseño orientado a objetos para un juego de ajedrez
- 8. Evitar declaraciones if con diseño orientado a objetos, PHP
- 9. Paradigma orientado a objetos Pregunta
- 10. ¿Está Erlang orientado a objetos?
- 11. experimento: orientado a objetos C?
- 12. ¿Está MongoDB orientado a objetos?
- 13. C para un programador orientado a objetos
- 14. ¿Cambió Python a más orientado a objetos?
- 15. Sintaxis del constructor Perl orientado a objetos
- 16. PHP ¿Está orientado a objetos o no?
- 17. ¿C++ es un lenguaje orientado a objetos?
- 18. Suicidio orientado a objetos o eliminar esto;
- 19. Buscando un lenguaje orientado a objetos puros
- 20. Filtrado de Spam Bayesiano Orientado a Objetos?
- 21. usando jQuery en modo orientado a objetos
- 22. C como un lenguaje orientado a objetos
- 23. ¿Cómo está Ruby completamente orientado a objetos?
- 24. ¿Mi código PHP está orientado a objetos?
- 25. ¿Vale la pena convertir mi código JavaScript funcional a un diseño orientado a objetos?
- 26. objeto de diseño orientado sugerencia
- 27. ¿Cuándo está orientado a objetos no es la solución correcta?
- 28. Problemas de práctica de diseño orientada a objetos
- 29. Recursos de diseño orientados a objetos
- 30. HAS-A, terminología IS-A en lenguaje orientado a objetos
Creo que es cuestión horrible para una entrevista. Dar abstracciones sin contexto no es diseño, es BS. – hasen
Me encuentro con una pregunta similar antes. – user297850