This lesson was translated automatically – it may contain errors.
Creating an object that reflects no entity of the domain, needed only to lower coupling, raise cohesion and make reuse easier.
Every object of the service layer is a pure fabrication – objects that talk to the database, for example.
Why invent entities
By Information Expert the order should save itself: it holds all the data. But then the domain object starts knowing about SQL, connections and transactions – cohesion drops and coupling grows.
The way out is to invent a class that does not exist in the domain:
// There is no «repository» in the domain – it is a pure fabrication,
// but the order knows nothing about the database
public class OrderRepository
{
public void Save(Order order) { }
public Order GetById(int id) => null;
}
// There is no «repository» in the domain – it is a pure fabrication,
// but the order knows nothing about the database
class OrderRepository {
public:
void Save(const Order& order) {}
std::optional<Order> GetById(int id) { return std::nullopt; }
};
// There is no «repository» in the domain – it is a pure fabrication,
// but the order knows nothing about the database
type OrderRepository struct{}
func (OrderRepository) Save(order Order) error { return nil }
func (OrderRepository) GetByID(id int) (Order, error) { return Order{}, nil }
# There is no «repository» in the domain – it is a pure fabrication,
# but the order knows nothing about the database
class OrderRepository:
def save(self, order: Order) -> None:
pass
def get_by_id(self, order_id: int) -> Order | None:
return None
// There is no «repository» in the domain – it is a pure fabrication,
// but the order knows nothing about the database
class OrderRepository {
save(order: Order): void {}
getById(id: number): Order | null {
return null;
}
}
// There is no «repository» in the domain – it is a pure fabrication,
// but the order knows nothing about the database
public class OrderRepository {
public void save(Order order) { }
public Order getById(int id) {
return null;
}
}
// There is no «repository» in the domain – it is a pure fabrication,
// but the order knows nothing about the database
class OrderRepository {
fun save(order: Order) = Unit
fun getById(id: Int): Order? = null
}
This is the case where the GRASP principles argue with each other, and Pure Fabrication settles the argument in favour of maintainability.