Вопрос по java, constructor, circular-reference – Круговые ссылки на Java

2

В проекте, над которым я работаю, люди написали класс служб для доступа к DAO. Почти каждый бизнес-объект имеет свой собственный сервис, который использует его собственный DAO. На некоторых сервисах мы используем ссылки на другие сервисы. В настоящее время люди создают необходимые службы внутри конструктора.

Но теперь у меня возникли проблемы, потому что сервис A нуждается в сервисе B, а сервис B - в сервисе A, поэтому вызов любого конструктора приводит к переполнению стека

Пример (псевдокод):

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

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

Как бы вы решили это? используя шаблон синглтона?

Спасибо

Ваш Ответ

4   ответа
1

о работает с предметами. Затем создайте 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;
  }
}

КакДжонатан заявилВы также можете внедрить сервисы в другие сервисы, но это может не понадобиться. Если синхронизация может привести к проблеме с памятью, вы можете решить эту проблему, используяvolatile, Смотрите такжеэтот ответ здесьуточняющий «шаблон блокировки с двойной проверкой»; (будьте осторожны, чтобы понять это правильно!)

4

Короче говоря, он создает экземпляры всех 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);
К сожалению, я не могу использовать Sprint Framework в этом проекте (не мой вызов, глупые правила администрирования). Estragon
Затем сделайте это вручную, т.е. создайте OrderService, ItemService. Тогда есть OrderService.setItemService (itemService); и ItemService.setOrderService (orderService);
0

Или, другими словами, предположим, что у вас есть OrderService, и он должен обратиться к своей личной копии ItemService. Нужен ли этот экземпляр ItemServiceit's Собственная копия 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; 
}

Или, возможно, в обратном направлении?

Похожие вопросы