在项目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();
}
你将如何解决这个问题? 使用单例模式?
谢谢
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);
让OrderService只是做事情的订单。 让ItemService只是做事情的物品。 然后创建它结合了两个OrderItemService。
是的,“单件模式”懒初始化一起就行了。 不要初始化服务在构造函数中,但在静态干将:
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
。 另见这个答案在这里 ,详细阐述了“双重检查锁定模式”(不过要小心,要得到这个权利!)
你可以分离出从构造“服务”?
或者换句话说,假设你有一个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;
}
或者可能以相反的方向?