2010-03-18 10 views
5

estoy aprendiendo acerca de los patrones de diseño y en los ejemplos de código que he visto una convención donde la clase abstracta declara un método, por ejemplo:abstracta firma del método, la herencia y "Do" convención de nomenclatura

public abstract class ServiceBase { 
... 

public virtual object GetSomething(); 

y luego

protected abstract object DoGetSomething(); 

Mi pregunta es acerca de por qué existen estos dos métodos, ya que parecen servir para el mismo propósito. ¿Esto es así para que la clase base de la lógica del método GetSomething() no pueda ser anulada por las clases heredadas? Pero, de nuevo, el método está marcado como virtual, por lo que puede ser anulado de todos modos. ¿Cuál es la utilidad aquí al requerir que los implementadores de clase derivados implementen el método abstracto cuando el método virtual se puede llamar de todos modos?

+0

¿Se supone que GetSomething es virtual? – JaredPar

+0

Sí, definitivamente es virtual. –

Respuesta

4

Una razón común es poner el manejo estándar alrededor del método abstracto. Por ejemplo, tal vez el método abstracto solo se puede llamar en ciertas circunstancias, por ejemplo, después de que las splines hayan sido reticuladas. En ese caso, tiene sentido comprobar _areSplinesReticulated en un solo lugar - el método público GetSomething - en lugar de requerir que cada implementación del método abstracto realice su propia comprobación. O tal vez GetSomething es un 90% repetitivo, pero requiere un poco de lógica adicional o una información crucial que solo las clases derivadas pueden proporcionar.

Esta es una forma del patrón Template Method.

GetSomething no virtual significa que cada clase derivada obtiene el manejo estándar y solo puede participar a través de su versión personalizada de DoGetSomething. Si GetSomething es virtual, eso significa que las clases derivadas pueden eludir el manejo estándar si así lo desean. Cualquiera de estas es una estrategia viable dependiendo de si el manejo estándar de GetSomething es integral a la lógica de la clase (por ejemplo invariantes) o si la clase base desea otorgar la máxima flexibilidad a las clases derivadas.

0

No he visto la versión que usted describe en "GetSomething()" es virtual, pero he visto (y escrito) clases de la siguiente manera:

public abstract class Foo 
{ 
    protected abstract void DoBar(); 

    public void Bar() 
    { 
     // do stuff that has to happen regardless of how 
     // DoBar() has been implemented in the derived 
     // class 
     DoBar(); 
     // do other stuff 
    } 
} 

Porque "bar" no es virtual (y supongo que también podría sellarlo solo para asegurarse de que) tiene la posibilidad de "inyectar" código antes y después de que se llame al método "DoBar". Es bastante útil

Cuestiones relacionadas