SOLID == OOP?

我想如果我说大多数人在面试中询问SOLID原则,那我不会错。技术,语言和框架是不同的,但是编码原理通常是相似的:SOLID,KISS,DRY,YAGNI,GRASP等都是每个人都应该知道的。



在现代行业中,OOP范例已占据主导地位数十年,许多开发人员都认为它是最好的,甚至更糟的-唯一的。有一个关于该主题的精彩视频,为什么不对规范进行功能编程?关于语言/范式的发展及其流行的根源。



SOLID最初是由罗伯特·马丁(Robert Martin)针对OOP进行描述的,许多人认为SOLID只是指OOP,甚至维基百科也告诉过我们,让我们看看这些原理是否与OOP紧密相关?



单一责任



让我们享受Bob叔叔对SOLID的见解



Tom DeMarco和Meilir Page-Jones的工作中描述了此原理。他们称之为凝聚力。他们将凝聚力定义为模块元素的功能相关性。在本章中,我们将略微改变其含义,并将内聚力与导致模块或类改变的力相关联。

每个模块应该有一个更改的原因(并且根本不做任何事情,没有那么多答案),正如作者自己在其中一个视频中解释的那样,这意味着更改应该来自一个群体/角色,例如,该模块仅应根据业务分析师,设计师,DBA专家,会计师或律师的要求。



请注意,该原理适用于模块,在OOP中它是一个类。几乎所有语言都有模块,因此该原理不限于OOP。



打开关闭



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