2010-03-10 11 views
5

Jestem ciekawy, co jest dobrą praktyką, jeśli chodzi o niektóre scenariusze dotyczące typów zagnieżdżonych w .NET.Zagnieżdżone typy, które są publiczne

Powiedzmy, że masz klasę Wheel, a klasa Wheel zawiera obiekty Bearing. Obiekt Bearing ma sens tylko w Kole, a Ty nie chcesz, aby był on tworzony niezależnie, więc byłoby sensowne, aby klasa Bearing była zagnieżdżona wewnątrz obiektu Wheel. Powiedzmy jednak, że masz scenariusz, w którym musisz przeczytać właściwość Wheel.Bearings poza klasą Wheel. Wymagałoby to teraz upublicznienia zagnieżdżonej klasy Bearing.

W tej sytuacji, jaka jest najlepsza opcja?
1 - Utwórz publiczną klasę łożyska zagnieżdżoną w klasie koła
2 - Utwórz niezależną klasę Bearing, która pobiera obiekt Wheel w swoim konstruktorze.
3 - Utwórz obszar nazw kół i utwórz niezależną klasę Bearing wewnątrz tego obszaru nazw.
4 - Coś jeszcze?

AKTUALIZACJA: Aktualizuję to, wprowadzając więcej szczegółów i odzwierciedlając niektóre z dotychczasowych sugestii. ClassParent jest klasą nadrzędną, ClassChild jest klasą potomną. ClassChild jest ZAWSZE dzieckiem klasy ClassParent, nie ma sensu istnieć samodzielnie. Problem polega na tym, że ClassChild ma kilka właściwości, które muszą być odsłonięte publicznie, podczas gdy cała reszta powinna być wywoływana tylko z ClassParent. Przykładem jest funkcja ClassChild.Delete, która nie powinna być publicznie dostępna, ponieważ powinna być wywoływana tylko z ClassParent, ponieważ ClassParent musi wykonać odpowiednie czyszczenie i modyfikacje.

Po przejrzeniu sugestii, projekt, który wymyśliłem, wygląda na trochę nieczysty, więc pomyślałem, że poprosiłbym o dane wejściowe. Mam:

public class Parent 
{ 
    ChildNested childObj 

    public DeleteChild() 
    { 
     //expose this method publically 
     childObj.DeleteChild() 
     //other functionality 
    } 

    public Child GetChild() 
    { 
     //expose Child, not ChildNested publically 
     return childObj 
    } 

    private class ChildNested:Child 
    { 
     public Child() 
     { 
       Base.Child() 
     } 
     public DeleteChild() 
     { 
       Base.Delete() 
     } 
    } 

public abstract class Child 
{ 
protected Child() 
    { 
    } 
protected Delete() 
    { 
    } 
    public PublicPropertyToExpose() 
    { 
    }  
} 

Odpowiedz

8

Najlepszy projekt jest stworzenie publicznego Bearing klasy z konstruktora internal i tworzyć instancje nim w klasie Wheel.

Jeśli klasa Bearing potrzebuje dostępu do prywatnych członków klasy Wheel, można sprawić, że publiczność Bearing klasa abstract, a następnie wykonać konkretną implentation jako private zagnieżdżonych klasy wewnątrz Wheel.

Ogólnie rzecz biorąc, you should not make public nested types.

+0

+1. W pełni się zgadzam. Zagnieżdżone typy są trudne do odczytania, trudne do naśladowania. Kiedy programujesz przeciwko nim, zawsze musisz określić typ wyjścia, co jest dość irytujące. – Steven

+0

A co, gdyby scenariusz polegał na tym, że Bearing nigdy nie może i nie powinno istnieć bez koła? Ponieważ w tym przypadku możesz faktycznie utworzyć obiekt Bearing bez koła. Przykładem jest klasa Klawiatura i klasa Klawisz, nigdy nie można mieć klawisza klawiatury bez klawiatury. –

+0

Czy istnieje sposób utworzenia klasy, która ma dwie (lub więcej) publicznych klas pochodnych od niej, ale nie jest "publicznie" możliwe do wyprowadzenia, poza tym, że ma klasę podstawową publiczną, z prywatnym konstruktorem, a następnie posiada klasy pochodne zagnieżdżony w nim? Projektując hierarchie klas, często wydaje mi się, że znajduję się w rogu, gdzie rzeczy, które chcę być klasami publicznymi, tkwią w innych klasach. Jakikolwiek miły sposób na to, inny niż dawanie rzeczy większy zakres niż naprawdę chcę? – supercat

1
  • Załóż niezależną klasę Łożysko z prywatnego konstruktora
  • Utwórz klasę fabryki, która będzie instancję klasy łożyska podano klasę Wheel
+0

Alternatywnie można zastosować metodę, która zwraca łożysko, powiedz "CreateBearing". –

1

Chciałbym przetestować „Azymut” niezależnie, tak bym wybierz drugą opcję.

1

Łożysko może istnieć samodzielnie, ponieważ prawdopodobnie jest wystarczająco użyteczne, aby można go było używać w innym miejscu na świecie, poza kołem.

Koło jest agregowane za pomocą łożysk, ale koło nie definiuje łożyska. Łożyska są użyteczne i mogą być używane w innych elementach oprócz kół.

Fakt, że potrzebna jest ci własność publiczna dla namiaru wskazuje, że musi to być klasa publiczna, poza Kołem.

Co się stanie, gdy ponownie wymyślecie Koło (wszyscy mamy ...). Być może używasz nowego "łożyska powietrznego", takiego jakie istnieją w mikroturbinach, teraz masz wiele typów łożysk w klasie koła, z których niektóre nie są używane.

Ustawiłbym łożysko w tej samej przestrzeni nazw, ale nie w klasie koła. Rzadko spotykam potrzebę zajęć wewnętrznych. Zwykle anonimowa klasa wypełnia wszelkie luki, których potrzebuję.

Powiązane problemy