リファクタリング — おっと、私はそれを間違ってやってきた.


このポストはJustinDFuller.com .
私の介入へようこそ.私はリファクタリング中毒です、そして、私はそれを認めるのを恐れません、しかし、1つの問題だけがあります:私は、それを後退させていました.参照してください、私がしてきたことは、より正確に未熟なコード抽象化として記述することができました.
我々はすべてリファクタリングについて知っている.場合でも、単一のプログラミング本を読んだことがある場合、または多くの時間を読んでコードのブログを読む場合は、すべてについて聞いているよ.これは、コードを理解し、維持し、拡張可能な重要な概念です.
少なくとも、それは誰でも私に話すものです.
では、なぜリファクタリングは私が望んでいたことを成し遂げなかったのでしょうか?
私の最近の図書館を書いたので、私は私のコードの進化を反映するために少しの時間を要しました.私は、私が完全に働く製品を持っていて、私が私の単体テストで理想的な出力をする前に、私が私が私が必要とすると確信さえしなかったインターフェースにコード化したと理解しました.私は周りのコードを移動し、それを拡張可能にし、再利用可能にしたが、なぜですか?そのコードは、私に私が必要とした最終的な出力を与えることになっていましたか?私はまだ知りませんでした.
結局すべてはうまくいきましたが、私のコードはもっと複雑になりました.そう信じます.

目的の原則
聞きましたかSOLID 原則私は、彼らを密接にフォローしようとします.私が書くあらゆる機能はa single responsibility . 私のクラスと工場はopen for extension while discouraging modification . 私はまた、あまりにも多くのことに直接依存しないようにしてください.I accept dependencies as arguments 関数とクラスで.
良いコードのレシピのようなものですか?そうだと思う.私のコードが固体であることに集中するとき、問題は起こります、あるいはpure , むしろ、それが生まれることを成し遂げるよりはむしろ.私が目的に関して原則を置くとき、問題は起こります.
例えば、私は確かに私のunit tests have no expensive IO (入出力)私は時々戻って、誤ってmockked依存のために間違っていたコードを修正しなければならなかった.
では、解決策は?
私が以前言及したその反射を覚えています?それは私にマントラを思い出させました.」Make it work, make it right, make it fast. ” 私は、私が注文していないとわかりました.私はそれを右に作ってきた、それを高速にし、それを作ること!

メイク・ワーク
私がもっと書き始めたとき、それは良い文章がちょうど起こらないことが明らかになった.まず最初に、私は私の考えをページの上に下ろしなければなりません.私は、私の考えがどこに私を連れて行くかについて見なければなりません.それから、私はそれらを形にしなければなりません.
同じことがコードで起こります.
そこにすべての機能を取得します.最初は命名、単一の責任、または拡張可能であることについてあまり心配しないでください.明らかに、あなたはこのようなアプリケーション全体を書くことはありません、1つだけ小さな作品.
したら、あなたが探している出力を持っている(あなたは、コードが正しいことを証明するために単体テストを持っている?)リファクタリングを開始するが、あまりにも高速すぎないでください!今のところ、適切な命名のカテゴリにあるリファクタリング戦略と固執し、1つだけのことを行う機能、および突然変異の回避;繰り返しパターンを特定するまで、拡張可能であるか再利用可能なクラスと工場をすぐに開始しないでください.
この時点で、論理的な利点を持つリファクタリングを使用することは意味があります.これは、信頼されているコードの目的、または信頼できるコードの目的でリファクタリングを意味します.
特定のシナリオでのみ有用なパターンで、リファクタリングを延期することを検討してください.
あなたが理由があるまでそれらを保存します.

理由がある
ソリッドコードを持っている理由ではない.機能的であるか純粋なコードを持つことは、理由でありません.
なぜ我々はコードを拡張可能にしますか?似ているが、同じではないので、機能は基本論理から分岐することができます.
なぜ依存関係を反転させるのか?ビジネスロジックを複数の実装で使用できるようにします.
うまくいけば、あなたは私がどこでこれに行っているかについて見ます.いくつかのリファクタリング独自のスタンド.たとえば、より正確になる変数の名前をリファクタリングすることは、常に意味をなすでしょう.そのメリットは固有です.副作用が予期しない問題を引き起こすことがありえるので、純粋に機能をリファクタリングすることは通常意味をなします.それは正当な理由です.
“依存性の反転を使用するのは最善の練習”理由ではありません.“良いコードは拡張可能です”理由ではありません.私はカップルの依存関係を変更することがありますか?依存性逆転はまだ必要ですか?おそらくまだない.何も私のコードを拡張する必要がある場合、私はそれを行うための何の計画もありませんか?私のコードは、この箱をチェックするだけで複雑さを増すべきですか?だめ!
次の例を見てください.
// not extensible

function getUser() {
  return {
    name: 'Justin',
    email: '[email protected]',
    entitlements: ['global', 'feature_specific']
  }
}

// used later

getUser().entitlements.includes['feature_specific']

// Extensible

class User {
  constructor() {
    // initialize here
  }

  hasEntitlement(expectedEntitlement) {
    return this.entitlements.includes(expectedEntitlement)
  }
}

// used later

new User().hasEntitlement('feature_specific')
どちらがお好きですか.あなたはまず最初に書く傾向がありますか.もちろん、他のクラスで上書きすることができるので、ユーザークラスははるかに拡張可能です.例えば、もしあなたがSuperUser その後、実装することができますhasEntitlement このように:
hasEntitlement() {
  return true
}
クラスにあなたを放さないでください.同じ結果はそれなしで達成できます.
function superUser(user) {
  return {
    ...user,
    hasEntitlement() {
      return true
    }
  }
}
いずれにせよ、このカプセル化hasEntitlement 別のユースケースでは、コードを変更するのではなく、拡張するために、多型を利用します.
それでも、そのユーザークラスは完全なoverkillであるかもしれません、そして、現在、あなたのコードはこれまでにある必要があるより複雑です.
私のアドバイスは、あなたがより複雑な何かの理由があるまで、最も簡単な可能なパターンに固執することです.上記のソリューションでは、複数のユーザータイプを持つまで、同じ単純なユーザーデータオブジェクトに固執することを選択できます.

複雑さの順序
そして今、あなたがそれを許すならば、私は何かを作るつもりです!私はそれを複雑さの順序と呼びます、そして、私がリファクタリング決定をするとき、それは私を助けます.次のようになります.
  • Constant Variable
  • Mutable Variable
  • Collection ( Object , array )
  • 機能
  • 機能付きClosure
  • ファクトリ(コレクションを返す関数)
  • クラス
  • 機能を整理する方法を決めるときはいつでも、リストを参照します.私は私の実装に十分な選択可能な選択を選択します.私はそれが単に動作しないまで再び選択しないでください.時々、パフォーマンスはこの選択に影響を及ぼしますが、しばしばありません.
    通常、私は、単純な定数変数の代わりにオブジェクトに何かを置くとわかります.または、私が機能を必要とするとき、私は工場をつくりました.
    このリストは私を接地している.それは私を早めのリファクタリングから防ぐ.

    バランス
    私は最近、あなたが会議で言うならば、「バランスを見つけることについてすべてです」と、あなたが意味がある何かを言ったように、誰でもあなたの無意味なコメントで彼らの頭をうなずきます.もうすぐやってみないと.
    でもここではバランスが大切だと思います.プログラマとして、我々は物事を成し遂げるために良い昔ながらのニーズとコード品質、パフォーマンス、保守性をバランスする必要があります.
    我々は警戒しなければならなくて、両方のニーズが彼らの正しい場所にとどまることを確認しなければなりません.正しく動作しない場合は、コードを管理できません.一方、悪いコードを正しく動作させるのは難しい.
    それでも、コードはリファクタリングされるかもしれません、しかし、それが有用であることのポイントを過ぎてリファクタリングされたならば、どうですか?これらは心に留めておくべき重要な質問です.
    次回、あなたのコードを書いてください、refactor!しかし、多分、多分?
    これは前哨のポストですwww.justindfuller.com .
    こんにちは、私はジャスティンフラーです.私は、あなたが私のポストを読んでとてもうれしいです!私はここで書かれているすべては私自身の意見であり、任意の方法で私の雇用主を代表するものではないことをお知らせする必要があります.すべてのコードサンプルは私自身で、完全に私の雇い主のコードに無関係です.
    私もあなたから聞くのが大好きですGithub または.読書のおかげで再び!