Given the following toy problem involving the design of some shipping business. The business consists of multiple types of facilities, e.g. a Warehouse, and a ShippingCenter. class Facility: def __init__(self, facility_id, address): self.facility_id = facility_id self.address = address ... # More generic facility attributes and functions class Warehouse(Facility): def __init__(self, facility_id, address, storage_space): super().__init__(facility_id, address) self.storage_space = storage_space self.inventory = [] def store_item(self, item): if self.storage_space >= item.size(): self.inventory.append(item) self.storage_space -= item.size() def retrieve_item(self, item): ... # retrieve item and free storage space class ShippingCenter(Facility): def __init__(self, facility_id, address, drivers, sorting_belts): super().__init__(facility_id, address) self.drivers = drivers self.sorting_belts = sorting_belts def ship_item(self, item, customer): ... # ship stuff This design worked well, until we add a HybridFacility that can do both storage and shipping: class HybridFacility(Warehouse, ShippingCenter): def __init__(self, facility_id, address, storage_space, drivers, sorting_belts): # Not quite sure how to make the initialization work. # Nevertheless, it's ugly due to diamond-shaped dependency The addition of the HybridFacility which inherits from both Warehouse and ShippingCenter which both inherit from Facility, introduces a Diamond problem. I'm looking for a better way to model this. Here is my attempt: # ======= Different facility types class WarehouseType: def __init__(self, storage_space): self.storage_space = storage_space self.inventory = ... class ShippingCenterType: def __init__(self, drivers, sorting_belts): self.drivers = drivers self.sorting_belts = sorting_belts class HybridType(WarehouseType, ShippingCenterType): def __init__(self, storage_space, drivers, sorting_belts): WarehouseType.__init__(self, storage_space) ShippingCenterType.__init__(self, drivers, sorting_belts) # ======= Different facilities each with their own type class Facility: def __init__(self, facility_id, address, facility_type): self.facility_id = facility_id self.address = address self.facility_type = facility_type ... # More generic facility attributes and functions class Warehouse(Facility): def __init__(self, facility_id, address, storage_space): super().__init__(facility_id, address, WarehouseType(storage_space)) def store_item(self, item): if self.facility_type.storage_space >= item.size(): self.facility_type.inventory.append(item) self.facility_type.storage_space -= item.size() def retrieve_item(self, item): ... # retrieve item and free storage space class ShippingCenter(Facility): def __init__(self, facility_id, address, drivers, sorting_belts): super().__init__(facility_id, address, ShippingCenterType(drivers, sorting_belts)) def ship_item(self, item, customer): ... # ship stuff class HybridFacility(Facility): def __init__(self, facility_id, address, storage_space, drivers, sorting_belts): super().__init__(facility_id, address, HybridType(storage_space, drivers, sorting_belts)) Here is a potential main method: def main(): warehouse = Warehouse("W1","address1", 10) shipping_center = ShippingCenter("D1","address2", 5, 3) hybrid_facility = HybridFacility("H1","address3", 5, 2, 2) facilities = [warehouse, shipping_center, hybrid_facility] print("Shipping centers:") # Should print D1 and H1 for facility in facilities: if isinstance(facility.facility_type, ShippingCenterType): print(f"Shipping center: {facility.facility_id}, address: {facility.address}") While this new implementation solves the Diamond problem, its rather verbose, and it also seems weird to access class attributes through the FacilityType, e.g. hybrid_facility.facility_type.drivers. Any suggestions for improvement? Any design patterns that would work well? Update: while I did the effort to propose a solution that solves the Diamond problem, I don't know whether this is a reasonable solution, or whether a seasoned software developer would instantly reject this solution. Continue reading...