Reed,
If you want to mitigate that duplication, there are lots of ways to do so, and all of them couple two or more components together, that’s the price you pay. If you create a configuration file, you are coupling your gateway and your entities to some external file, which would violate the dependency rule. If you just let the gateway have access to the entity, you are exposing its business rules and some weird things can happen. I would advise you to let the entities have DTOs that are reused by other layers, so you can mitigate duplication and isolate the business rules but still somewhat conform to the dependency rule:
Your entity holds a reference to a data structure…
class AddressEntity {
AddressDTO data
AddressEntity(AddressDTO data){
validate(data);
this.data = data
}
void doSomething(){
// business rule manipulating the DTO in this.data
}
AddressDTO serialize(){
return this.data;
}
}
…that is reused in the gateway component…
class AddressORM extends AddressDTO { // note that the ORM extends the DTO and not the Entity itself
// ORM specific stuff goes in here
}
class AddressGateway {
void save(AddressDTO address){
AddressORM orm = new AddressORM(address)
orm.save()
}
}
…so you avoid rewriting all those fields, hide entity business rules from the gateway, and still keep the dependencies pointing inwards in your architecture.
You don’t have to use inheritance like I’ve shown here, you can be creative and use other language features to achieve the same reuse given the dependency stays the same.
I’m sorry for not investing more time in building a better example, I’m pretty sure this code doesn’t even compile and the names are really bad, but I think this is sufficient for you to have a clearer idea about this approach I suggested.
Caio