SOLID == OOP?

Ich denke, ich werde mich nicht irren, wenn ich sage, dass die meisten Leute während der Interviews nach SOLID-Prinzipien fragen. Technologien, Sprachen und Frameworks sind unterschiedlich, aber die Prinzipien der Codierung sind im Allgemeinen ähnlich: SOLID, KISS, DRY, YAGNI, GRASP und dergleichen sind für jeden wissenswert.



In der modernen Industrie dominiert das OOP-Paradigma seit vielen Jahrzehnten, und viele Entwickler haben den Eindruck, dass es das beste oder sogar das schlechteste ist - das einzige. Zu diesem Thema gibt es ein großartiges Video. Warum ist funktionale Programmierung nicht die Norm? über die Entwicklung von Sprachen / Paradigmen und die Wurzeln ihrer Popularität.



SOLID wurde ursprünglich von Robert Martin für OOP beschrieben und wird von vielen als nur auf OOP bezogen angesehen. Sogar Wikipedia erzählt uns davon. Schauen wir uns an, ob diese Prinzipien so eng mit OOP verbunden sind.



Einzelverantwortung



Lassen Sie uns Onkel Bobs Einblick in SOLID genießen :



Dieses Prinzip wurde in der Arbeit von Tom DeMarco und Meilir Page-Jones beschrieben. Sie nannten es Zusammenhalt. Sie definierten Kohäsion als die funktionale Verwandtschaft der Elemente eines Moduls. In diesem Kapitel werden wir diese Bedeutung ein wenig verschieben und den Zusammenhalt mit den Kräften in Beziehung setzen, die bewirken, dass sich ein Modul oder eine Klasse ändert.

Jedes Modul sollte einen Grund für Änderungen haben (und überhaupt nicht eine Sache tun, so viele antworten) und wie der Autor selbst in einem der Videos erklärt hat, bedeutet dies, dass Änderungen von einer Gruppe / Rolle von Personen stammen sollten, zum Beispiel sollte sich das Modul nur entsprechend ändern Anfragen von Geschäftsanalysten, Designern, DBA-Spezialisten, Buchhaltern oder Anwälten.



Bitte beachten Sie, dass dieses Prinzip für ein Modul gilt, das in OOP eine Klasse ist. Es gibt Module in fast allen Sprachen, daher ist dieses Prinzip nicht auf OOP beschränkt.



Offen geschlossen



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