SOLIDE == POO?

Je suppose que je ne me tromperai pas si je dis que le plus souvent, les gens posent des questions sur les principes SOLID lors des entretiens. Les technologies, les langages et les frameworks sont différents, mais les principes de codage sont généralement similaires: SOLID, KISS, DRY, YAGNI, GRASP et autres valent la peine d'être connus de tous.



Dans l'industrie moderne, le paradigme de la POO a dominé pendant de nombreuses décennies, et de nombreux développeurs ont l'impression qu'il est le meilleur ou même le pire - le seul. Il y a une excellente vidéo sur ce sujet Pourquoi la programmation fonctionnelle n'est-elle pas la norme? sur le développement des langages / paradigmes et les racines de leur popularité.



SOLID a été décrit à l'origine par Robert Martin pour la POO et est perçu par beaucoup comme se référant uniquement à la POO, même wikipedia nous en parle, voyons si ces principes sont si liés à la POO?



Responsabilité unique



Profitons de la vision d' oncle Bob sur SOLID :



Ce principe a été décrit dans les travaux de Tom DeMarco et Meilir Page-Jones. Ils ont appelé cela la cohésion. Ils ont défini la cohésion comme la relation fonctionnelle des éléments d'un module. Dans ce chapitre, nous allons changer un peu ce sens et relier la cohésion aux forces qui provoquent le changement d'un module ou d'une classe.

Chaque module doit avoir une raison de changement (et ne pas faire du tout une chose, autant de réponses) et comme l'auteur lui-même l'a expliqué dans l'une des vidéos, cela signifie que les changements doivent provenir d'un groupe / rôle de personnes, par exemple, le module ne doit changer que selon demandes d'analyste d'affaires, de concepteur, de spécialiste DBA, d'expert-comptable ou d'avocat.



Veuillez noter que ce principe s'applique à un module, qui en POO est une classe. Il existe des modules dans presque toutes les langues, ce principe ne se limite donc pas à la POO.



Ouvert fermé



SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION, BUT CLOSED FOR MODIFICATION

Bertrand Meyer

- , — , ( ) .



( , ). , . map, filter, reduce, . , foldLeft !



def map(xs: Seq[Int], f: Int => Int) = 
  xs.foldLeft(Seq.empty) { (acc, x) => acc :+ f(x) }

def filter(xs: Seq[Int], f: Int => Boolean) = 
  xs.foldLeft(Seq.empty) { (acc, x) => if (f(x)) acc :+ x else acc }

def reduce(xs: Seq[Int], init: Int, f: (Int, Int) => Int) =
  xs.foldLeft(init) { (acc, x) => f(acc, x) }


, , — .



Liskov Substitution



:



If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.

, , "" . , , .



"", , "" . , ! , ( ), :



static <T> T increment(T number) {
  if (number instanceof Integer) return (T) (Object) (((Integer) number) + 1);
  if (number instanceof Double) return (T) (Object) (((Double) number) + 1);
  throw new IllegalArgumentException("Unexpected value "+ number);
}


, T, , "" (.. ), , — .



, , "" , , . , , ( ), , (ad hoc) . .



Interface Segregation



, , , .



, , "" ! , (type classes), .



Comparable Java type class Ord haskell ( classhaskell ):



// 
class Ord a where
    compare :: a -> a -> Ordering


"", , , compare ( Comparable). .



Dependency Inversion



Depend on abstractions, not on concretions.

Dependency Injection, — , :



int first(ArrayList<Integer> xs) // ArrayList    -> 
int first(Collection<Integer> xs) // Collection   -> 
<T> T first(Collection<T> xs) //         


: ( ):



def sum[F[_]: Monad](xs: Seq[F[Int]]): F[Int] =
  if (xs.isEmpty) 0.pure
  else for (head <- xs.head; tail <- all(xs.tail)) yield head + tail

sum[Id](Seq(1, 2, 3)) -> 6
sum[Future](Seq(queryService1(), queryService2())) -> Future(6)


, , .






SOLID , . , SOLID , . , !




All Articles