My C# app reads json file which changes over time (weekly or monthly) and it has to support all the versions. For example,
Version 1
{firstname:"John", lastname:"Doe"}
Version 2
{firstname:"Tony", lastname:"Doe", address:{line1:"Xavier", line2:"California"}}
Version 3
{firstname:"Adam", lastname:"Wood", address:{line1:"13 House", line2:"Texas", pincode: 12345}}
My C# class which deserialise the json looks like below,
// Version 1
public class DetailsV1: IBase
{
private string firstname;
private string lastname;
}
// Version 2
public class DetailsV2: IBase
{
private string firstname;
private string lastname;
private AddressV1 address;
}
// Version 3
public class DetailsV3: IBase
{
private string firstname;
private string lastname;
private AddressV2 address;
}
From my brief search in Google, it says Strategy pattern is a good choice for this kind of problem. So, I created a context class like below,
public class Context
{
private IBase details;
private int version;
public Context(int version, string path)
{
this.version = version;
// TODO The version should be parsed from the file
if (version == 1)
{
this.details = new DetailsV1(path);
}
else if (version == 2)
{
this.details = new DetailsV2(path);
}
else if (version == 3)
{
this.details = new DetailsV3(path);
}
else
{
throw new NotImplementedException();
}
}
// To avoid unnecessary boilerplate, I believe the below functions should return only primitive types
public int getPinCode()
{
if (version == 1)
{
throw new NotAvailableInThisVersionException();
}
if (version == 2)
{
throw new NotAvailableInThisVersionException();
}
if (version == 3)
{
var address = (this.details as DetailsV1).address;
var pc = (address as AddressV2).pincode;
return pc;
}
else
{
throw new NotImplementedException();
}
}
}
Below are my queries,
- Is this correct design pattern or is there any other better design pattern for my usecase? My versions can grow upto 400+ and thus, my class also grows. I feel this if/else will look ugly (and error prone?).
- If this is the correct design pattern, Is it correct to cast the address in getPinCode or this has to be handled inside the DetailsV3 class (i.e) DetailsV3 should have a method called getPinCode?
- If this is the correct design pattern, then I presume these methods should provide only primitive types (or types I am sure going to be static forever). Am I right?
Aucun commentaire:
Enregistrer un commentaire