内部APIへの変更が他のプロジェクトを壊すのを防ぐ方法は?


8

20〜30の独立したモジュール/ソリューションがあります。これらのそれぞれには、クラス、コンポーネントなどが異なる7〜10のプロジェクトがあります。これらはすべて社内で使用されます。

私たちの問題は、1つのモジュールに変更を加える場合、このコードにアクセスしている他のすべてのモジュールを確実に更新する必要があることです。コードベースが異なるため、これを知るのは困難です。

APIのすべての外部使用がどこにあるかをどのように文書化できますか?あるいは、小さな変更が他のモジュールを壊すのを防ぎますか?



6
APIの変更がコードを壊すのを防ぐ方法は?うーん... APIを変更しないでください。本当に、それ以外にどんな答えがあるでしょうか?

@ dan1111 APIに変更を加える必要があり、他のどのモジュールを壊すのかわからない場合、これをどのようにして防ぐことができますか。メソッド名を取得して、ハードディスク上のコードベースファイルを検索します。効率的な方法ではありません。それを行う
数学

コードベースでメソッド呼び出しを検索する際の何が問題になっていますか?何が何を使用しているかのドキュメントがない場合、これは非常に良い方法です。すべてのコードですべてのAPI呼び出しを検索し、これについて報告する小さなスクリプトを簡単に作成できます。

1
詳細を教えてください。どのプログラミング言語?ソースコードの互換性は大丈夫ですか、それともバイナリ互換性が必要ですか?「既存のAPIシグネチャを変更しない」で、新しいメソッドシグネチャを追加するだけで問題が解決しますか?あなたの言語は "defaultparameters"をサポートしていますか
k3b '21

回答:


13

最も簡単なソリューションであるIMOは、各製品に対して適切な数の自動テストを行うことです。ライブラリを更新するときは、各製品のテストスイートを実行します。テストが失敗した場合は、更新が必要な製品がわかります。


5

これを(少なくとも手動で)文書化しようとするのはお勧めしません。まるでそれを更新するように人々に要求する場合、正しく機能するには高レベルの精度が必要になるからです。しかし、この種のドキュメントを追加するのは面白くないし、誰もそれをしないため、このレベルの正確さは得られません。

いくつかのより良いオプション:

  • 検索基準に基づいて、他のすべてのモジュールのすべてのメソッド呼び出しの使用可能なリストを生成するスクリプトを用意します。シンプルで粗野ですが、おそらく効果的です。
  • メジャーバージョン番号を除いて、下位互換性を壊さないある種のバージョンシステム。したがって、メソッドfooをバージョン2.1から2.2に変更しても、バージョン2.Xを参照するすべてのコードは引き続き機能します。この互換性を解除する必要がある場合は、メジャーバージョン番号(この場合は3.0)をアップグレードし、他のモジュールを担当するすべてのプロジェクトオーナーに通知してください。リリースプロセスのしくみによっては、これを実装するのが簡単な場合もあれば、信じられないほど複雑な場合もあります。
  • コードをプッシュするたびにビルドがある種のテストを実行する自動テストまたはCIビルドプロセスがあります。これにより、問題が発生した場所を特定できます。私が推測しているのは、あなたがこれをすでに備えていない問題としてあなたが説明していることです。
  • すべてのモジュール/リポジトリ用のある種の自動ドキュメントシステム

また、APIをゆっくりとリファクタリングすることでそれほど脆弱にならないようにすることもできますが、個人で20以上の大規模なモジュールを扱う場合は、合理的に達成できることの範囲を超えていると思います。


1
バージョニングの+1、およびセマンティックバージョニング
xpy

2

まず、外部で使用するAPIは変更しないでください。

@BryanOakleyが述べたように、自動化された単体テストを使用することは非常に重要であり、そのような状況では命を救います。さらに、状況に応じて役立つ(または状況によってはそうでない)いくつかの提案

  • 多くの言語(JavaやC#など)が提供していますFunction/Method Overriding。Pythonのような言語では、(無制限の)引数とキーワード引数を関数に渡すことができます。

    Java:

    public void disp(char c)
    {
         System.out.println(c);
    }
    
    public void disp(char c, int num)  
    { 
         System.out.println(c + " " + num);
    }
    
    disp("A")
    disp("A", 3)

    パイソン

    def disp(c, *args):
        if args:
            num = args[0]
            print("%s %f" % (c, num))
        else:
            print("%s" % c)
    
    disp("A")
    disp("A", 3)
  • 多くの言語publicprivateprotectedメソッドが提供されています。関数内で関数呼び出しを処理し、関数内でpublicジョブをprivate/protected実行できます。

    Pythonでは、メソッドと関数のパブリック/プライベート定義はありませんが、先頭のアンダースコア(_)は、メソッドがプライベートであり、外部で使用してはならないことを示しています。外部API呼び出しは外部に開かれたメソッドによって渡され、すべてのタスクはいわゆるローカル関数で実行されます。

    def format_input(a, b, *args, **kwargs):
        # This function is open to anyone. so use *args and **kwargs to get
        # all possible available arguments. Do not change this function
        # definition and function parameters
        a = _evaluate_input(a)
        b  =_evaluate_input(b)
        # c is not used by all APIs and may not documented in all external
        # API docs. So chech if it was sent as a keyword argument. If yes
        # evalaute it too
        if "c" in kwargs:
            c  =_evaluate_input(kwargs.get("c"))
        _check_extra_arguments(args)
        _check_extra_keyward_arguments(kwargs)
    
    def _evaluate_input(value):
        # This is a private method thus should not be called from the
        # outside world. You can change this method and parameter structure 
        # to fit your needs and do not care for outside world since no
        # outer API should use this function directly.
        ...
    
    def _check_extra_arguments(value):
        # We will check if any extra argument is passed and handle them accordingly
        ...

私が言ったように、外部アプリケーションによって(も)使用されるAPI定義はそれほど頻繁に変更されるべきではありません。現在の状態を壊すことなくAPIの動作を変更できるように、外部関数をより柔軟にする方法を探すことができます。


1

私たちの問題は、1つのモジュールに変更を加える場合、このコードにアクセスしている他のすべてのモジュールを確実に更新する必要があることです。コードベースが異なるため、これを知るのは困難です。

これを知るのは不可能だと思います。

あなたはコンポーネントとそのインターフェースに責任があります。
あなたはそれらを利用する可能性のあるものすべてに対して責任を負いません

APIのすべての外部使用がどこにあるかをどのように文書化できますか?あるいは、小さな変更が他のモジュールを壊すのを防ぎますか?

簡潔な答え?テスト。

公開されたインターフェイスを実行するテストを記述します。変更を加えたら、それらを再実行してください。テストが「合格」である限り、何も壊れていません。テストが失敗した場合(およびテストが失敗した場合)、(a)問題を見つけて修正するか、(b)変更を正当なものとして正当できる場合は、それに対応するようにテストを書き直します。


0

関数パスや名前にバージョン番号が含まれているAPIを見てコード化しました。

このようにして、完全なAPIとAPI内の関数のさまざまなバージョン-さまざまなAPIバージョンを利用できます。

これにより、すべてのAPIバージョンをAPIのコードに保持する作業が行われます。新しいAPI機能が作成されたコード以外のアプリケーションのコードを変更する必要はありません。

これは、組織外のアプリケーションで使用されるAPIを作成するときに特に重要だと思います。

例として、bulksms apiを使用してSMSを送信するコードサンプルを次に示します。

http://developer.bulksms.com/eapi/code-samples/csharp/send_sms/

そこから行があります:

string url = ".../submission/send_sms/2/2.0";

2と2.0はAPIのバージョン番号です。

このAPIは多くのBulk SMSの顧客が使用することを目的としているため、このAPIを変更すると、多くのアプリケーションが壊れ、サポート電話がフックから外れる可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.