Przykład
Natknąłem się na monolityczny kod, który robi „wszystko” w jednym miejscu - ładuje dane z bazy danych, pokazuje znaczniki HTML, działa jak router / kontroler / akcja. Zacząłem stosować SRP przenoszący kod bazy danych do własnego pliku, zapewniając lepsze nazewnictwo rzeczy i wszystko wyglądało dobrze, ale potem zacząłem mieć wątpliwości, dlaczego to robię.
Dlaczego warto refaktoryzować? Co jest celem? Czy to jest bezużyteczne? Jaka jest korzyść? Zauważ, że w większości zostawiłem plik monolityczny bez zmian, ale zmieniłem tylko mniejszą część, która była odpowiednia dla obszaru, w którym musiałem trochę popracować.
Oryginalny kod:
Aby dać konkretny przykład, natknąłem się na ten fragment kodu - ładuje specyfikacje produktu albo przez znany identyfikator produktu, albo przez identyfikator wersji wybranej przez użytkownika:
if ($verid)
$sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid);
else
$sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ;
$result1 = query($sql1);
$row1 = fetch_array($result1);
/* html markup follows */
Refaktoryzacja:
Ponieważ wykonuję pewne prace wymagające zmiany rzeczy w tej konkretnej części kodu, zmieniłem go, aby używał wzorca repozytorium, i zaktualizowałem go, aby używał obiektowych obiektów MySQL:
//some implementation details omitted
$this->repository = new SpecRepository($mysql);
if ($verid)
$row1 = $this->repository->getSpecByVersion($verid);
else
$row1 = $this->repository->getSpecByProductId($productid);
/* html markup follows to be refactored or left alone till another time*/
//added new class:
class SpecRepository extends MySqlRepository
{
function getSpecByVersion(int $verid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE id = ?
", $verid)->getSingleArray();
}
function getSpecByProductId(int $productid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE product_id = ?
", $productid)->getSingleArray();
}
}
Powinienem to zrobić?
Patrząc wstecz na zmiany, kod wciąż tam jest, kod z tą samą funkcjonalnością, ale w różnych plikach, różnych nazwach, miejscach, przy użyciu bardziej obiektowego stylu niż procedury. W rzeczywistości śmiesznie jest zauważyć, że zrekonstruowany kod wygląda na znacznie bardziej rozdęty, mimo że ma tę samą funkcjonalność.
Przewiduję kilka odpowiedzi mówiących: „jeśli nie znasz powodów, dla których dokonujesz refaktoryzacji, nie rób tego”, a być może zgodzę się. Moim powodem jest poprawa jakości kodu w czasie (i mam nadzieję, że zrobię to, przestrzegając SRP i innych zasad).
Czy to wystarczające powody, czy marnuję czas na „przestawianie kodu” w ten sposób? Ogólnie mówiąc, refaktoryzacja przypomina trochę kroczenie po wodzie - wymaga czasu i staje się bardziej „oddzielona”, jeśli chodzi o SRP, ale pomimo moich dobrych intencji nie czuję się, jakbym robił niesamowite ulepszenia. Dlatego zastanawiamy się, czy najlepiej zostawić kod jak poprzednio, a nie refaktoryzować.
Dlaczego przede wszystkim dokonałem refaktoryzacji?
W moim przypadku dodałem nową funkcjonalność dla nowej linii produktów, więc muszę albo przestrzegać istniejącej struktury kodu dla podobnych linii produktów, albo napisać własną.
select *
staje się „najlepszą praktyką”.
Select * from ..
można to uznać za anty-wzór. Zobacz stackoverflow.com/q/3639861/31326