أعتقد أنني لن أكون مخطئا إذا قلت إن معظم الناس يسألون عن مبادئ SOLID أثناء المقابلات. تختلف التقنيات واللغات والأطر ، ولكن مبادئ التشفير متشابهة بشكل عام: SOLID و KISS و DRY و YAGNI و GRASP وما شابه يستحق معرفة الجميع.
في الصناعة الحديثة ، هيمن نموذج OOP لعقود عديدة ، ولدى العديد من المطورين انطباع بأنه الأفضل أو الأسوأ - الوحيد. يوجد فيديو رائع حول هذا الموضوع ، لماذا لا تعتبر البرمجة الوظيفية هي القاعدة؟ حول تطوير اللغات / النماذج وجذور شعبيتها.
تم وصف SOLID في الأصل من قبل روبرت مارتن لـ OOP ويعتبره الكثيرون على أنه يشير فقط إلى OOP ، حتى تخبرنا ويكيبيديا عن ذلك ، دعنا ننظر إلى ما إذا كانت هذه المبادئ مرتبطة جدًا بـ OOP؟
مسؤولية واحدة
دعونا نتمتع برؤية العم بوب في SOLID :
تم وصف هذا المبدأ في عمل توم ديماركو وميلير بيج جونز. يسمونه التماسك. عرّفوا التماسك بأنه الارتباط الوظيفي لعناصر الوحدة. في هذا الفصل ، سنقوم بتحويل هذا المعنى قليلاً ، وربط التماسك بالقوى التي تسبب وحدة نمطية ، أو فئة ، للتغيير.
يجب أن يكون لكل وحدة سبب واحد للتغيير (ولا تفعل شيئًا واحدًا على الإطلاق ، مثل العديد من الإجابات) وكما أوضح المؤلف نفسه في أحد مقاطع الفيديو ، فإن هذا يعني أن التغييرات يجب أن تأتي من مجموعة / دور واحد من الأشخاص ، على سبيل المثال ، يجب أن تتغير الوحدة فقط وفقًا محلل الأعمال ، مصمم ، متخصص 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 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 , . , !