Mam funkcję, która przyjmuje zestaw parametrów, a następnie stosuje się do nich jako warunki do zapytania SQL. Jednakże, chociaż faworyzowałem tablicę pojedynczych argumentów zawierającą same warunki:
function searchQuery($params = array()) {
foreach($params as $param => $value) {
switch ($param) {
case 'name':
$query->where('name', $value);
break;
case 'phone':
$query->join('phone');
$query->where('phone', $value);
break;
}
}
}
Mój kolega wolał zamiast tego jawnie wymienić wszystkie argumenty:
function searchQuery($name = '', $phone = '') {
if ($name) {
$query->where('name', $value);
}
if ($phone) {
$query->join('phone');
$query->where('phone', $value);
}
}
Jego argumentem było to, że poprzez jawne wyszczególnienie argumentów, zachowanie funkcji staje się bardziej widoczne - w przeciwieństwie do konieczności zagłębiania się w kod, aby dowiedzieć się, co to $param
był za tajemniczy argument .
Mój problem polegał na tym, że staje się to bardzo gadatliwe, gdy mamy do czynienia z wieloma argumentami, takimi jak 10+. Czy jest jakaś preferowana praktyka? Mój najgorszy scenariusz wyglądałby następująco:
searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')
źródło
foreach
w tym przypadku nie jest konieczne, możesz użyćif(!empty($params['name']))
zamiastforeach
iswitch
.!empty($params['name'])
na ślepo do testowania parametrów - na przykład ciąg „0” byłby pusty. Lepiej użyć,array_key_exists
aby sprawdzić klucz, lubisset
jeśli cię to nie obchodzinull
.Odpowiedzi:
IMHO twój kolega ma rację dla powyższego przykładu. Twoje preferencje mogą być zwięzłe, ale są również mniej czytelne, a zatem mniej konserwowalne. Zadaj pytanie, po co zawracać sobie głowę pisaniem funkcji, co twoja funkcja „przynosi do stołu” - muszę zrozumieć, co robi i jak to robi, bardzo szczegółowo, po prostu z niej korzystać. Na jego przykładzie, mimo że nie jestem programistą PHP, widzę wystarczająco dużo szczegółów w deklaracji funkcji, że nie muszę się martwić o jej implementację.
Jeśli chodzi o większą liczbę argumentów, jest to zwykle uważane za zapach kodu. Zazwyczaj funkcja próbuje zrobić zbyt wiele? Jeśli naprawdę potrzebujesz dużej liczby argumentów, prawdopodobnie są one w jakiś sposób powiązane i należą do jednej lub kilku struktur lub klas (może nawet tablicy powiązanych elementów, takich jak linie w adresie). Jednak przekazanie nieustrukturyzowanej tablicy nie rozwiązuje problemu zapachów kodu.
źródło
where
argumentów, drugą dlajoin
specyfikatorów itp. Nadając im odpowiednie nazwy, nadal byłyby to dokumenty.Moja odpowiedź jest mniej lub bardziej zależna od języka.
Jeśli jedynym celem grupowania argumentów w złożonej strukturze danych (tabela, rekord, słownik, obiekt ...) jest przekazanie ich jako całości do funkcji, lepiej jej unikać. Dodaje to niepotrzebną warstwę złożoności i sprawia, że twoja intencja staje się niejasna.
Jeśli pogrupowane argumenty mają znaczenie same w sobie, wówczas ta warstwa złożoności pomaga zrozumieć cały projekt: zamiast tego nazwij ją warstwą abstrakcji.
Może się okazać, że zamiast kilkunastu pojedynczych argumentów lub jednej dużej tablicy, najlepszym rozwiązaniem są dwa lub trzy argumenty, z których każdy grupuje skorelowane dane.
źródło
W twoim przypadku wolałbym metodę twojego kolegi. Jeśli pisałeś modele, a ja korzystałem z twoich modeli, aby się nad nimi rozwijać. Widzę podpis metody twojego kolegi i mogę go natychmiast użyć.
Będę musiał przejść przez implementację Twojej
searchQuery
funkcji, aby zobaczyć, jakich parametrów oczekuje Twoja funkcja.Wolę twoje podejście tylko w przypadku, gdy
searchQuery
ogranicza się do wyszukiwania tylko w obrębie jednej tabeli, więc nie będzie żadnych połączeń. W takim przypadku moja funkcja wyglądałaby następująco:Tak więc od razu wiem, że elementy tablicy są w rzeczywistości nazwami kolumn konkretnej tabeli, którą klasa posiadająca tę metodę reprezentuje w twoim kodzie.
źródło
Rób oba, w pewnym sensie.
array_merge
pozwala na wyświetlenie wyraźnej listy na górze funkcji, jak lubi twój kolega, przy jednoczesnym utrzymaniu parametrów nieporęcznych, jak wolisz.Zdecydowanie sugeruję również skorzystanie z sugestii @ chiborg z komentarzy do pytań - jest to o wiele jaśniejsze, co zamierzasz.
źródło
Możesz również przekazać ciąg podobny do ciągu zapytania i użyć
parse_str
(ponieważ wygląda na to, że używasz PHP, ale inne rozwiązania są prawdopodobnie dostępne w innych językach), aby przetworzyć go na tablicę wewnątrz metody:i nazwać to tak
Możesz użyć
http_build_query
do konwersji z tablicy asocjacyjnej na ciąg znaków (odwrotnieparse_str
).źródło