web-dev-qa-db-ja.com

関数をリファクタリングする方法は?

Jsonとファイルパスの両方からプロジェクトのデータを読み込む関数が必要だとしましょう。最初に頭に浮かぶのは、次のような2つの関数を持つことです。

def load_project_from_json(json_data):
    ...

def load_project_from_path(path):
    with open(path) as f:
        load_project_from_json(f.read())

しかし、次に、たとえば単一の関数だけで両方のタスクを達成する方が便利かもしれないかどうかを考えていました。

def load_project(path_or_json)

多くの尋問が私の頭に浮かびます。例えば:

  • 関数を複数の関数に分解するのが便利かどうかはどのようにしてわかりますか?

  • 関数が「良い」関数かどうかをどのように判断できますか?

  • sRP後の機能ですか?

質問:関数からすべての責任を抽出するのに役立つ体系的な方法(一連のステップまたはルール)はどれですか?主な理由は、任意の関数の品質を判断する方法を学ぶことです(無料の関数とクラスメソッドのどちらについて話している場合でも)。そうすることで、リファクタリングが必要かどうかを判断できます。

NS:体系的な方法で方程式を単純化することを考えると、一連の規則に従うと、方程式をさらに単純化できない点に到達できます。同様に、 d関数をこれ以上リファクタリングできない場合に適用できるルールを知りたい。類推が意味をなすことを願っています

3
BPL

1つの関数をファイルからロードし、別の関数をJSONからロードすることは、まったく理にかなっています。これがあいまいな状況で(複数の場所で)アプリケーションが見つかった場合は、3番目の関数を追加して、ファイルまたはJSONの形式を決定するロジックのレプリケーションを削除できます。

基本的に、load_project(file_or_json)がファイルかどうかを検出し、適切なメソッドを呼び出す3つすべてがあります。

def load_project(path_or_json)
  if os.path.exists(path_or_json):
     return load_project_from_path(path_or_json)
  else:
     return load_project_from_json(path_or_json)

利点:

  1. 何かがファイルパスまたはJSONであるかどうかをテストする集中化された場所

  2. 発信者が違いを知らないときに使用すると便利です

  3. doの形式を知っていても、明示的な関数がまだあります

  4. テストを最適化できます。ファイルシステムを呼び出す代わりに、それがJSONであるかどうかを確認するために簡単な正規表現テストを行うことにしたかもしれません(結局、いくつのファイル名が{または[文字で始まるのでしょうか?)

  5. load_project関数が形式の決定を担当するため、引き続き単一責任主体を遵守します。他の2つの関数は、特定の形式からの読み込みを担当します。

2
Greg Burghardt

一般に、関数から副作用を削除すると、理想的には最初から何もないはずです、関数が同じタスクを実行している場合次に、動的またはダックタイピング言語では、単一の関数にリファクタリングしない理由はありません。

同様に、2つ以上の関数が実行している処理の大部分が、コードのその部分またはそれらの部分を一般的な関数に削除する非常に良いケースがある場合があります。特定の関数で異なるタイプのファイルをロードするが、共通の関数でコンテンツを操作する。

動的型付けのない言語では、タイプセーフティはしばしば異なるタイプの重複コードが必要であることを意味します。コードを保存するためにタイプセーフティを弱めるのはbadの考え方です。一部の言語には、使用できる型の特定のサブセットで関数を操作できるバリアントメカニズムがあり、またはもちろん、基本クラスが共通の機能を提供するクラスにリファクタリングすることは良いアイデアですが、過剰-数百のクラスがあり、それぞれに約10行のコードが含まれているコードを見たことがあります。このコードは、3つのファイルに3000行以上の単一の機能が複製されているのとほぼ同じです(両方の例同じ著者によるものでした)

もちろんC++では、および他のいくつかの言語を可能にするテンプレートの概念がありますpotentially、何百ものクラス/関数を作成します-それぞれ技術的にタイプセーフ-自動的に。

1
Steve Barnes