Course program← Объектно ориентированное программирование
1История ООП
2Объект и Класс
3Базовые концепции ООП
4Принцип проектирования GRASP
5Принцип проектирования SOLID
6Паттерны GOF
7Методические материалы

Pure Fabrication

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.