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 框架通过使用依赖注入解决了这个问题。简而言之,它所做的就是实例化所有 DAO,然后在实例化之后,但在主要业务逻辑之前设置 dao-dependencies。

如果您必须手动执行此操作,这里有一个示例:

/*
  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 只处理项目。然后创建一个将两者结合的 OrderItemService。

于 2012-05-14T09:28:56.123 回答
0

Can you separate out the "service" from the Constructor?

Or in other words, lets say you have an OrderService and it needs to consult its own personal copy of an ItemService. Will this ItemService instance need it's own copy of the OrderService to fulfill the request from the OrderService calling it?

Thus, it would be a sort of lazy initialization--don't create the new item unless and until you actually need it. And don't link up the additional service unless and until you need it.

Second idea: can you pass a copy as part of the Constructor?

e.g.:

//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; 
}

Or possibly in the reverse direction?

于 2012-05-14T09:45:27.117 回答
0

是的,“单例模式”以及延迟初始化就可以了。不要在构造函数中初始化服务,而是在静态 getter 中:

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 回答