コードは生きていて死んでいます。 パート1 オブジェクト

コードは思考です。 問題が発生し、開発者はそれを解決する方法、関数とクラスで要件を表現する方法、それらを友達にする方法、厳密さと正確さを達成する方法、ビジネスを復avenする方法を考えます。 実践、技術、原則、パターン、アプローチ-すべてを考慮する必要があり、すべてを覚えておく必要があります。







これに伴い、マネージャー、ヘルパー、サービス、コントローラー、セレクター、アダプター、ゲッター、セッター、その他の悪霊が広まっています。これはすべてデッドコードです。 彼は足etterと雑然とした。







このように戦うことを提案します。プログラムを自然言語のテキストとして提示し、それに応じて評価する必要があります。 これとどうなるかは記事にあります。







サイクルの目次



  1. オブジェクト
  2. アクションとプロパティ
  3. テキストとしてコード


プロローグ



私の経験はささやかなものです(約4年)が、仕事をすればするほど理解が深まります。プログラムが読めない場合は意味がありません。 それは長い間知られており、思い出させるためにbeatられました-コードは現在いくつかの問題を解決するだけでなく、 後でも:それはサポートされ、拡張され、修正されました。 さらに、彼は常に:読んでください。







結局のところ、これはテキストです。







テキストとしてのコードの美学は、サイクルの重要なテーマです。 ここの美学とは、物事を見て、いい、いい、美しい、と言うグラスです。







美と理解の問題では、言葉は非常に重要です。 「現時点では、血中のエタノール濃度が高いために私の知覚は鈍い状態にあります」、「 酔っぱらった」とはまったく異なります。







私たちは幸運なプログラムであり、ほぼ完全に言葉で構成されています。







「健康とマナを持ち、歩く、攻撃する、呪文を使用するキャラクター」を作成する必要があるとしましょう。すぐに見ることができます: オブジェクト (キャラクター、健康、マナ、呪文)、 アクション (歩く、攻撃、使用)およびプロパティ (キャラクターの体力、マナ、呪文のspeed唱速度など)-これらはすべて名前になります:クラス、関数、メソッド、変数、プロパティ、フィールド、一言で言えば、プログラミング言語が分割するすべて。







しかし、クラスを構造から区別し、フィールドをプロパティから、メソッドを関数から区別しません:物語の一部としての文字は、技術的な詳細(参照または重要なタイプのいずれかで表現できる)に依存しません。 本質的に異なるもの:これはキャラクターであり、彼らは彼をHero



(またはCharacter



)と呼び、 HeroData



またはHeroUtils



はないHeroData



HeroUtils









さて、私はまさに美学のグラスを取り上げて、今日のコードがどのように書かれているのか、なぜ完璧からはほど遠いのかを示します。







オブジェクト



C#では(だけでなく)、オブジェクト-ヒープに配置され、しばらくそこに存在し、その後ガベージコレクターがそれらを削除するクラスのインスタンス。 スタックまたは連想配列、またはその他の構造を作成することもできます。 私たちにとっては、クラス名、名詞です。







コード内の名前は、一般的な名前と同様、混乱を招く可能性があります。 はい、見苦しい名前はめったに見ませんが、美しいオブジェクトです。 特にManager



場合。







オブジェクトの代わりにマネージャー



UserService



AccountManager



DamageUtils



MathHelper



GraphicsManager



GameManager



VectorUtil









ここで支配するのは正確性と具体性ではなく、霧の中にどこかに残る曖昧なものです。 そのような名前の場合、多くは許容されます。







たとえば、 GameManager



では、 ゲームおよびゲームロジックに関連するものを追加できます。 6か月後、技術的な特異点があります。







または、Facebookで作業する必要があります。 FacebookManager



またはFacebookService



すべてのコードを1か所に配置してみませんか? それは誘惑的に単純に聞こえますが、そのようなあいまいな意図は、同様にあいまいなソリューションを作成します 。 同時に、Facebookにはユーザー、友人、メッセージ、グループ、音楽、興味などがあることがわかっています。 十分な言葉!







十分な言葉があるだけでなく、私たちはまだそれらを使用しています。 プログラム間ではなく、通常のスピーチでのみ。







そして、それはGitUtils



ではなく、 IRepository



ICommit



IBranch



です。 ExcelHelper



ではなく、 ExcelDocument



ExcelSheet



GoogleDocsService



ではなく、 GoogleDocs



です。







すべてのサブジェクト領域はオブジェクトで満たされています。 「オブジェクトは巨大なボイドによってマークされていました」「心臓は猛烈に鼓動していました」「家は立っていました」 -オブジェクトは機能し、感じ、想像しやすいです。 彼らはここのどこかに、有形で密集しています。







同時に、あなたは時々これを見ます: Microsoft/calculator



リポジトリ-メソッドを持つCalculatorManager



SetPrimaryDisplay



MaxDigitsReached



SetParentDisplayText



OnHistoryItemAdded



...







(それでも、 UtilsManager



見たことが UtilsManager



ます...)







このようになります。新しい動作でList<>



タイプを拡張したいのですが、 ListUtils



またはListHelper



が生まれました。 この場合、拡張メソッドListExtensions



のみを使用する方がより適切で正確ListExtensions



。これらは概念の一部であり、プロシージャからのダンプではありません。







数少ない例外の1つは、投稿としてのOfficeManager



です。







それ以外の場合...プログラムにそのような単語が含まれている場合は、コンパイルしないでください。







オブジェクトの代わりのアクション



IProcessor



ILoader



ISelector



IFilter



IProvider



ISetter



ICreator



IOpener



IHandler



; IEnableable



IInitializable



IUpdatable



ICloneable



IDrawable



ILoadable



IOpenable



ISettable



IConvertible









ここで、本質の本質は概念ではなく手順であり、コードは再びイメージと読みやすさを失い、通常の言葉は人工的な言葉に置き換えられます。







IEnumerable



ではなく、より活気のあるものはISequence



です。 IBlueprint



ではなくICreator



IButton



ではありませIButtonPainter



IFilter



ではなくIPredicate



IGate



ではなくIOpeneable



IToggle



ではなく、 IEnableable









良い話は、キャラクターがどのように作成し、ビルダーが構築し、ペインターが描くかではなく、キャラクターとその開発について語っています。 アクションはオブジェクトを完全に表すことはできません。 ListSorter



ListSorter



はありません。







たとえば、ファイルシステム上のフォルダーをクリーンアップするオブジェクトであるDirectoryCleaner



を取り上げます。 エレガントですか? しかし、「フォルダークリーナーにD:/ Testをクリーンアップするように依頼する」 、常に「D:/ Testにクリーンアップする」とは決して言わないので、 Clean



メソッドを使用したDirectory



はより自然に近くなります。







より活気のあるケースは、より興味深いものですFileSystemWatcher



は、変更を報告するファイルシステムオブザーバーです。 しかし、なぜ変化そのものが起こったと報告できるのであれば、なぜオブザーバー全体なのでしょうか? さらに、これらはファイルまたはフォルダーと密接にリンクしている必要があるため、 Directory



またはFile



配置する必要がありFile



Changes



プロパティを使用してfile.Changes.OnNext(action)



を呼び出すことができます)。







このような口頭の名前は、 「アルゴリズムのファミリをカプセル化するように指示するStrategy



設計パターンを正当化するようです。 しかし、 「アルゴリズムのファミリ」ではなく、ストーリーに存在する本物のオブジェクト見つけた場合、戦略は単なる一般化であることがわかります。







これらおよび他の多くのエラーを説明するために、哲学に目を向けます。







存在は本質に先行する



MethodInfo



ItemData



AttackOutput



CreationStrategy



StringBuilder



SomethingWrapper



LogBehaviour









そのような名前は一つのことで結ばれています:それらの存在は詳細に基づいています。







何かがタスクにすぐに干渉することが起こります。何かが欠落しているか、または存在していますが、何かではありません。 次に、 「Xを行う方法を知っているものが今私を助けるだろう」と考えます。これが存在の構想です。 次に、Xを「実行」するために、 XImpl



が書き込まれます。これがエンティティの表示方法です。







したがって、 IArrayItem



代わりに、 IIndexedItem



またはIItemWithIndex



がより一般的です。たとえば、Reflection APIでは、 メソッドMethod



)の代わりに、それに関する情報MethodInfo



)のみが表示されます。







もっと真の方法:存在の必要性に直面し、それを実装するエンティティを見つけ 、そしてこれがその性質であるため、他のエンティティ。







たとえば、中間インスタンスを作成せずにstring



型の値を変更したいと考えていました。これはStringBuilder



の形式の簡単なソリューションであることが判明しましたが、私の意見では、より適切MutableString









ファイルシステムを思い出してください: DirectoryRenamer



フォルダーの名前を変更する必要DirectoryRenamer



ません。Directoryオブジェクトの存在に同意するとすぐにアクションがその中にあるため、コード内で対応するメソッドが見つからないためです。







ロックの取得方法を説明する場合、 ILockBehaviour



またはILockStrategy



を指定する必要はありませんILockBehaviour



またはILockStrategy



方がはるかに簡単ですILock



IDisposable



を返すAcquire



メソッドを使用)またはICriticalSection



Enter



)。







ここで、すべての種類のData



Info



Output



Input



Args



Params



(あまり頻繁にはState



)は、一方的なものと見なされたため、動作がまったくないオブジェクトです。







存在が主である場合、商は共通のものと混同され、オブジェクトの名前は紛らわしいです-各行を読み、キャラクターがどこに行ったのか、なぜ彼のData



だけがあるのか​​を把握する必要があります。







奇妙な分類



CalculatorImpl



AbstractHero



ConcreteThing



CharacterBase









上記と同じ理由で、階層内の場所が正確に示されているオブジェクトが表示される場合があります。 繰り返しますが、存在は急いでいます。また、結果を考慮せずに、差し迫った必要性がコードに急いでこぼれたことがわかります。







結局のところ、実際に人( Human



)がいますか?ベースの人( HumanBase



)の相続人ですか? しかし、 Item



AbstractItem



継承する場合はどうですか?







時々、 Character



ではなく、ある種の「生の」類似性-CharacterRawがあることを示したいことがあります。







Impl



Abstract



Custom



Base



Concrete



Internal



、Raw-不安定性の兆候、建築の曖昧さ。これは、最初のシーンの銃のように、後で確実に撃ちます。







繰り返し



ネストされたタイプでは、これは起こりRepositoryItem



RepositoryItem



Repository



Window



WindowState



Hero



HeroBuilder









繰り返しは意味をカットし、欠陥を悪化させ、テキストの複雑さのみに寄与します。







冗長部品



スレッドを同期するには、次のAPIでManualResetEvent



がよく使用されます。







 public class ManualResetEvent { //   —  `EventWaitHandle`. void Set(); void Reset(); bool WaitOne(); }
      
      





個人的には、 Set



Reset



(不快な文法)とどのように異なるか、およびストリームを操作する場合の「手動でリセットするイベント」とは何であるかを常に覚えておく必要があります。







そのような場合、プログラミングから遠く離れたメタファーを使用する方が簡単です(ただし、日常生活に近い):







 public class ThreadGate { void Open(); void Close(); bool WaitForOpen(); }
      
      





混乱することは確かにありません!







時々ばかげたことになる: オブジェクトは単なるItems



ではなく、必然的にItemsList



またはItemsDictionary



あることを明確にしている!







ただし、 ItemsList



面白くない場合は、 Springの AbstractInterceptorDrivenBeanDefinitionDecorator



ItemsList



ません。 この名前の単語は、巨大なモンスターが縫い付けられるぼろです。 しかし...これがモンスターである場合、次に何をHasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor



ますかHasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor



遺産を願っています







クラス名とインターフェイス名に加えて、変数またはフィールドの冗長性にしばしば遭遇します。







たとえば、タイプIOrdersRepository



フィールドはIOrdersRepository



と呼ばれ_ordersRepository



。 しかし、注文がリポジトリによって送信されたことを報告することはどれほど重要ですか? 結局のところ、はるかに簡単です_orders









また、LINQクエリでは、たとえばPlayer.Items.Where(item => item.IsWeapon)



などのラムダ式の完全な引数名を書き込みますが、 Player.Items.Where(item => item.IsWeapon)



を見ることでこの項目を既に理解していPlayer.Items



。 そのような場合、私は常に同じ文字x



Player.Items.Where(x => x.IsWeapon)



を使用するが好きPlayer.Items.Where(x => x.IsWeapon)



これらが関数内の関数である場合、 y



z



続きます)。







合計



私は、そのような始まりから客観的な真実を見つけることは容易ではないことを認めます。 例えば、誰かが言う: Service



を書くか書かないかは論争点であり、重要ではなく、良い味であり、それが機能する場合の違いは何ですか?







しかし、使い捨てカップから飲むことができます!







コンテンツへのパスはフォームを介して行われると確信しており、思考を考慮しない場合は存在しないようです。 プログラムテキストでは、すべてが同じように機能します。スタイル、雰囲気、およびリズムは、混乱せずに、明確かつ容量的に自分自身を表現するのに役立ちます。







オブジェクトの名前は、その顔だけでなく、自分自身でもあります。 それは、それがエーテルであるか飽和しているか、抽象的であるか本物であるか、ドライであるかアニメーションであるかを決定する。 名前は変化しています-コンテンツは変化しています。







次の記事では 、このまさにその内容とそれが起こることについて話します。








All Articles