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 objecto1
of typeS
there is an objecto2
of typeT
such that for all programsP
defined in terms ofT
, the behavior ofP
is unchanged wheno1
is substituted foro2
thenS
is a subtype ofT
.
, , "" . , , .
"", , "" . , ! , ( ), :
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
( class
— haskell
):
//
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 , . , !