3

取り組んでいるプロジェクトでは、人々はDAOにアクセスするためのサービスクラスを作成しました。ほとんどすべてのビジネスオブジェクトには、独自のDAOを使用する独自のサービスがあります。一部のサービスでは、他のサービスへの参照を使用しています。現在、人々はコンストラクター内で必要なサービスをインスタンス化しています。

しかし、サービスAにはサービスBが必要であり、サービスBにはサービスAが必要であるため、問題が発生しました。いずれかのコンストラクターを呼び出すと、スタックオーバーフローが発生します...

例(擬似コード):

//Constructor of OrderService
public OrderService() {
     orderDAO = DAOFactory.getDAOFactory().getOrderDAO();
     itemService = new ItemService();
}

//Constructor of ItemService
public ItemService() {
     itemDAO = DAOFactory.getDAOFactory().getItemDAO();
     orderService = new OrderService();
}

これをどのように解決しますか?シングルトンパターンを使用していますか?

ありがとう

4

4 に答える 4

4

Spring Frameworkは、依存性注入を使用してこの問題を解決します。つまり、すべてのDAOをインスタンス化し、インスタンス化後、メインのビジネスロジックの前にdao依存関係を設定します。

これを手動で行う必要がある場合の例を次に示します。

/*
  OrderService
 */
public OrderService ()
{
     orderDAO = DAOFactory.getDAOFactory().getOrderDAO();
}

public setItemService (ItemService service)
{
     itemService = service;
}

/*
  ItemService
 */
public ItemService ()
{
     itemDAO = DAOFactory.getDAOFactory().getItemDAO();
}

public setOrderService (OrderService service)
{
     orderService = service;
}

/*
   Bring it together in some other class
 */
...
// instantiate singletons
orderService = new OrderService ();
itemService = new ItemService ();

// inject dependencies
orderService.setItemService (itemService);
itemService.setOrderService (orderService);
于 2012-05-14T09:27:36.847 に答える
1

OrderServiceに注文を処理させます。ItemServiceにアイテムを処理させるだけです。次に、2つを組み合わせたOrderItemServiceを作成します。

于 2012-05-14T09:28:56.123 に答える
0

はい、怠惰な初期化と一緒に「シングルトンパターン」で十分です。コンストラクターではなく、静的ゲッターでサービスを初期化します。

class OrderService {
  private static OrderService instance;
  private OrderDAO orderDAO;

  public OrderService() {
    orderDAO = DAOFactory.getDAOFactory().getOrderDAO();
  }

  public static synchronized OrderService getInstance() {
    if (instance == null) {
      instance = new OrderService();
    }

    return instance;
  }
}

ジョナサンが述べたように、他のサービスにサービスを注入することもできますが、それは必要ないかもしれません。同期によってメモリの問題が発生する傾向がある場合は、を使用してこれを解決できますvolatile「ダブルチェックされたロックパターン」について詳しく説明しているこの回答も参照してください(ただし、これを正しく行うには注意してください)。

于 2012-05-14T09:37:52.377 に答える
0

「サービス」をコンストラクターから分離できますか?

つまり、OrderServiceがあり、ItemServiceの独自の個人用コピーを参照する必要があるとします。このItemServiceインスタンスは、それを呼び出すOrderServiceからの要求を満たすために、OrderServiceの独自のコピーを必要としますか?

したがって、これは一種の怠惰な初期化になります。実際に必要になるまで、新しいアイテムを作成しないでください。また、必要になるまで、追加のサービスをリンクしないでください。

2番目のアイデア:コンストラクターの一部としてコピーを渡すことができますか?

例えば:

//Constructor of OrderService public OrderService() 
{     orderDAO = DAOFactory.getDAOFactory().getOrderDAO();
      itemService = new ItemService(this); 
}
//Constructor of ItemService public ItemService(OrderService orderService) 
{     itemDAO = DAOFactory.getDAOFactory().getItemDAO();
      this.orderService = orderService; 
}

またはおそらく逆方向に?

于 2012-05-14T09:45:27.117 に答える