W 2000 roku mój kolega powiedział mi, że to anty-wzorzec, aby publiczne metody były wirtualne lub abstrakcyjne.
Na przykład uważał taką klasę za niezbyt dobrze zaprojektowaną:
public abstract class PublicAbstractOrVirtual
{
public abstract void Method1(string argument);
public virtual void Method2(string argument)
{
if (argument == null) throw new ArgumentNullException(nameof(argument));
// default implementation
}
}
Stwierdził to
- twórca klasy pochodnej, która implementuje
Method1i zastępuje,Method2musi powtórzyć sprawdzanie poprawności argumentów. - na wypadek, gdyby twórca klasy podstawowej zdecydował się dodać coś wokół dostosowywalnej części
Method1lubMethod2później, nie może tego zrobić.
Zamiast tego mój kolega zaproponował takie podejście:
public abstract class ProtectedAbstractOrVirtual
{
public void Method1(string argument)
{
if (argument == null) throw new ArgumentNullException(nameof(argument));
this.Method1Core(argument);
}
public void Method2(string argument)
{
if (argument == null) throw new ArgumentNullException(nameof(argument));
this.Method2Core(argument);
}
protected abstract void Method1Core(string argument);
protected virtual void Method2Core(string argument)
{
// default implementation
}
}
Powiedział mi, że upublicznianie publicznych metod (lub właściwości) jest tak samo złe, jak upublicznianie pól. Dzięki zawijaniu pól we właściwości można w razie potrzeby przechwycić później dostęp do tych pól. To samo dotyczy publicznych wirtualnych / abstrakcyjnych członków: zawijanie ich w sposób pokazany w ProtectedAbstractOrVirtualklasie pozwala programistom klasy podstawowej przechwytywać wszelkie wywołania, które przechodzą do metod wirtualnych / abstrakcyjnych.
Ale nie uważam tego za wytyczne projektowe. Nawet Microsoft tego nie przestrzega: wystarczy spojrzeć na Streamklasę, aby to sprawdzić.
Co sądzisz o tej wytycznej? Czy to ma sens, czy uważasz, że to komplikuje API?
protectedjest najbardziej przydatny, gdy chcesz narazić prywatnych członków klasy abstrakcyjnej na klasy pochodne. W każdym razie nie martwię się szczególnie o opinię twojego przyjaciela; wybierz modyfikator dostępu, który najlepiej pasuje do konkretnej sytuacji.
virtualpozwalają na opcjonalne zastąpienie. Twoja metoda powinna być prawdopodobnie publiczna, ponieważ może nie zostać zastąpiona. Tworzenie metodabstractzmusza do ich przesłonięcia; prawdopodobnie powinnyprotected, ponieważ nie są szczególnie przydatne wpublickontekście.