インタビューの際にほとんどの人がSOLIDの原則について尋ねるのであれば、私は間違いないと思います。テクノロジー、言語、フレームワークは異なりますが、コーディングの原則は一般的に似ています。SOLID、KISS、DRY、YAGNI、GRASPなどは、誰にとっても知っておく価値があります。
現代の業界では、OOPパラダイムが何十年にもわたって支配されており、多くの開発者はそれが最良またはさらに悪い-唯一のものであるという印象を持っています。このトピックに関する素晴らしいビデオがあります。なぜ関数型プログラミングは標準ではないのですか?言語の開発/パラダイムとその人気のルーツについて。
SOLIDはもともとOOPについてロバートマーティンによって記述され、多くの人がOOPのみを参照していると認識しています。ウィキペディアでもそれについて教えられています。これらの原則がOOPにそれほど結びついているかどうかを見てみましょう。
単一の責任
ボブおじさんの SOLIDへの洞察を楽しみましょう:
この原理は、トム・デマルコとメイリル・ペイジ・ジョーンズの研究で説明されました。彼らはそれを結束と呼んだ。彼らは、凝集度をモジュールの要素の機能的な関連性として定義しました。この章では、その意味を少し変えて、モジュールまたはクラスを変化させる力に凝集力を関連付けます。
各モジュールには変更の理由が1つある必要があり(1つのことを実行するのではなく、できるだけ多くの答えを出します)、作成者自身がビデオの1つで説明したように、これは、変更は1つのグループ/人々の役割から来る必要があることを意味します。たとえば、モジュールはビジネスアナリスト、デザイナー、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 , . , !