4

class Commandバッファ内のコマンドを順番に表すために使用している一般的な問題があります。ComputeCommandDefineCommand、などのいくつかの子クラスもありますDisplayCommand。各サブクラスのコンストラクターはString引数を取り、コマンドはコマンド構文に従って解析します。コマンド構文はコマンドの種類ごとに異なります。

私は次のようなことができるようにしたい:

String [] lines = { ... };
ArrayList<Command> commands = new ArrayList<Command>();
for(String line: lines){
    commands.add(new Command(line))
}

ただし、各コマンドを処理できるようにするには、より特殊なクラスが必要です。

コンストラクターを次のように定義できるとします。

Command(String line){
    if(ComputeCommand.isValidComputeCommand(line))
        return new ComputeCommand(line);
    else if(DisplayCommand.isValidDisplayCommand(line))
        return new DisplayCommand(line);
    [ ... ]
}

それは私が必要とすることを達成するでしょうが、私たち全員が知っているように、コンストラクターはそのようには機能しません。

私が考えた1つの方法は、次のようなメソッドを含めることです

static Command getInstance(String line){ [...] }

その機能を実行するためですが、この状況でそれが正しいアプローチであるかどうかはわかりません。

別の可能な方法は、それぞれのファクトリ クラスを作成することです。

class CommandFactory(){
    CommandFactory [] subFactories = {new ComputeCommandFactory(), [...]};
    Command makeCommand(String line){
        for(CommandFactory subFactory: subFactories)
            if(subFactory.canMake(String line))
                return subFactory.makeCommand(line);
    }
    boolean canMake(String line){
        for(CommandFactory subFactory: subFactories)
            if(subFactory.canMake(String line))
                return true;
    }
}

これはこれを行うための最も正確な方法かもしれないと思いますが、より良い方法がある場合、余分な複雑さを追加したくありません.

この状況で使用する正しい設計パターンは何ですか?

編集: また、いくつかのコマンドをさらにサブクラス化する予定です。たとえば、またはサブクラスComputeCommandを持つことができます。AddCommandMultiplyCommand

4

4 に答える 4

1

私が読んでいるのは、コンテキストに基づいて正しいオブジェクトを構築したいということですか? 文字列があり、その文字列の内容から正しいオブジェクトを構築したいですか?

CommandBuilder/Factory を持つことができ、そこに if-else ロジックを配置して正しいコマンドを返すことができます。

public Command buildCommand(String line){
    if(ComputeCommand.isValidComputeCommand(line))
        return computeCommandFactory.buildCommand(line);
    else if(DisplayCommand.isValidDisplayCommand(line))
        return displayCommandFactory.buildCommand(line);
    [ ... ]

}

ビルダーまたは抽象ファクトリを使用して、必要な Command オブジェクトを構築したいようです。if-else if チェーンが大きい場合は、通常、戦略パターンを使用します。

于 2013-09-30T16:43:22.520 に答える
1

やりたいことをやるにはFactoryとパターンの組み合わせが必要だと思います。Chain of Responsibility

interface CommandFactory{
    Command create(String line);

    void addToChain(CommandFactory next);
}

ファクトリが指定された行を処理できない場合、チェーン内の次のファクトリにその行を渡します。

class ComputeCommandFactory{


    CommandFactory next;

    Command create(String line){
        if(<can process>){
           return new ComputeCommand(line);
        }
        if(next ==null){
          throw Exception("can't process");
        }
        return next.create(line);
     }

 }

このようにして、後で (実行時であっても) 新しいファクトリを追加できます。これは、クラスローダとデータベース ドライバの追加が Java でどのように機能するかに似ています。

于 2013-09-30T17:13:28.950 に答える