KISS-他のすべおの蚭蚈原則を含む蚭蚈原則

KISSの蚭蚈原理の本質を簡単か぀同時に詳现に説明しようず思いたす。 KISSは、他のほずんどすべおの蚭蚈原則を含む非垞に䞀般的で抜象的な蚭蚈原則です。 蚭蚈原則では、「適切な」コヌドを蚘述する方法を説明しおいたす。 しかし、良いコヌドずはどういう意味ですか これは、可胜な限り高速に実行されるコヌドであるず考える人もいれば、可胜な限り倚くの蚭蚈パタヌンが関係するコヌドであるず考える人もいたす。しかし、正しい答えは衚面にありたす。 コヌドは玔粋な情報です。 そしお、情報の䟡倀に関する䞻な基準は、1信頌性2アクセシビリティ3理解可胜性です。 信頌性ずアクセシビリティが重芁である理由は明らかです。 コヌドからは、゚ラヌが発生した堎合や、アプリケヌションがむンストヌルされおいるサヌバヌが「嘘を぀く」堎合は圹に立ちたせん。 コヌドの理解性が重芁なのはなぜですか 理解可胜なコヌドでは、゚ラヌの怜玢が簡単になり、゚ラヌの倉曎、修正、および保守が簡単になりたす。 そのため、プログラマビリティヌが理解すべき䞻な䟡倀は理解可胜性です。 ただし、1぀の問題がありたす。 事実は、理解可胜性は玔粋に䞻芳的なものであるこずです。 もっず客芳的な理解の基準が必芁です。 そしお、この基準はシンプルです。 実際、単玔なアプリケヌションは耇雑なアプリケヌションよりも理解しやすいものです。 ただし、シンプルさを実珟するこずは困難です。 Peter Goodwinが圌の著曞「The Craft of a Programmer」に曞いおいるこずは次のずおりです。

プロゞェクトが単玔な堎合、理解するのは簡単です...単玔なプロゞェクトの開発はそれほど簡単ではありたせん。 時間がかかりたす。 耇雑なプログラムの堎合、最終決定は膚倧な量の情報を分析するこずによっお埗られたす。 コヌドが適切に蚭蚈されおいれば、他の方法では実珟できなかったように芋えたすが、集䞭的なメンタルワヌクおよび倧量のリファクタリングの結果ずしおその単玔さが達成された可胜性がありたす。 シンプルなものを䜜るのは難しいです。 コヌドの構造が明らかな堎合は、簡単だずは思わないでください。



そのため、KISSの蚭蚈原則シンプルでわかりやすいものにするは、シンプルなコヌドが最も理解しやすいため、コヌドのシンプルさが最も重芁であるず宣蚀しおいたす。

ほずんどすべおの蚭蚈原則は、コヌドの明瞭床を達成するこずを目的ずしおいたす。 蚭蚈原則に違反するこずにより、コヌドの理解床が䜎䞋したす。 理解できないコヌドは、理解や修正が難しいため、コヌドが耇雑であるず自動的に感じさせたす。 これらの原則のいずれかに違反した堎合、KISSの原則にも違反したす。 したがっお、KISSには他のほずんどすべおの蚭蚈原則が含たれおいるず蚀えたす。

蚭蚈パタヌンは、いく぀かの問題に察しお最も成功し、単玔で、明確な解決策を説明したす。 このパタヌンが解決する問題がないデザむンパタヌンを䜿甚するず、KISSに違反し、コヌドに䞍芁な耇雑さが生じたす。 パタヌンに察応する問題がある堎所でデザむンパタヌンを䜿甚しない堎合は、KISSが再床砎損し、コヌドが耇雑になりたす。



私の意芋では、KISSの原則は 、デザむンの基本原則を知らない、たたは理解しおいない初心者のデザむナヌにのみ有甚です 。 KISSは、蚭蚈原則ずパタヌンの誀甚から保護したす。 原則ずパタヌンはコヌドの理解床を高めるように蚭蚈されおいるため、それらを適切に䜿甚しおもコヌドの理解床が䜎䞋するこずはありたせん。 ただし、蚭蚈原則を誀解しおいる堎合たずえば、「䞍芁な゚ンティティを䜜成しない」を「できる限り少ない゚ンティティを䜜成する」ず解釈する、たたは1぀の原則を遵守し、他の12の原則に違反する堎合、KISSは信頌できる゚アバッグになりたす。 それ以倖の堎合、KISSはほずんど圹に立ちたせん。 圌はあたりにも䞀般的か぀抜象的です。 残りの原則はより具䜓的であり、コヌドのわかりやすさず単玔さを実珟するためのより明確な方法が含たれおいたす。



「単玔性」などの抂念に関する人々の考え方はさたざたである可​​胜性があるため、 KISS-aに関する次の誀解が広たっおいたす。

誀解1.単玔なコヌドが最も簡単に蚘述できる皮類のコヌドであるず想定する堎合、KISSの原則は、蚭蚈を考えずに頭に浮かぶ最初のものを曞くこずを奚励しおいるず解釈できたす。

誀解2.単玔なコヌドが、曞くためにできるだけ知識を必芁ずしないようなコヌドであるず仮定する堎合、KISSの原則はデザむンパタヌンを䜿甚しないこずを掚奚しおいるず解釈できたす。



この堎合、単玔さは耇雑ではなく、人工的でなく、最も自然で、難しくなく、理解しやすいものずしお理解されるべきです。



Cの䟋





タスク図圢を暪断するずきは、その亀差郚分をシェヌディングする必芁がありたす。

それで、異なる組み合わせのための普遍的なhatch化アルゎリズムを開発する方法

圢状長方圢-長方圢、長方圢-倚角圢、

polygon-polygon、ellipse-polygon、ellipse-ellipseかなり

難しく、ほずんどの堎合、あたり効果的ではありたせん。

オプションは独自のアルゎリズムです。



最初に思い浮かぶのは次のようなものです



コヌドを展開
public interface IShape { } public class Circle : IShape { } public class Rectangle : IShape { } public class RoundedRectangle : IShape { } public class IntersectionFinder { public IShape FindIntersection(IShape shape, IShape shape2) { if (shape is Circle && shape2 is Rectangle) return FindIntersection(shape as Circle, shape2 as Rectangle); if (shape is Circle && shape2 is RoundedRectangle) return FindIntersection(shape as Circle, shape2 as RoundedRectangle); if (shape is RoundedRectangle && shape2 is Rectangle) return FindIntersection(shape as RoundedRectangle, shape2 as Rectangle); return FindIntersection(shape2, shape); } private IShape FindIntersection(Circle circle, Rectangle rectangle) { return new RoundedRectangle(); //     Rectangle  Circle,     .          RoundedRectangle } private IShape FindIntersection(Circle circle, RoundedRectangle rounedeRectangle) { return new Circle(); } private IShape FindIntersection(RoundedRectangle roundedRectanglerectangle, Rectangle rectangle) { return new Rectangle(); } }
      
      









ただし、このコヌドは、単玔さの定矩からの2぀のポむント、぀たり最も自然で理解しやすいものず矛盟しおいたす。 人工的なクラスIntersectionFinderがあるため、コヌドは自然ではありたせん。 コヌドに慣れおいない人は、亀差点蚈算関数が実装されおいるかどうか、およびその䜿甚方法を理解するために、IShapeが䜿甚されおいるすべおの堎所を調べる必芁があるため、コヌドを理解するために簡単にアクセスできたせん。 数䞇たたは数癟のコヌド行を持぀プロゞェクトでは、これは簡単な䜜業ではないかもしれたせん。 IntersectionFinderクラスでの䜜業が難しくなるもう1぀の䞍快な瞬間がありたす。FindIntersectionずいう名前の関数の数は、数字の数から算術玚数の圢で増加したす。その結果、IntersectionFinderクラスは、時間の職業。 したがっお、FindIntersectionをIShapeに転送したす。



コヌドを展開
 public interface IShape { IShape FindIntersection(IShape shape); } public class Circle : IShape { public IShape FindIntersection(IShape shape) { if (shape is Rectangle) return FindIntersection(shape as Rectangle); if (shape is RoundedRectangle) return FindIntersection(shape as RoundedRectangle); return shape.FindIntersection(this); } private IShape FindIntersection(Rectangle rectangle) { return new RoundedRectangle();//     Rectangle  Circle,     .          RoundedRectangle } private IShape FindIntersection(RoundedRectangle rounedeRectangle) { return new Circle(); } } public class Rectangle : IShape { public IShape FindIntersection(IShape shape) { if (shape is RoundedRectangle) return FindIntersection(shape as RoundedRectangle); return shape.FindIntersection(this); } private IShape FindIntersection(RoundedRectangle roundedRectangle) { return new Rectangle(); } } public class RoundedRectangle : IShape { public IShape FindIntersection(IShape shape) { return shape.FindIntersection(this); } }
      
      









さお、今ではコヌドに䞍慣れなプログラマヌは、2぀の図の共通郚分を䜜成するためにプロゞェクトを回避する方法を探す必芁はありたせん。 䞍芁な゚ンティティ「亀差電卓」が消えたした。 コヌドがより自然になり、理解しやすくなりたした。぀たり、よりシンプルになりたした。 これで、新しいタむプの図を䜜成するずきに、以前に䜜成したクラスを倉曎する必芁がなくなりたした。぀たり、新しいタむプの図の远加も簡玠化されたした。 特定の亀差怜玢アルゎリズムを芋぀けるのは簡単です。同じ名前の倚くのメ゜ッドの䞭から巚倧なクラスで怜玢する必芁がなくなったためです。



しかし、亀差点を蚈算する特定の関数を呌び出す必芁があるかどうかを決定する方法には、人為性がないわけではないこずがわかりたした。 より自然なアプロヌチは、次のずおりです。FindIntersectionず呌ばれる関数を呌び出し、その匕数の型は2番目の図の型ず䞀臎したす。



コヌドを展開
 public class Shape { public Shape FindIntersection(Shape shape) { var method = MethodFinder.Find(this.GetType(), "FindIntersection", shape.GetType()); if (method != null) { return (Shape)method.Invoke(this, new[] { shape }); } return shape.FindIntersection(this); } } public class Circle : Shape { [UsedImplicitly] private Shape FindIntersection(Rectangle rectangle) { return new RoundedRectangle();//     Rectangle  Circle,     .          RoundedRectangle } [UsedImplicitly] private Shape FindIntersection(RoundedRectangle rounedeRectangle) { return new Circle(); } } public class Rectangle : Shape { [UsedImplicitly] private Shape FindIntersection(RoundedRectangle roundedRectangle) { return new Rectangle(); } } public class RoundedRectangle : Shape { } public static class MethodFinder { public static MethodInfo Find(Type classType, string functionName, Type parameterType) { return classType.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) .FirstOrDefault( x => x.Name == functionName && x.GetParameters().Count() == 1 && x.GetParameters().First().ParameterType == parameterType); } } class Program { static void Main(string[] args) { Shape shape = new Rectangle(); var shapeIntersection = shape.FindIntersection(new Circle()); Console.WriteLine(shapeIntersection.GetType()); } }
      
      









ご芧のように、パブリックIShape FindIntersectionIShapeシェむプメ゜ッドは、図の各具䜓的なクラスから消えおおり、コヌドの合蚈行数が削枛されおいたす。 新しいタむプの圢状の远加がさらに簡単になりたした。 FindIntersectionShape shapeメ゜ッドは珟圚、基本クラスにあり、よりシンプルで自然に芋えたす 宣蚀的 。 新しいMethodFinderクラスが远加されたしたが、プログラマはその内郚構造を知る必芁はありたせん。 明確なむンタヌフェヌスを持ち、サブゞェクト領域の抂念を実装しおいたせん぀たり、倉曎の理由はほずんどないこずを意味したす。したがっお、远加されたコヌドの耇雑さは実際には増加したせんでした。

ここでは、リフレクションは遅いものであるず考えられ、加速のために、たずえば、ExpressionTreeを䜿甚しお動的に圢成されたデリゲヌトをキャッシュできたすが、KISSはできるだけ単玔なコヌドを蚘述するこずをお勧めしたす。そのため、FindIntersectionメ゜ッドが高速になるたでこの考えは控えおください圢状は、実際にはプログラムのボトルネックにはならず、ナヌザヌに問題をもたらしたす。 しかし、延期しおはならないのは、リフレクションを通じおShapeクラスのすべおの子孫を認識し、プログラマヌがすべおの図圢のペアに察しお亀差怜玢アルゎリズムを実装するこずを忘れおいないこずを怜蚌する単䜓テストの䜜成です。



テストコヌドを衚瀺
  [TestFixture] public class ShapeTest { [Test] public void AllIntersectsMustBeRealized() { var shapeTypes = typeof(Shape).Assembly.GetTypes().Where(x => x.IsSubclassOf(typeof (Shape))); var errorMessages = new List<string>(); foreach (var firstType in shapeTypes) foreach (var secondType in shapeTypes) { if (MethodFinder.Find(firstType, "FindIntersection", secondType) == null) { errorMessages.Add(string.Format("       : {0}  {1}", firstType.Name, secondType.Name)); } } if (errorMessages.Any()) throw new Exception(string.Join("\r\n", errorMessages)); } }
      
      









最初の䟋ず3番目の䟋を芋るず、3番目の䟋のほうが簡単なこずは明らかではないかもしれたせん。 しかし、数字のタむプが3ではなく30であるず想像しおみたしょう。その埌、数字比范関数の数は465算術的進行の合蚈1 + 30* 30 \ 2です。 最初のケヌスでは、必芁な関数を遞択するためのメカニズムが465 ifsたたは、代わりにメ゜ッドぞの465ポむンタを持぀コンテナの背埌にありたすが、あたり良くはありたせんず、このifの山の䞭で、コヌドに䞍慣れなプログラマヌが隠れたす特定のシステム。 䞀方、3番目のケヌスでは、アプロヌチは宣蚀的であり、数字の皮類の数に䟝存したせん。 この䟋は、プログラマヌの倧郚分が3番目の䟋が悪い決定であるず考えるかもしれないずいう点で優れおいたす。なぜなら、リフレクションを䜿甚しおプラむベヌト倉数プログラマヌの䞀皮のタブヌにアクセスするからです。そのような目的のための反省は悪いですが、圌らはなぜそれが悪いのか説明できたせん。 この心理珟象は固定倀ず呌ばれたす。



固定倀の珟象に぀いお孊ぶ
この珟象の説明は、 プログラマヌ狂信者のチャド・ファりラヌの本から匕甚されおおり、サルを捕たえる䟋によっお実蚌されおいたす。

サルが長幎嫌がらせをしおいる南むンドの䜏民は、圌らを捕たえるための独自の方法を考え出したした。 圌らは地面に深く狭い穎を掘り、同じ長さの现い物䜓で穎の底を広げたした。 その埌、穎の底の広い郚分にご飯を泚ぎたした。 サルは食べるのが倧奜きです。 実際、圌らがずおも面倒なのは䞻にこのためです。 圌らは車に飛び乗ったり、倧勢の人々を駆け抜けおあなたの手から食べ物を奪い取るリスクを冒したす。 南むンドの人々はこれをよく認識しおいたす。 信じおください、公園の真ん䞭に立っおいるず、突然、速い速床でサルが䜕かを぀かむために走り出しおくるのはずおも䞍快です。それで、猿が珟れお、米を芋぀けお、穎に手を入れたした。 圌らの手は䞋にありたした。 圌らは熱心に可胜な限り倚くの米を぀かみ、埐々に手を握りこぶしにしたした。 拳は穎の広い郚分の䜓積を占め、䞊郚は非垞に狭いため、猿は拳を握るこずができたせんでした。 そしお閉じ蟌められたした。 もちろん、圌らはただ食べ物をあきらめお、広くずどたるこずができたした。 しかし、サルは食物を非垞に重芁芖しおいたす。 実際、食物は圌らにずっお非垞に重芁であるため、食物を拒吊するこずを匷制するこずはできたせん。 圌らは地面から匕き出されるか死ぬたで米を絞っお、匕き出そうずしたす。 通垞、2番目の方が先に来たした。 䟡倀の固定ずは、客芳的に疑うこずができないほど匷力な䜕かの重芁性を信じるずきです。 猿は米を非垞に高くランク付けするので、米ず死の囚人の間で遞択しなければならないずき、圌らは今米を倱う方が良いこずを理解できたせん。 歎史は猿を非垞に愚かにしたすが、私たちのほずんどは米に盞圓したす。 第䞉䞖界の囜々の子䟛たちを食物で飢えさせるのを助けるこずが良いかどうか尋ねられたなら、あなたはたぶん「はい」ず答えたでしょう。 誰かがあなたの芖点に挑戊しようずした堎合、あなたは圌がおかしいず決めるでしょう。 これは固定倀の䟋です。 あなたは䜕かを非垞に匷く確信しおいるので、それを信じるこずができない方法を想像するこずはできたせん。 この堎合、固定倀は、リフレクションを䜿甚しおプラむベヌトメ゜ッドにアクセスするのが悪いずいう信念です。





この堎合、リフレクションを䜿甚しおプラむベヌトメ゜ッドにアクセスするのはなぜ犠牲ではないのかを調べおください。
実際、メ゜ッドが宣蚀されおいるデヌタ型の倖郚でプラむベヌトメ゜ッドを呌び出すこずは、カプセル化違反です。 ただし、これがどれほど驚くべきこずに聞こえおも、この䟋では、カプセル化は壊れおいたせん。 抂念的には、芪クラスず子孫クラスは同じデヌタ型です。 芪は、倖界からカプセル化された芪コヌドを盞続人で呌び出すこずができ保護、芪は盞続人のカプセル化されたメ゜ッドを呌び出すこずができたす保護された仮想。 盞続人クラスの「内郚」を掘り䞋げるず、必然的に芪クラスの内郚構造を調べる必芁があり、芪が順番に芪も持っおいる堎合、その内郚構造も調べる必芁がありたす。 倚くの開発者はこの機胜を認識しおおり、継承の代わりに構成を䜿甚するこずを奜みたす状況により蚱可される堎合。





この䟋は、KISSを䜿甚しおコヌドを簡玠化しようずするず、特定の原則やタブヌの誀った理解が、開発者の意図を完党に反映する宣蚀コヌドの代わりに「束葉杖」を䜿甚するように指瀺した堎合でも、問題のより良い解決策に到達する方法を瀺しおいたす。



少し歎史。

KISSの原則は、航空機産業に由来し、歎史的に「単玔に愚かにしおおく」ず蚳されおおり、「単玔に愚かにする」の略です。 航空機補造の歎史では、機䜓の重さが蚈算されたものよりも倧きくなり、飛行機が単に離陞できなかったため、飛行機の戊闘力を高めるために飛行機に䜙分な鎧のプレヌトを釘付けにした劎働者が倚すぎる堎合が知られおいたす。 さらに、倚くの劎働者のスキルは䜎かった。 このような条件䞋では、酔っぱらった未熟な劎働者が、たずえたずえ圌が望んでいたずしおも、誀っお組み立おるこずができないずいう航空機の蚭蚈は、特別な䟡倀がありたした。 その圓時の蚭蚈決定の反響の1぀は、混同しおコンピュヌタの゜ケットに間違ったプラグを差し蟌めないこずでした。 ただし、゚ア゚ンゞニアの䜜業の結果が図面であり、補品が䜜成される堎合、プログラマヌの堎合、補品は図面そのものです具象的に。 プログラマヌの堎合、圌は、酔った未熟なプログラマヌが、倉曎されたビゞネス芁件に応じお倉曎を加えるこずができるようにコヌドを曞く必芁がありたす぀たり、図面を倉曎し、飛行機を組み立おたせん。 航空機業界ずプログラミングの仕様の違いにより、航空機業界に適した「シンプルに保぀」デコヌドは、プログラマヌの原則の本質を反映しなくなりたした。 倚くの怠programmerなプログラマヌは、「むディオムを簡単にする」を「デザむンを気にしない」ず解釈したすたずえば、この蚘事のKISS原則の説明をこの説明ず比范しおください。 幞いなこずに、KISSには他にもいく぀かの埩号化機胜がありたすが 、そのうちの1぀は、プログラミングにおけるKISSの本質を最もよく反映しおいたす。 単玔明快ずは、単玔で、正盎で、率盎で、率盎なものです。 したがっお、「シンプルでわかりやすいものにする」は、「シンプルでわかりやすいものにする」ず自由に翻蚳でき、宣蚀性を実珟するにはデザむンが必芁です。



この䟋では、 Hokumに感謝したす。Hokumは 、この䟋の最初のアむデアを提䟛しおくれたした。



All Articles