The main point of this part of the chapter is to understand the two ways of implementing a function that supports multiple data types. You either implement a function that is able to handle all types, or you implement the function polymorphically.
Lets look at this from the perspective of a financial data processing application which converts DTOs into Domain Objects, which is a completely random example that I just made up in my mind:
Procedural Code
```cs
interface FinancialDTO { }
class StockBuyDTO : FinancialDTO { }
class StockSellDTO : FinancialDTO { }
class StockPositionDTO : FinancialDTO { }
class FinancialImporter {
public FinancialObject ImportFinDto(FinancialDTO dto) {
if (dto instanceof StockBuyDTO) {
return new StockBuy(...);
} else if (dto instanceof StockSellDTO) {
return new StockSell(...);
} else if (dto instanceof StockPositionDTO) {
return new StockPosition(...);
}
}
}
```
There are multiple problems with this implementations that can be solved by using polymorphism:
- The interface is useless
- If you add a new type, the code inside the `FinancialImporter` will not be able to handle the new Type
- You might get the ridiculous idea that adding a third type of object, which mimics the inheritance hierarchy of the already duplicate hierarchy of `FinancialDTOs` and `FinancialObjects` , whose sole purpose is to convert a concrete `FinancialDTO` to a concrete `FinancialObject`, then creating a huge list with all of them and then iterating over the list to find the matching concrete `FinancialDTOImporter` for a specific `FinancialDTO` instead of just doing the instance check like a sane person
If we implement this code polymorphically, we fix all three of those problems at the same time.
Polymorphic Code
```cs
interface FinancialDTO {
FinancialModel ToModel();
}
class StockBuyDTO : FinancialDTO {
public FinancialModl ToModel() {
return new StockBuy(...);
}
}
class StockSellDTO : FinancialDTO {
public FinancialModel ToModel() {
return new StockSell(...);
}
}
class StockPositionDTO : FinancialDTO {
public FinancialModel ToModel() {
return new StockPosition(...);
}
}
```
*But should the DTO really know about the details of the model? Shouldn’t we keep them separate?*
Personally, I don’t really see the advantage of it. If you *really* want/need to separate them, there is just the right pattern for it: factory.
```cs
class StockBuyDTO : FinancialDTO {
public FinancialModel ToFinancialModel() {
return new StockBuyFactory(...).build();
}
}
```
That way, responsibility for creating domain objects is delegated out of the DTOs into the factory.
*But what if I want to have pure DTOs without any additional functionality?*
You can still achieve this and solve the problem polymorphically.
```cs
class StockBuyDTOData {
// members
}
class StockBuyDTO : StockBuyDTOData, FinancialDTO {
public FinanicalModel ToFinancialModel() {
return new StockBuy(...);
}
}
```
At this point I would ask the question why the DTO is not allowed to know about the model, considering that the DTO specifically exists to create model entities, and the model residing in the highest architectural layer, requiring everything else being built around it anyways.
What I would *not* do is to use metaprogramming, or some other intricate algorithm to stitch together DTOs and models as indirectly as possible, just for the sake of keeping them separate. At the end of the day, a model is a model and a DTO should be a representation of a model. They do belong together anyway.