私は20年間、建築の多様性を楽しんでいます。私の考えを共有したいと思います。





最初は「C#で10年間ひどいアーキテクチャに苦しんでいた...という記事にコメントを書きたかったのですが、2つのことに気づきました。



  1. 共有するにはあまりにも多くの考えがあります。
  2. このようなボリュームの場合、コメント形式は書き込みまたは読み取りのいずれにも不便です。
  3. 私は長い間Habrを読んでいて、時々コメントしますが、記事を書いたことがありません。
  4. 番号付きリストは得意ではありません。


免責事項:私は@pnovikovまたは彼の考え全般を批判していませんテキストは高品質で(私は経験豊富な編集者のように感じます)、私は私の考えのいくつかを共有します。多くのアーキテクチャがありますが、それは問題ありません(はい、韓国映画のタイトルのように聞こえます)。 



しかし、順番に見ていきましょう。まず、アーキテクチャに影響を与えるものについての私の意見、次に「アーキテクチャの修正」に関する記事の論争点について。また、私たちにとって何がうまくいくかについても説明します-多分それは誰かに役立つでしょう。



そしてもちろん、ここで述べられていることはすべて、私の経験と認知的偏見に基づく個人的な意見です。



私の意見について



私はよく建築上の決定をします。一度大きく、一度小さく。たまに、アーキテクチャを最初から思いつくことがあります。まあ、まるでゼロからのように-確かにすべてが私たちの前に発明されましたが、私たちは何かについて知らないので、私たちは発明しなければなりません。そして、自転車作りへの愛情からではなく(たとえば、自転車作りへの愛情からだけでなく)、一部のタスクでは、すべてのパラメーターに適合する既製のソリューションがなかったためです。



完全に異なるアーキテクチャが存在する権利があると私が信じるのはなぜですか?プログラミングは工芸ではなく芸術であると推測する人もいるかもしれませんが、私はそうは思いません。私の意見:かつては芸術、かつては工芸品。それについてではありません。主なことは、タスクが異なるということです。そして人々。明確にするために、タスクはビジネス要件です。



いつか私のタスクが同じタイプになった場合、私は誰かに私に取って代わるニューラルネットワーク(またはスクリプトで十分かもしれません)を書くか、書くように頼みます。そして、私自身はもっと暗いことをします。私と、あなたの個人的な黙示録が来ないことを願っていますが、タスクやその他の条件がさまざまなアーキテクチャにどのように影響するかを考えてみましょう。TL&DR; -さまざまです。



パフォーマンスとスケーラビリティ



これはおそらく、アーキテクチャを変更する最も正しい理由です。もちろん、古いアーキテクチャを新しい要件に適合させる方が簡単でない限り。しかし、ここでは、何か有用なことを簡単に伝えることは困難です。



タイミング



用語(「o」で書いたことを2回確認した)が非常にタイトだとしましょう。そうすれば、アーキテクチャを考え出すことは言うまでもなく、選択する時間がありません。使い慣れたツールを使って掘り下げてください。しかし、微妙な違いがあります。複雑なプロジェクトは、根本的に新しいものを適用する(そしておそらく発明する)ことによってのみ、時間どおりに実行できる場合があります。顧客を浴場に招待するのは古いテクニックだと言う人もいるかもしれませんが、今は建築について話しています...



タイミングが快適なとき(逆説的な状況になることがよくあります)、何か新しいことを思いつくことができるようですが、なぜですか?確かに、多くの人は、別のより燃えているプロジェクトを引き受けて、状況を前のプロジェクトに減らしたいという誘惑に首尾よく屈服します。



私の実践では、タイミングがアーキテクチャの革命につながることはめったにありませんが、それは起こります。そして、それは素晴らしいことです。



開発のスピードと品質



それはそうなります-チーム(または管理者の誰か)は、開発速度が遅くなった、または多くのバグが反復中に実行されたことに気づきます。多くの場合、「間違ったアーキテクチャ」がこれを非難します。時々-当然です。より頻繁に-最も便利な被告人と同じように(特にチームに彼女の「親」がいない場合)。



原則として、場合によっては、すべてが時間的要因に帰着します。そして他の人では-保守性のために、後でそれについて。



メンテナンス性



あいまいなトピック。すべてが非常に主観的であり、何に大きく依存するからです。たとえば、チーム、プログラミング言語、社内のプロセス、さまざまなクライアントへの適応の数などです。最後の要素について話しましょう、それは私にとって最も興味深いようです。



これで、カスタムプロジェクトが作成されました。成功裏に、時間通りに予算内で、顧客はすべてに満足しています。私もこれを持っていました。今、あなたはあなたが使ったものを見て考えます-それでここにあります-金鉱です!現在、これらすべての開発を使用しており、1つのB2B製品をすばやく作成し、...最初はすべて問題ありません。製品は製造され、数回販売されました。より多くのベンダーと開発者を雇いました(「より多くの金が必要」)。顧客は満足し、サポートにお金を払い、新しい販売が起こります...



そして、顧客の1人が人間の声で言います-「私はこれをまったく異なる方法で行ったでしょう-それはどれくらいの費用がかかりますか?」まあ、考えてみてください-異なるコードのチク(たとえば、DIをねじ込む時間がなかった)の場合、いくつかの悪いことが起こり得ますか?



そして初めて、本当に悪いことは何も起こりません。私はそのような状況で何か特別なものを囲うことさえ勧めません。アーキテクチャの時期尚早な複雑化は、時期尚早の最適化に似ています。しかし、2回目と3回目に発生する場合は、DI、「戦略」パターン、機能の切り替えなどを覚えておく必要があります。そして、しばらくの間、それは役に立ちます。



そして、特定のテストベンチのプロジェクト設定(数百のオプションのみ)を見る日が来ます...組み合わせの数を数える方法を覚えて、考えてください-あなたの母親、これをどのようにテストできますか?理想的な世界では、これが単純であることは明らかです。結局のところ、各機能は、他の機能に影響を与えないように設計および実装されています。影響がある場合は、これらすべてが提供され、一般に、開発者が間違ったことはありません。



もちろん、色を濃くしました。実際の顧客が使用する機能のセットを強調表示し、さらにテストを記述して(どの方法で、どのテストが別の会話のトピックになるか)、タスクを少し単純化できます。しかし、考えてみてください。すべてのメジャーリリースをすべての顧客に対してテストする必要があります。これはB2Cではないことを思い出してください。「ユーザーの5%に機能を展開し、フィードバックを収集する」と言えます。B2Bの場合、裁判所からフィードバックの収集を開始できます...



解決策?たとえば、製品を個別のライフサイクルを持つモジュールに分割します(相互作用のテストを忘れないでください)。これにより、開発が複雑になりますが、メンテナンスの複雑さが軽減されます。そして今、私はホリバーの肥沃なトピックについて話していません。マイクロサービス "-モノリスでは、同様のものを配置することもできます(私の意見では、より複雑ですが)。



そして、実用的な観点から、すべての段階で、私たちは優れたアーキテクチャを持っていたことを忘れないでください。



そして、これは何のためですか?



アーキテクチャが変更された他の理由を挙げて、あなた(そして私自身)を疲れさせたくありません。ここで、アーキテクチャは多くの要因に応じて時間とともに変化する傾向があることに同意しましょう。つまり、「まあ、すべての問題」を解決する理想的なアーキテクチャは存在しません。



これについてまだ納得していない場合は、さまざまなプログラミング言語とフレームワークを確認してください(フロントエンドではなく、このトピックを開く必要はありません)。これが悪いと誰かが言った場合は、思考実験を行うことをお勧めします。特定のプログラミング言語が1つある世界を想像してみてください。1つの重要な条件で-あなたはそれが好きではありません。たとえば、使用したことがなく、使用するつもりもなかったためです。



そして、私は認めます、別の正当な理由があります-何か新しいものを考え出し、いくつかのパラメータを最適化し、妥協して遊んでいます-それはとても楽しいです。さて、私たち全員(右?)は、アーキテクチャの多様性は大丈夫だということに同意します...



「アーキテクチャの修正」に関する記事のディスカッション



IoCはどうですか?



IoCについて私は、フットクロスが軍隊に存在し、モジュールが普遍的に優れていることに同意します。しかし、残りはここにあります...



もちろん、「クリーンなコード」について謝罪者の話を聞く場合は、サービスの山をコーディングできます。各サービスには、平均1.5のメソッドがあり、メソッドには2.5行があります。しかし、なぜ?正直なところ、あなたは間違いなく、遠い将来に起こりそうもない問題に対処するのに役立つ原則に従いたいと思っていますが、数十のファイルにまたがる単純なロジックさえも塗りつぶしますか?それとも、きちんと機能するコードを今すぐ書くだけで十分ですか? 



ちなみに、今は間違いなくさまざまな製品で使用され、おそらく積極的に「調整」されるモジュールに取り組んでいます。そこで私は「浅く」しないようにしています。報われない。その中で私は通常より頻繁にインターフェースの唯一の実装を使用しますが。



では、モジュールがあり、「ささいな」ものではない場合、IoCのパフォーマンスの問題やサポートされていない「IoC構成のフットクロス」はどこから来るのでしょうか。私は出くわしていません。 



ただし、作業条件を明確にします。



  • 私たちのモジュールは、「ほとんどすべてのIoCフレームワークによって提供される」モジュールではなく、APIを介してリモートで相互に通信する「直接モジュール」です(パフォーマンス上の理由から、1つのプロセスにまとめることができますが、作業スキームは変更されません)。

  • IoCは、可能な限り単純かつ可能な限り単純に使用されます。依存関係は、コンストラクターのパラメーターに固定されます。

  • はい、マイクロサービスアーキテクチャができましたが、ここでは小さすぎないようにしています。 



ヒント:インターフェイスはクラスと同じファイルに保持できます。便利です(もちろん、メモ帳ではなく通常のIDEを使用する場合)。インターフェイス(またはそれらへのコメント)が大きくなると、例外を作成します。もちろん、これはすべて味です。



ORMの何が問題になっており、データベースに直接アクセスするのはなぜですか? 



はい、私自身が何が悪いのかを言います-それらの多くはSQLから遠すぎます。すべてではありません。したがって、「O / RMが3000個のオブジェクトを削除する間、耐える」または別のオブジェクトを考え出す代わりに、自分に合ったオブジェクトを見つけてください。



ヒント:LINQ toDBを試してくださいバランスが取れており、複数行の更新/削除メソッドがあります。ただ注意してください-中毒性があります。はい、EFの機能はなく、コンセプトも少し異なりますが、EFの方がずっと好きでした。



ちなみに、これが私たちの同胞の発展であるのは素晴らしいことです。Igor Tkachev-敬意を表します(Habréでは見つかりませんでした)。



UPD: RouRコメントの中で、一括操作を可能にするEFCoreの拡張機能があることに注意してくださいLINQ to DBは良いので、とにかくあきらめません



データベーステストの何が問題になっていますか?



はい、メモリ内のデータよりも遅くなります。それは致命的ですか?いいえ、もちろん違います。この問題を解決する方法は?同時に使用するのに最適な2つのレシピを次に示します。



レシピ番号1。あなたはあらゆる種類のクールなことをするのが大好きなクールな開発者を連れて行き、この問題を美しく解決する方法について彼と話し合います。ラッキーだから見た目よりも早く問題を解決しました(話し合ったかどうかさえ覚えていません)。どうやって?操作の主要なサブセットを配列へのアクセスに置き換えるORMのテストファクトリを(1日で)作成しました。



簡単なユニットテストに最適です。別のオプションは、「大規模な」データベースの代わりにSQLiteまたは同様のものを使用することです。

コメント : . -, , ORM, , SQL . -, , , , , .. . .



レシピ番号2。私は実際のデータベースでビジネスシナリオをテストすることを好みます。また、プロジェクトが複数のDBMSをサポートする機能を宣言している場合、テストは複数のDBMSに対して実行されます。どうして?簡単だ。「データベースサーバーをテストしたくない」というステートメントには、残念ながら、概念の置き換えがあります。私は、参加が機能するか、注文するかをテストしていません。



DBで動作するコードをテストしています。また、同じDBMSの異なるバージョンでも、同じクエリで異なる結果が生成される可能性があることを知っているので(証明)、このコードが機能するデータベースで主なシナリオを正確に確認したいと思います。



通常、このようなテストは次のようになります。



  • テストのグループ(Fixture)の場合、データベースメタデータを使用して最初から生成されます。必要に応じて、必要な参考書に記入します。

  • 各スクリプトは、通過中に必要なデータを単独で追加します(ユーザーも追加します)。パフォーマンステストではそうではありませんが、それはまったく別の話です...

  • 各テストの後、余分なデータ(リファレンスブックを除く)は削除されます。



アドバイス:そのようなテストが長期間客観的に実行される場合(データベースへのクエリを最適化するときではないため)、それらを実行する頻度が少ないビルドを作成します(テストカテゴリまたは別のプロジェクトが役立ちます)。そうでなければ、開発者は残りを実行したくないでしょう-クイックテスト自体。



トランザクションと電子メール



「何らかの理由でデータベース内のトランザクションが失敗し、電子メールが消えた」という話に追加します。システム全体を焚き時に使用できないメールサーバのトランザクションを待ち、そして、それはユーザーが読んで...なしバスケットに送信するためにいくつかの通知をどう楽しみになります



確かに、私はいつもそれだけで6月を信じ野生でのトランザクションで送信手紙レビューがない場合。そのようなカンデラブラムのための私たちのチームでは、彼らは(これまでのところ仮想的に)打ち負かしました。



結果



一般に、@ pnovikovアーキテクチャの唯一の真のイデオロギーの助けを借りて世界を引き継ぐ計画がない場合、言及する価値のある他の違いは見つかりませんでした。もちろん、いくつかのタスクには、彼が表明した原則が適しています。以下の記事やコメントを読んで喜んでいます。自分にとって役立つアイデアが見つかるかもしれません。



提案されたフレームワークはほとんど使用しません。理由は簡単です-私たちはすでに理想的なアーキテクチャ



を持っています... PSコメントで何かを議論したい場合は、私はそれに参加してうれしいです。



All Articles