I need to create a simple payments validator. On the following class diagram, I tried to present the model of payments. As you can see, each payment type inherits from Payments class.
Now I want to work with these payments but hide the details so the user can only access what he needs. And those things are are:
Load
payments from path and return list of payments
Save
payments to path
Update
input payments list and return updated list
I am not sure if the way I am doing it is correct.
My idea would be to use Facade design pattern, so PaymentsModel
class which would contain following methods should be created:
public class PaymentsModel
{
IList<ToBePaidPaymentsDto> GetToBePaidPayments(string path){
return new IList<ToBePaidPaymentsDto>();
}
IList<DonePaymentsDto> GetDonePayments(string path){
return new IList<DonePaymentsDto>();
}
IList<MissedPaymentsDto> GetMissedPayments(string path){
return new IList<MissedPaymentsDto>();
}
...
}
Then create abstract class:
public abstract class Payments<T>
{
protected string Delimiter {get; private set;}
protected int NumberOfHeaders {get; private set;}
public abstract IList<T> LoadRecords(string path);
public abstract IList<T> UpdateRecords(IList<T> records);
public void SaveRecords(string path, DataGridViewRowCollection records)
{
}
}
where T is Data Transfer Object depending on the type of payments, so:
ToBePaidPayments
class would use ToBePaidPaymentsDto
DonePayments
class would use DonePaymentsDto
as presented below
public class PaymentsToBePaid : Payments<IcsToBePaidPaymentDto> {
public override IList<IcsToBePaidPaymentDto> LoadRecords(string path){
return null;
}
public override IList<IcsToBePaidPaymentDto> UpdateRecords(IList<IcsToBePaidPaymentDto> records){
return null;
}
}
and
public class PaymentsDone : Payments<IcsDonePaymentDto>
{
public override IList<IcsDonePaymentDto> LoadRecords(string path){
return null;
}
public override IList<IcsDonePaymentDto> UpdateRecords(IList<IcsDonePaymentDto> records){
return null;
}
}
Now, my final question is – am I doing this correctly? Am I applying correct design pattern and am I applying it correctly?
Thank you for advice.
Best Answer
Given your comment that payments have different fields based on their status (and I will therefore assume this is an issue because of database tables), then What I'd do is implement a CsvReader class that has a generic-type argument, that maps Csv fields to the POCO in question. Therefore you'd write a single Csv Importer, and that can then be used to import data regardless of what class you throw at it.
Similarly, you can write a CsvExporter class that does the same thing. Write once, use everywhere.
Some comments:
Remove the
Dto
extension. We know what a payment is, it can potentially be used in many places (the database, the Csv File, business logic).Dto
is relevant in a single, specific scenario.Consider changing
Todo
toPending
.