4
public interface iUserInfo
{
    string getUserName(int userId);
    string getUserAge(string username);
}

public class UserDb implements iUserInfo
{
    string getUserName(int userId)
    {
        //code to retrieve user info from the database
    }
}

public class UserTxtFile implements iUserInfo
{
    string getUserName(int userId)
    {
        //code to retrieve user info from the plain text file
    }
}

public class UserManager()
{
    private iUserInfo userInfo;

    public string retrieveUserData(string userName)
    {
        return userInfo.getUserAge(userName);
    }
}

私の教授は言う

「上記のユーザー マネージャー クラスには iUserInfo 型の参照変数があるため、この参照がファクトリ メソッドまたはその他の手段によって提供される場合、マネージャー クラスのコードは、提供される実装に関係なく同じになります。

このアプローチは、ソフトウェア開発の過程で一部の実装を変更する必要がある場合に、より高いレベルのレイヤーがまったく影響を受けないため、柔軟性を最大限に高めます。」

理解しておく必要があることが 2 つあります。柔軟性の最大化とファクトリーメソッド。

後者はこんな感じかもしれません

public class UserManager()
{
    private iUserInfo userInfo;
    private UserTxtFile  uTxtFile;
    private UserDb uDB;
    public iUserInfo GetUserInfoObjFactory(bool dbOrTxt)
    {
        return dbOrTxt? uTxtFile:uDB;
    }
    public string retrieveUserData(string userName)
    {
        return userInfo.getUserAge(userName);
    }
}

講義中、私は他のことについて空想にふけっていましたが、今ではそれが何を意味するのか理解できません。一部のインタビュアーが、答え方がわからない未解決の質問で私を攻撃する可能性がある場合に備えて、もう少し詳しく理解したいと思います.

高レベルのレイヤーが影響を受ける場合の例で、上記のソースを壊すコードを追加していただけますか? 本当にありがとうございました。

[更新]「一般的なメソッドをグループ化するためのインターフェイスが必要です」などの回答も、あまり説得力がありません。抽象基本クラスだけでも役立ちます。たとえば、2 つのオブジェクト {Penguin vs Bird} からの Fly 動作。インタビュアーに IFly が必要だと簡単に言うことはできません。Fly を必要とする何百万もの異なるオブジェクトがある場合でも、それぞれの Fly をいつでも実装できます。IFly を設計する場合でも、実装クラスでそれを行う必要があるためです。より詳細なケースを提供するか、インターフェイスがどのように必須になるかを再度説明してください。

4

3 に答える 3

1

インターフェイスの必要性について。

空港のディスパッチャを実装する必要があると仮定しましょう。空港空間のオブジェクトと相互作用し、位置と空気の状況に関するコマンドを提供します。このコマンドのセットは明確に定義されており、空間内のオブジェクトのタイプに依存しません(すべきではありません)。ディスパッチャは位置を知る必要があり、着陸を許可し、着陸を拒否し、着陸を遅らせ、緊急コース修正を発行できる必要があります。これを可能な限り簡単に実装および保守できるように、すべての「航空機」に実装する一種のインターフェースを定義します。

次にAirportDispatcher、インターフェースを一般的な方法で実装するオブジェクトのセットで動作するを作成できます。これは、実装方法(ヘリコプターは所定の位置で待機できますが、飛行機は待機中に周回する必要があります)や航空機のタイプを知らなくても機能します。あなたが知っておくべきことは、それが飛んで、あなたの命令に従うことができるということだけです。

interfaceこれはJavaの観点からではなく、単なる契約であり、実装方法は言語の可能性にのみ依存することに注意してください。動的またはダックタイプの言語は構文上の制約なしにそれを行うことができますが、静的タイプの言語は追加の作業が必要になります。

インターフェイスと抽象クラスがあります。インターフェイスと抽象クラスの主な違いは、1つのオブジェクトに複数のインターフェイスが存在する可能性があることですが、抽象クラスは1つだけです(これはすべての言語での方法ではありませんが、共通の分母です)。また、インターフェイスには実装を含めることはできませんが、抽象クラスには実装を含めることができます。

于 2012-08-05T08:57:15.677 に答える
0

教授の講義は疎結合を意味し、例はBridge PAtternを参照しています。

もっと詳しく:

クラスは、UserManagerビジネス ロジックとルールを適用してデータを処理し、保存して取得する必要があります。このクラスは、ある場所との間でデータを保存および取得する必要があることだけを知っている必要がありますが、汚い仕事をする責任はありません。iUserInfo代わりに、データの保存と取得を処理するオブジェクト (インスタンス) を用意します。このオブジェクトはどのようにこの仕事をしますか? UserManagerクラスには関係ありません。これは疎結合です。

さて、なぜこの仕事を処理するインターフェース/抽象クラスでなければならないのでしょうか? テキスト ファイル、xml ファイル、リレーショナル データベース、メモリ内データベース、外部デバイスなど、さまざまなデータ ソースを使用できるためです。クラスでデータ ソース ハンドラを直接呼び出すことはできませUserManagerん。代わりに、別のクラスがこの正確な実装を提供します。この場合、抽象クラスまたはインターフェースによって処理される抽象化を使用する必要があります。抽象クラスとインターフェイスは、クライアントが使用できるメソッドを確立するコントラクトですが、必ずしもメソッドの実装ではありません。これはどのように機能しますか?例を確認しましょう:

public interface iUserInfo {
    //the client (any class that uses the interface) knows that can get the UserName
    //and the UserAge, it doesn't need to know how...
    string getUserName(int userId);
    string getUserAge(string username);
}

public class UserDb implements iUserInfo
{
    string getUserName(int userId)
    {
        //this implementation will connect to database to get the data
    }
}

public class UserTxtFile implements iUserInfo
{
    string getUserName(int userId)
    {
        //this implementation will read from a text file to get the data
    }
}

ここまでで、クラスUserDbUserTxtFileクラスがダーティな作業を処理します。ここUserManagerで、データがどこに保存されるかを知ってはならないので、息をのむことができます。しかし、別の質問があります: データを取得するためにどの実装をUserManager使用する必要がありますか?

ファクトリ メソッドは、ファクトリ メソッド パターンの実装であり、クライアントはどの実装を使用すべきかを認識してはならず、代わりにファクトリが構成または別のビジネス ルールに基づいて決定を下します。つまり、UserManagerアクセスも実装も定義する必要がないため、クラスは安心して休むことができます。いいですね。さて、例として、ファクトリメソッドとして機能する単純なメソッドがあります

//it will return the iUserInfo implementation based in a boolean variable
//this could become more complex depending on the rules, like retrieving the boolean
//value from a configuration file
public iUserInfo GetUserInfoObjFactory(bool dbOrTxt)
{
    return dbOrTxt? uTxtFile:uDB;
}

より詳しい情報:

于 2012-08-05T08:51:18.287 に答える