1. ホーム
  2. java

[解決済み] Spring 3アノテーションでシンプルなファクトリーパターンを実装する

2022-03-06 02:47:27

質問

Spring 3 のアノテーションを使用して、シンプルなファクトリーパターンを実装する方法を考えていました。 ドキュメントで、ファクトリークラスを呼び出し、ファクトリーメソッドを実行するビーンを作成できることを見ました。 私は、これがアノテーションのみを使用して可能であるかどうか疑問に思っていました。

現在、あるコントローラで

MyService myService = myServiceFactory.getMyService(test);
result = myService.checkStatus();

MyServiceは、checkStatus()というメソッドを1つ持つインターフェースです。

私のファクトリークラスは次のようなものです。

@Component
public class MyServiceFactory {

    public static MyService getMyService(String service) {
        MyService myService;

        service = service.toLowerCase();

        if (service.equals("one")) {
            myService = new MyServiceOne();
        } else if (service.equals("two")) {
            myService = new MyServiceTwo();
        } else if (service.equals("three")) {
            myService = new MyServiceThree();
        } else {
            myService = new MyServiceDefault();
        }

        return myService;
    }
}

MyServiceOneクラスは次のようになります。

@Autowired
private LocationService locationService;

public boolean checkStatus() {
      //do stuff
}

このコードを実行すると、変数locationServiceは常にNULLです。 これは、ファクトリー内で私自身がオブジェクトを作成しているため、自動配線が行われていないためだと思います。 これを正しく動作させるためにアノテーションを追加する方法はありますか?

ありがとうございます。

解決方法は?

あなたの言う通り、手動でオブジェクトを作成することで、Springに自動配線をさせないようにしています。サービスの管理もSpringで行うことを検討してください。

@Component
public class MyServiceFactory {

    @Autowired
    private MyServiceOne myServiceOne;

    @Autowired
    private MyServiceTwo myServiceTwo;

    @Autowired
    private MyServiceThree myServiceThree;

    @Autowired
    private MyServiceDefault myServiceDefault;

    public static MyService getMyService(String service) {
        service = service.toLowerCase();

        if (service.equals("one")) {
            return myServiceOne;
        } else if (service.equals("two")) {
            return myServiceTwo;
        } else if (service.equals("three")) {
            return myServiceThree;
        } else {
            return myServiceDefault;
        }
    }
}

しかし、全体的なデザインはかなり貧弱だと考えています。いっそのこと、一般的な MyService を実装し one / two / three の追加パラメータとして文字列を指定します。 checkStatus() ? 何を実現したいのか?

@Component
public class MyServiceAdapter implements MyService {

    @Autowired
    private MyServiceOne myServiceOne;

    @Autowired
    private MyServiceTwo myServiceTwo;

    @Autowired
    private MyServiceThree myServiceThree;

    @Autowired
    private MyServiceDefault myServiceDefault;

    public boolean checkStatus(String service) {
        service = service.toLowerCase();

        if (service.equals("one")) {
            return myServiceOne.checkStatus();
        } else if (service.equals("two")) {
            return myServiceTwo.checkStatus();
        } else if (service.equals("three")) {
            return myServiceThree.checkStatus();
        } else {
            return myServiceDefault.checkStatus();
        }
    }
}

これは 今も を追加するのは、設計が悪い。 MyService の実装が必要です。 MyServiceAdapter も修正する必要があります(SRP違反)。しかし、これは実は良い出発点なのです(ヒント:MapとStrategyのパターン)。