2011-01-26 32 views
16

mi pregunta para hoy: ¿hay métodos sobrecargados en la interfaz incorrecta? Ya sabes, el tipo de métodos "omitir parámetros si no te importa, vamos a averiguar los valores predeterminados" sobrecargados. Al igual que :Métodos sobrecargados en la interfaz

void Add(object item); 
void Add(object item, bool shouldDoSomething); 
void Add(object item, bool shouldDoSomething, IUltraObscureDeviceContext context); 

En este caso, tiendo a pensar que sólo este último pertenece a una interfaz y los demás debe ser implementado en la clase abstracta en la parte superior de la misma. Pero, de nuevo, no estoy seguro.

Además, hay momentos en los que simplemente desea diferentes sobrecargas haciendo un trabajo ligeramente diferente (detenerme allí mismo si los métodos sobrecargados nunca se deben utilizar para eso). O a veces no puedes rellenar nulls en lugar de algún parámetro, quieres que se genere la excepción si algo es nulo. ¿No debería usar sobrecarga en este caso?

Básicamente, estoy buscando algunas pautas sobre métodos sobrecargados en interfaces vs métodos sobrecargados en clases abstractas que implementan estas interfaces, etc. Gracias de antemano

+0

Si el contrato que está entregando promete ofrecer 3 versiones de este método, entonces debe incluir esas sobrecargas. –

+0

Bueno, sí, lo sé, pero la pregunta también incluye esto: ¿debo proporcionar contratos o no, a veces o quizás – Dyppl

+0

¿Por qué no usamos ** parámetros predeterminados **? –

Respuesta

8

Si los valores predeterminados dependen del receptor de la llamada al método, los declara como métodos de interfaz.

Si los valores predeterminados son predeterminados independientemente del receptor, cree las diversas sobrecargas de lista de argumentos reducidos como métodos de extensión y ahorre a los implementadores el dolor de cabeza de tener que proporcionar todas las sobrecargas.

Si usted está tratando con algún tipo de excepciones de la regla 80/20 meollo de la cuestión, en los que por defecto son independientes de la implementación casi pero no del todo siempre es suficiente, usted tiene algunas opciones, ninguna de las cuales son tan buenos:

  • Trate de hacerlo como si siempre fueran diferentes, grábelos como métodos de interfaz y vuelva a implementarlos en todas partes. No muy seco
  • Trate de hacerlo como si siempre fueran diferentes, los declare como métodos de interfaz y herede una clase base que proporcione la implementación predeterminada del 80%. Es algo torpe, y no es bueno si tu única ranura de clase base ya está ocupada.
  • Crea otra interfaz que contenga esos métodos específicos. Declare los métodos de extensión con la firma correspondiente en la interfaz original. En los métodos de extensión, as, envíe el argumento this al nuevo tipo de interfaz, y si coincide, llámelo allí; de lo contrario, rellene los valores predeterminados de stock. Muy funky, depende del casting dinámico, por lo que no es tan bueno en un bucle interno, pero desacopla los valores predeterminados tanto del implementador como del llamante sin sacrificar la flexibilidad para los implementadores que no pueden tomar los "valores predeterminados predeterminados".
+0

La última opción es de hecho muy funky, pero parece una buena solución para un mal problema. Respuesta sólida en general, gracias. – Dyppl

+0

¿Qué tal si la interfaz incluye un parámetro bitmask-enum que indica cuál de los otros parámetros se especifica, y los wrappers independientes de la implementación llaman a la rutina "real" con los valores adecuados en el parámetro extra? Si tuviera mi druthers, habría una forma de hacerlo automáticamente, pero incluso sin un mecanismo automatizado podría ser un buen enfoque. – supercat

0

IMO si la interfaz/contrato lo especifica, no debería haber ningún problema. Sin embargo, el objetivo es simplificar las cosas al exponer una interfaz y ocultar los detalles. Y eso es donde los parámetros opcionales son útiles. Los lenguajes perfectamente orientados a objetos como Python ni siquiera tienen sobrecarga AFAIK

+0

Otros lenguajes orientados a objetos perfectamente adecuados, como Objective-C, no tienen interfaces (ObjC tiene protocolos que están relacionados de alguna manera) lo que también haría que la pregunta fuera irrelevante. –

1

Los métodos sobrecargados en una interfaz pueden estar bien si el diseño de la interfaz lo justifica. Yo personalmente nunca tuve que hacer esto.

No definiría los valores de los parámetros predeterminados en una interfaz. Es un detalle de implementación que implementa las clases que eligen salir a la superficie.

comentan tener diferentes implementaciones para las sobrecargas ....

No hagas eso. Piense en la implementación de estos métodos sobrecargados como llamando al único método que tiene todos los parámetros definidos con algunos valores predeterminados. Así es como los usuarios de tu código esperarían que fuera.

Si necesita un comportamiento diferente a continuación, utilizar el polimorfismo. Para eso está ahí.

+0

El polimorfismo no le dará dos implementaciones en una instancia. Supongo, eso es lo que los métodos con diferentes nombres están ahí para – Dyppl

+0

Sí, indirectamente lo que decía que la clase de implementación debería ser diferente y no mezclar cosas teniendo diferentes sobrecargas implementando cosas diferentes, sino usar polimorfismo en su lugar. –

Cuestiones relacionadas