Java的循环引用(Java circular references)

2019-06-25 08:30发布

在项目IM工作的人写的服务类访问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();
}

你将如何解决这个问题? 使用单例模式?

谢谢

Answer 1:

Spring框架解决了使用依赖注入这个问题。 总之,它的作用是实例所有的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);


Answer 2:

让OrderService只是做事情的订单。 让ItemService只是做事情的物品。 然后创建它结合了两个OrderItemService。



Answer 3:

是的,“单件模式”懒初始化一起就行了。 不要初始化服务在构造函数中,但在静态干将:

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 。 另见这个答案在这里 ,详细阐述了“双重检查锁定模式”(不过要小心,要得到这个权利!)



Answer 4:

你可以分离出从构造“服务”?

或者换句话说,假设你有一个OrderService,它需要请教ItemService的自己的个人副本。 这是否会ItemService情况下需要它的 OrderService的自己的副本来满足来自OrderService调用它的要求?

因此,这将是一种懒惰的初始化 - 不要创建新的项目,除非和直到你真正需要它。 除非和直到你需要它没有连接起来的附加服务。

第二个想法:你可以传递一个副本作为构造的一部分吗?

例如:

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

或者可能以相反的方向?



文章来源: Java circular references