Czy istnieje termin używany, gdy zmienne wewnętrzne są deklarowane jako publiczne i dostępne?

10

Jeśli ktoś pisze kod, aby wewnętrzna zmienna $ _fields była dostępna bez korzystania z metod getter / setter, czy istnieje odpowiedni termin, aby to opisać?

Coś na tyle grzecznego, by korzystać z zarządzania :)

PeterB
źródło
9
Brak enkapsulacji?
Oded
@Oded Myślę, że masz rację - brak / słaba enkapsulacja dobrze to opisuje
PeterB
Dwa zdania, o których myślałem, próbując odpowiedzieć na to pytanie, to „nieszczelna abstrakcja” i „luźne określanie zakresu” - do czego odnoszą się każde z nich (poza moją głową)?
PeterB,
1
Przeciekająca abstrakcja występuje, gdy próbujesz wyodrębnić koncepcję, ale tak naprawdę to nie działa - podstawowe koncepcje wciąż wyciekają (ORM w SQL i frameworki WWW w HTTP / HTML są zwykle nieszczelnymi abstrakcjami).
Oded
@PeterB - aby dodać do wyjaśnienia Odeda
Joris Timmermans

Odpowiedzi:

30

Ujawnianie prywatnych członków nigdy nie jest dobre w uprzejmym społeczeństwie ...

Ta praktyka to brak / słabe kapsułkowanie.

Oded
źródło
6
+1, Cóż, nie wyprowadziłbyś swoich szeregowych z biura, prawda?
StuperUser,
6
-1: Hermetyzacja naprawdę się wydarzyła i wydarzyła się dobrze. Ale nie zostało to udokumentowane za pomocą kodu źródłowego w powszechnie akceptowany sposób. Niektóre języki (np. Python) nie mają prawdziwie prywatnych zmiennych, ale wciąż ćwiczą enkapsulację.
S.Lott,
6
@Oded: Encapsulation to koncepcja projektowa . Różne języki mają różne implementacje tej koncepcji. Język z prywatną deklaracją pozwala na jedną implementację. Funkcjonalny język programowania z obiektami bezstanowymi może mieć inną implementację. Python (którego brakuje private) ma jeszcze jedną implementację pojęcia enkapsulacji.
S.Lott,
1
@S Lott; Oded - enkapsulacja jest dobra i poleganie na kodzie, w którym często są bezpośrednio dostępne zmienne prywatne z innych klas, jest kiepskie. W Pythonie robisz to, uzyskując dostęp do zmienionych nazwami prywatnych zmiennych innej klasy lub ignorując konwencje pojedynczego prefiksu podkreślenia (chociaż jeśli twój geter robi inne zachowanie; naprawdę powinien być używany __do zmiany nazwy). Inne języki mogą mieć również słabą enkapsulację, np. Odbicie w Javie i arytmetyka wskaźnika w C ++, aby uzyskać prywatne zmienne. Python po prostu nie sprawia, że ​​składnia jest tak uciążliwa.
dr jimbob,
2
@drjimbob: Kod w Pythonie rzadko używa zmiany __nazw. Bez __tego projekt nadal odzwierciedla dobre kapsułkowanie. Twierdzenie, że „publiczne” oznacza „brak / słabe kapsułkowanie” jest błędne. Koncepcja jest nadal obecna. W kodzie źródłowym brakuje odpowiedniej dekoracji.
S.Lott,
10

Poza brakiem enkapsulacji wspomnianym już przez Odeda, w zależności od języka programowania i jego paradygmatów, może to być również „zwykłe stare dane” (gdzie niekoniecznie jest to zapach antypatternowy lub kodowy).

Joris Timmermans
źródło
4

Słyszałem już wcześniej termin „nagi przedmiot”.

Raku
źródło
1
Jest to z pewnością mylący sposób na nazwanie osób rozważających wzorzec Naked Objects
Matthieu,
1
Tak, to też mnie zdezorientowało.
Raku,
2

Nazywa się to torbą nieruchomości.

Zwykle służy do przechowywania zestawu może powiązanych właściwości (gdzie każda z nich może potencjalnie być obiektem klasy, który ma odpowiednie specyfikatory dostępu lub nie). Ale otaczająca go struktura to tylko torba właściwości.

Martin York
źródło
2

Nazywa się to „nieprzestrzeganiem określonego standardu kodowania”.

OP napisał:

wewnętrzna zmienna $ _fields jest dostępna bez użycia metod getter / setter

Może to być niezgodne z twoim standardem i (a więc) może to być zapach kodu. Ale niekoniecznie jest to słaba enkapsulacja. Wystawienie zmiennej zewnętrznej (jak w „tylko do użytku wewnętrznego”) na getter i setery na świat zewnętrzny byłoby jeszcze gorsze.

Pytanie brzmi: czy powinno $_fieldsbyć dostępne dla świata zewnętrznego?

Jeśli tak, mamy przypadek, w którym dodajesz metody pobierające / ustawiające. Te metody nie zawierają niczego poza faktem, że $_fieldsjest to pewnego rodzaju zmienna (w przeciwieństwie do czegoś obliczonego / pobranego itp. W locie). W zależności od języka prawdopodobnie nadal będziesz wyciekał na zewnątrz (inaczej szczegóły implementacji). Niezależnie od tego, czy zawsze chcesz getterów / seterów, czy tylko wtedy, gdy „potrzebny” jest standardowym problemem kodowania.

Jeśli nie$_fields powinno być dostępne, to nie korzystaj z niego. To, czy powinieneś uniemożliwić innym dostęp do niego na poziomie językowym (prywatnym i znajomym), czy nie (co może ułatwić debugowanie w pewnych okolicznościach) jest - znowu - standardowym zagadnieniem kodowania.

Problem enkapsulacji jest całkowicie ortogonalny. Naruszenie enkapsulacji jest absolutnie możliwe w przypadku osób pobierających i ustawiających. Jeszcze łatwiej jest się w nie wsunąć, ponieważ dzwonki większości ludzi nie dzwonią, gdy widzą grupę pobierających i ustawiających - kod, który pozornie przestrzega najlepszych praktyk. Kod, który bardzo dobrze może wprowadzić znacznie więcej zależności od wewnętrznych szczegółów implementacji niż wywoływana zmienna, $_fieldsktóra nie jest określona jako private.

Jestem fanem złych analogii: nazywanie tego złym hermetyzacją jest jak nazywanie kogoś, kto trzyma broń, mordercą.

rwos
źródło
1

Nazwałbym takie zmienne zmiennymi publicznymi .

Olivier Jacot-Descombes
źródło
-2

jeśli twoje metody setter / getter są niczym więcej niż

void setfoo(bar){foo=bar;}
foo getfoo{return foo;}

to po prostu utworzenie zmiennej łonowej pozwala zaoszczędzić trochę pisania poza kilkoma przypadkowymi krawędziami, w których różnica ma znaczenie.

Ryathal
źródło
3
Tylko dlatego, że to wszystko, co robią teraz osoby pobierające i ustawiające, nie oznacza, że ​​zawsze tak będzie. A jeśli dodanie sprawdzania poprawności do ustawiacza wymaga przeczesywania dziesiątek tysięcy wierszy kodu w celu znalezienia wszędzie, gdzie dostępna jest właściwość, natychmiast zniszczysz kilkanaście sekund, które sam sobie zaoszczędziłeś, celowo unikając enkapsulacji za pierwszym razem.
Plutor
@Plutor: Jeśli to wszystko, co obiekt kiedykolwiek zrobi (np. Ponieważ reprezentuje komunikat wysłany do innego procesu lub rekordu w bazie danych), to jest OK; są to rzeczy, które powinny być wysoce konserwowane.
Donal Fellows,