Context: I am working on a Java Spring Boot backend service, related to e-commerce domain. My service gets data from Order-Service(OS), and I have to extract some data to send it further. Extracted data class looks something like:
class TargetDTO {
String orderId;
String shipmentId;
String trackingUrl;
String deliveryDate;
// so on..
}
The source data, which I get from OS is contained in a JsonNode , and hence is of free form or no defined schema as below:
class OSResponseDTO {
String field1;
String field2;
JsonNode sourceData; // this is of our interest for this problem
// so on..
}
There are 2 dimensions in mapping the data :
-
Mapping criteria from source to target:
- The data can be directly extracted from source field, e.g. orderId <=> sourceData.orderId
- The data can be a combination of more than one field, e.g. shipmentId <=> sourceData.orderId + sourceData.shipments.number.
- We may need to apply some logic, and using one or more source fields, e.g. map deliveryDate from sourceData jsonNode and convert to specific format as per geographical region.
-
Same target data can be mapped from different json paths of sourceData , based upon business conditions, such as orderPlacedOnline, orderPlacedOffline, orderPaidOnline, orderPaidCash, orderPaidCard, orderOutForDelivery, orderDelayed, etc. There are, as of now, about 200 such conditions, which can be grouped in 8-10 schemas. For e.g. trackingUrl <=>
if(orderOutForDelivery) {
trackingUrl = sourceData.orderDetails.url;
}
else if(orderPlaced) {
trackingUrl = sourceData.url;
}
.
.
.
else if(orderShipped) {
trackingUrl = sourceData.shipments.url;
}
else {
}
Question: What possible design I can go with to implement this?
What I have tried One approach I could think of was - Having strategies for mapping each target attribute, and creating a Map of condition and strategies, as:
interface OrderIdStrategy {
void mapOrderId();
}
class OrderIdStrategy1 implements OrderIdStrategy {
}
class OrderIdStrategy2 implements OrderIdStrategy {
}
interface TrackingUrlStrategy {
void mapTrackingUrl();
}
class TrackingUrlStrategy1 implements TrackingUrlStrategy {
}
class TrackingUrlStrategy2 implements TrackingUrlStrategy {
}
class DataExtractor {
Map<String, Set<String>> businessCaseAndUsedStrategiesMapping;
@PostConstruct
init() {
businessCaseAndUsedStrategiesMapping.put("orderPlacedOnline", Set.of("OrderIdStrategy1", "TrackingUrlStrategy2"));
businessCaseAndUsedStrategiesMapping.put("orderOutForDelivery", Set.of("OrderIdStrategy2", "TrackingUrlStrategy2"));
// so on
}
mapOrderId(String businessCase) {
businessCaseAndUsedStrategiesMapping.get(businessCase).mapOderId();
}
mapShipmentId(String businessCase) {
businessCaseAndUsedStrategiesMapping.get(businessCase).mapShipmentId();
}
mapTrackingUrl(String businessCase) {
businessCaseAndUsedStrategiesMapping.get(businessCase).mapTrackingUrl();
}
}
But the unhappy part of this approach is that I have to create a map for all those 200 business cases; and these business conditions are likely to grow with future.
Aucun commentaire:
Enregistrer un commentaire