¿Es la convención de OOP verdadera? -- p camp Relacionados El problema

Is this OOP convention true?


2
vote

problema

Español

Hace algún tiempo he leído algo como una 'Convención' para OOP, pero no estoy seguro de si lo recuerdo correctamente.

Dice que un método debe tomar los objetos más genéricos en la jerarquía de herencia como parámetros, mientras que la mayoría de los descendientes.

es esto verdadero y, si es, ¿alguien puede explicar un poco de lil?

Ejemplo:

  IList<T> someMethod(IList<T> someList) {     IList<T> resultList = new List<T>();      ... do something with resultList ...      return resultList; }   

De acuerdo con la 'Convención' El método anterior debe devolver la lista, en lugar de ILIST?

Original en ingles

Some time ago I've read something like a 'convention' for OOP, but I'm not sure if I remember it correctly.

It says that a method must take the most generic objects in inheritance hierarchy as parameters, while return the most descendant ones.

Is this true and if it is, can anybody explain a lil bit?

Example:

IList<T> someMethod(IList<T> someList) {     IList<T> resultList = new List<T>();      ... do something with resultList ...      return resultList; } 

According to the 'convention' the method above should return List, instead of IList?

  
     
     

Lista de respuestas

5
 
vote

Es a menudo el caso de que una clase declare un puntero genérico a un objeto. A menudo la clase base. En el tiempo de ejecución, se inyecta una clase más concreta a través del constructor o un método de configuración que permite extenderse el código sin ser modificado. Este es un Santo Grial en Ingeniería de Software. Hay una regla que dice que las clases base deben ser sustituibles por sus clases derivadas: el principio de sustitución de Liskov. No estoy seguro de su ejemplo que no parece usar el argumento somelista.

 

It is often the case that a class declares a generic pointer to an object. Often the base class. At run time a more concrete class is injected through the constructor or a setter method which allows the code to be extended without being modified. This is a Holy Grail in software engineering. There is a rule that says that base classes should be substitutable by their derived classes - The Liskov substitution principle. I am not sure about your example which does not seem to use the someList argument.

 
 
 
 
3
 
vote

Intenta leer sobre Principio de sustitución de Liskov , específicamente sobre covarianza de tipos de devolución

Siguiendo los principios anteriores, usted devolverá IList en lugar de List

...
El principio de Liskov impone algunos requisitos estándar en las firmas que se han adoptado en nuevos lenguajes de programación orientados a objetos (generalmente a nivel de clases en lugar de tipos; ver nominal vs. Subtificador estructural para la distinción):

  • Contravanación de los argumentos del método en el subtipo.
  • covarianza de los tipos de retorno en el subtipo.
  • No se deben tirar nuevas excepciones del subtipo, excepto cuando esas excepciones sean en sí mismas Subtipos de excepciones lanzadas por los métodos del supertipo.
 

Try reading about Liskov Substitution Principle, specifically about Covariance of return types

Following the above principles, you would return IList rather than List

...
Liskov's principle imposes some standard requirements on signatures that have been adopted in newer object-oriented programming languages (usually at the level of classes rather than types; see nominal vs. structural subtyping for the distinction):

  • Contravariance of method arguments in the subtype.
  • Covariance of return types in the subtype.
  • No new exceptions should be thrown bymethods of the subtype, except where those exceptions are themselves subtypes of exceptions thrown by the methods of the supertype.
 
 
2
 
vote

Creo que te refieres al principio de robustez, también conocido como la Ley del Postel. Usted puede Google para ello y encontrar mucha información.

 

I think you're referring to the Robustness principle, AKA the Postel's Law. You can google for it and find plenty of information.

 
 
1
 
vote

Sí, en general, debe devolver la lista, porque la lista puede lanzar implícitamente a ILIST.

La Convención está destinada a simplificar el código de usuario y hacer que los métodos sea lo más genéricos posible. Si, en su ejemplo, ha utilizado un argumento List2 , el método habría sido difícil de llamar, si el usuario estaba usando una implementación personalizada List3 , que no es < Código> List , a pesar de que ofrece las mismas funcionalidades, y en realidad no hará ninguna diferencia en su método.

De la misma manera, si su método devolvió un IList en lugar de un List6 , cualquier método que se define en List , pero no En IList no sería accesible (a menos que sepa que IList es en realidad un 99887776610 y realice un reparto). Sin embargo, esta es una regla más débil que la anterior.

Considere el siguiente caso: usted implementa su método para devolver un List1111 , pero luego se da cuenta de que hay otra clase List2 que es más adecuada y ofrece un mejor rendimiento. Ahora, tiene que modificar el tipo de devolución de su función, y la nueva versión será incompatible con la anterior, ya que cambió el tipo de devolución de un método público.

Entonces, si bien esto es casi siempre cierto para los argumentos del método, se complica más cuando se trata de tipos de devolución. Cuando se trata de argumentos, debe preguntarse:

  1. ¿Realmente necesito un tipo tan específico?
  2. ¿Qué tan probable es que necesitaré un tipo tan específico en el futuro?

Cuando se trata de tipos de devolución, en la otra manera:

  1. ¿El usuario del método realmente necesitará un tipo tan específico?
  2. ¿Necesitará el usuario fundición explícita para acceder a los métodos útiles de mi valor de retorno?
  3. ¿Qué tan probable es que necesitaré un tipo de devolución más genérico en el futuro?
 

Yes, it should generally return List, because List can then be implicitly cast to IList.

The convention is meant to simplify user code and make the methods as generic as possible. If, in your example, you had used a List<T> argument, the method would have been hard to call, if the user was using a custom IList implementation, which is not List, even though it offers the same functionalities, and would actually make no difference to your method.

In the same way, if your method returned a IList rather than a List, any method which is defined in List, but not in IList wouldn't be accessible (unless you know that IList is actually a List and perform a cast). Though, this is a weaker rule than the previous one.

Consider the following case: you implement your method to return a List, but then you realize there is another class OtherCollection : IList that is more suited and offers better performance. Now, you have to modify the return type of your function, and the new version will be incompatible with the old one, because you changed the return type of a public method.

So, while this is almost always true for method arguments, it gets more complicated when it comes to return types. When dealing with arguments, you should ask yourself:

  1. Do I really need a so specific type?
  2. How likely is it that I'm going to need such a specific type in the future?

When dealing with return types, on the other way:

  1. Will the method user really need such a specific type?
  2. Will the user need explicit casting to access the useful methods of my return value?
  3. How likely is it that I'm going to need a more generic return type in the future?
 
 
1
 
vote

Nunca lo escuché de esa manera, pero tiene sentido. Echemos un vistazo al parámetro primero.

Si su método hace algo con un objeto dado como parámetro, necesita un cierto conjunto de oparaciones. Si un tipo ya tiene esas operaciones, no hay necesidad de profundizar en el tipo HIERACHY. De esta manera, su método se puede usar más flexible. Si, por otro lado, su método hace algo que solo debe hacerse a un tipo determinado, aunque un supertype ya ofrece las operaciones necesarias, debe ser más específico.

Con el tipo de retorno, está al revés. Si tiene un tipo específico, ¿por qué devolverlo como uno de sus supertypes? Solo limitaría las operaciones que el cliente podría llamar al objeto devuelto. Peor aún, algunos desarrolladores podrían comenzar a escribir y reparar para poder hacerlo.

Mientras que las otras respuestas son en su mayoría formalmente a la derecha (principio de sustitución de Liskov), pensé que daría una pequeña explicación más práctica. Espero que ayude.

 

Never heard it that way before but it makes sense. Let's have a look at the parameter first.

If your method does something with an object given as parameter, it needs a certain set of oparations. If one type already has those operations, there is no need to go deeper in the type hierachy. This way your method can be used more flexible. If on the other hand your method does something that should only be done to a certain type, although a supertype already offers the needed operations, you should be more specific.

With the return type it is the other way around. If you have a specific type, why return it as one of it's supertypes? It would only limit the operations the client could call on the returned object. Even worse some developers might start to typecheck and cast to be able to do so.

While the other answers are mostly formally right (Liskov Substitution Principle) I thought I'd give a little more practical explanation. Hope it helps.

 
 
 
 

Relacionados problema

2  Diseño lógico versus físico  ( Logical versus physical design ) 
Tengo una pregunta de diseño muy general, pero lo enmarcaré en términos concretos con un ejemplo. Supongamos que está trabajando en un software incrustado p...

0  Convención de nombres arbitrarios (objetos comerciales)  ( Arbitrary naming convention business objects ) 
OK, ¿realiza - (void)drawRect:(CGRect)rect0 o - (void)drawRect:(CGRect)rect111 - (void)drawRect:(CGRect)rect2 o - (void)drawRect:(CGRect)rect3 ¿Qué ...

98  ¿Cómo accedería a las propiedades de objetos desde un método de objeto? [cerrado]  ( How would you access object properties from within an object method ) 
Según lo que actualmente representa, esta pregunta no es un buen ajuste para nuestro Q & Amp; un formato. Esperamos que las...

21  ¿La clase inmutable debe ser definitiva?  ( Immutable class should be final ) 
dice en este artículo que: Haciendo una final de clase porque es inmutable es una buena razón para hacerlo. Estoy un poco desconcertado por esto ... E...

53  Pasar por referencia o pasar por valor? [cerrado]  ( Pass by reference or pass by value ) 
Según lo que actualmente representa, esta pregunta no es un buen ajuste para nuestro Q & Amp; un formato. Esperamos que las...

682  Agregar un método a una instancia de objeto existente  ( Adding a method to an existing object instance ) 
He leído que es posible agregar un método a un objeto existente (es decir, no en la definición de clase) en Python. Entiendo que no siempre es bueno hacerlo...

30  ¿Filtrado de spam bayesiano orientado a objetos?  ( Object oriented bayesian spam filtering ) 
Me preguntaba si hay alguna implementación de programación (OOP) orientada a objetos buena (OOP) de filtrado bayesiano para la clasificación de spam y texto? ...

13  ¿Cómo evitar las asignaciones / asignaciones sucesivas en C ++?  ( How to avoid successive deallocations allocations in c ) 
Considere el siguiente código: class A { B* b; // an A object owns a B object A() : b(NULL) { } // we don't know what b will be when constructing ...

56  ¿Debo usar clases anidadas en este caso?  ( Should i use nested classes in this case ) 
Estoy trabajando en una colección de clases utilizadas para la reproducción de video y la grabación. Tengo una clase principal que actúa como la interfaz públ...

55  Vistas de clase en Django  ( Class views in django ) 
django Ver puntos a una función, lo que puede ser un problema si quieres cambiar solo un poco de funcionalidad. Sí, podría tener un millón de argumentos de ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos