Reputation:
I have two service classes. WarehouseManagementService provides methods to administrate warehouses and stocks. SalesManagementService provides methods to manage customers and their orders.
To create an order, it is necessary to check, if the order item quantity is sufficient. For this I would use the method availableStock(Product p) in the WarehouseManagementService. But I do not know, how to call this method properly.
Do I have to create an instance of WarehouseManagementService in SalesManagementService? Or should I add the WarehouseManagementServiceInterface to the SalesManagementService constructor (dependency injection)?
What could a good architecture look like, to achieve a loose coupling of these two classes?
Thanks in advance.
public class WarehouseManagementService implements WarehouseManagementServiceInterface {
private DatabaseReadWarehouseInterface dbRead;
private DatabaseWriteWarehouseInterface dbWrite;
public int availableStock(Product p) {
// returns available quantity of product
}
}
public class SalesManagementService implements SalesManagementServiceInterface {
private DatabaseReadSalesInterface dbRead;
private DatabaseWriteSalesInterface dbWrite;
public void addOrder(Order o) {
// creates order, if product quantity is sufficient
}
}
Upvotes: 3
Views: 9952
Reputation: 5815
You have the right feeling: The dependency should be injected. Just remember the Single Responsibility Principle: "A class should have only one reason to change".
By constructing WarehouseManagementService
in SalesManagementService
, you would add a second reason for SalesManagementService
to change: When the way of constructing your WarehouseManagementService
changes.
To solve it, you could either use a full-blown Dependency Injection framework, or simply start by adding a constructor parameter to SalesManagementService
:
public class SalesManagementService implements SalesManagementServiceInterface {
private DatabaseReadSalesInterface dbRead;
private DatabaseWriteSalesInterface dbWrite;
private WarehouseManagementServiceInterface warehouseManagementService;
constructor(DatabaseReadSalesInterface dbRead,
DatabaseWriteSalesInterface dbWrite,
WarehouseManagementServiceInterface warehouseManagementService) {
this.dbRead = dbRead;
this.dbWrite = dbWrite;
this.warehouseManagementService = warehouseManagementService;
}
public void addOrder(Order o) {
// creates order, if product quantity is sufficient
}
}
Then in your main
method, take care of instantiating WarehouseManagementService
and pass it to SalesManagementService
.
As a sidenote, you might want to move the construction of SalesManagementService
and WarehouseManagementService
into factories which give you a SalesManagementServiceInterface
and a WarehouseManagementServiceInterface
rather than the concrete classes ("program to interface, not implementation").
Upvotes: 5