2012-05-14 56 views
2

在項目IM工作的人寫的服務類訪問DAO。 幾乎每個業務對象都有自己的服務,它使用自己的DAO。 在某些服務上,我們使用對其他服務的引用。 目前,人們在構造函數中實例化所需的服務。Java的循環引用

但現在,我有麻煩,因爲服務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(); 
} 

你會如何解決這個問題?使用單身模式?

謝謝

回答

3

Spring框架通過使用依賴注入來解決這個問題。簡而言之,它的作用是實例化所有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); 
+0

不幸的是我沒有辦法在這個項目中使用Sprint框架(不是我的調用,愚蠢的管理規則) – Estragon

+1

然後手動執行它,即:創建OrderService,ItemService。然後有OrderService.setItemService(itemService);和ItemService.setOrderService(orderService); – Jonathan

1

讓OrderService只是做事情的訂單。讓ItemService只對項目做些事情。然後創建一個將這兩者結合的OrderItemService。

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

由於Jonathan stated,你也可以注入服務的其他服務,但可能並不需要。如果同步容易導致內存問題,則可以使用volatile來解決此問題。請參閱this answer here,詳細闡述「雙重檢查鎖定模式」(請小心,但要正確!)

0

您能從構造函數中分離出「服務」嗎?

或者換句話說,假設你有一個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; 
} 
在相反的方向

或可能?