2013-10-17 10 views
17

Używam Delphi już od jakiegoś czasu, ale zamiast pochodzić z tła CS, nauczyłem się "w pracy" - głównie od mojego szefa, a wzbogacony o fragmenty zebrane z internetu, przewodniki dla użytkowników , przykłady itp.Dlaczego powinniśmy używać klas, a nie rekordów lub odwrotnie?

Teraz mój szef jest stary, zaczął programować za pomocą Pascala i niekoniecznie był na bieżąco z najnowszymi zmianami w Delphi.

Niedawno zastanawiałem się, czy jedna z naszych podstawowych technik jest "zła".

Większość naszych aplikacji współpracuje z MySQL. Ogólnie będziemy tworzyć record ze strukturą do przechowywania danych odczytanych z DB, a te zapisy będą przechowywane w TList. Ogólnie będziemy mieli jednostkę, która definiuje różne zapisy, które mamy w aplikacji, oraz funkcje i procedury, które rozpoczynają i odczytują rekordy. Nie używamy procedur rekordowe takie jak opisane here

Po zapoznaniu się kilka przykładów zacząłem się zastanawiać, czy bylibyśmy lepiej wyłączyć za pomocą classes zamiast rekordów, ale mam trudności ze znalezieniem silne wytyczne w obu kierunkach .

Rzeczą, z którą mamy do czynienia, są informacje o użytkowniku: nazwy, DOB, zdarzenia, typy zdarzeń. Lub informacje grafiku: Godziny, Praca, etc ...

Odpowiedz

35

Największą różnicą jest to, że zapisy są typy wartości i zajęcia są typy referencyjne. Krótko mówiąc, oznacza to, że:

  1. Dla typu wartości, przy korzystaniu z przydziału, a := b, tworzona jest kopia. Istnieją dwa odrębne przypadki: a i b.
  2. Dla typu odniesienia, podczas korzystania z przydziału, a := b, obie zmienne odnoszą się do tej samej instancji. Jest tylko jedno wystąpienie.

Główną konsekwencją tego jest to, co dzieje się podczas pisania a.Field := 42. W przypadku rekordu, typ wartości, przypisanie a.Field zmienia wartość elementu w a, ale nie w b. To dlatego, że a i b są różnymi instancjami. Ale dla klasy, od a i b, oba odnoszą się do tej samej instancji, a następnie po wykonaniu a.Field := 42 możesz bezpiecznie potwierdzić tę b.Field = 42.

Nie ma sztywnej zasady, która mówi, że należy zawsze używać typów wartości lub zawsze używać typów odniesienia. Obaj mają swoje miejsce. W niektórych sytuacjach lepiej będzie użyć jednego, aw innych sytuacjach lepiej będzie użyć drugiego. Zasadniczo decyzja zawsze sprowadza się do decyzji o tym, co ma oznaczać operator przypisania.

Masz istniejącą podstawę kodu i prawdopodobnie programista ją zna, która dokonała konkretnych wyborów. O ile nie ma się nieodpartego powodu, aby przejść do korzystania z typów referencyjnych, wprowadzenie zmiany prawie na pewno doprowadzi do defektów. I wady zarówno w istniejącym kodzie (zmiana na typ odniesienia zmienia znaczenie operatora przypisania), jak i w kodzie, który piszemy w przyszłości (ty i twoi współpracownicy rozwinęli intuicję co do znaczenia operatora przypisania w konkretnych kontekstach i ta intuicja się złamie jeśli się zmienisz).

Co więcej, twierdzisz, że twoje typy nie używają metod. Typ, który składa się tylko z danych i nie ma z nim żadnych metod, jest najprawdopodobniej najlepiej reprezentowany przez typ wartości. Nie mogę tego powiedzieć na pewno, ale moje instynkty mówią mi, że pierwotni programiści dokonali właściwego wyboru.

+0

+1 Całkowicie przeciwny od mojego pierwszego instynktu, ale bardzo pragmatyczny, więc w końcu muszę się zgodzić. PO powinien być jednak świadomy ewentualnego trafienia w wyniku zleceń. Na przykład: przekazanie parametrów rekordu jako "const" powinno być domyślne, ale potem znowu, może to przerwać aplikację i wracamy do próbowania bycia pragmatycznym . –

+0

@LievenKeersmaekers Tak, myślałem o dyskusji nad przekazywaniem parametrów, ale zdecydowałem się nie na prostotę. Można pomyśleć, że przekazywanie parametru według wartości jest równoznaczne z przypisaniem. Parametry są zmiennymi lokalnymi. Przekazywanie według wartości powoduje skopiowanie wartości lub odniesienia w zależności od typu parametru. Więc to, co wiesz o przypisaniach, odnosi się zarówno do przekazywania wartości parametrów. –

+0

Generalnie używamy rekordów tylko podczas przesyłu danych strukturalnych (np. TCP, serial lub dysk), w którym to przypadku używamy zapakowanych rekordów, aby zapewnić, że rozmiar pozostaje skończony. Użyjemy klas/obiektów dla wszystkiego innego. –

Powiązane problemy