Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design pattern for translating multiple data-formats from multiple sources to a single format

I work for a company that has multiple websites, and the existing infrastructure is...well, awful.

Right now, each store has its own table that varies in structure. This is rapidly becoming a problem (if it wasn't already).

So I need to find a way to take orders from multiple channels, format them into a single, unified way, store them in our end, and translate them back to the format expected by the store APIs (which can be everything from RESTful JSON to SOAP).

My initial gut-reaction was a mixture of factory, visitor, and builder patterns (plus some smart polymorphism), but it got a little bit too complex too quickly. Before I go and code myself into a corner with a solution that may not be optimal, maintainable or extensible, is there a pattern or set of patterns that would be more efficient?

Basically, I'm thinking it would be something like:

Source -> Translator -> Our Format
Our Format -> Translator -> Source

I don't need the translator to actually act on the data. All it should be responsible for is getting it in the right format, and we can get it from point A to point B (and vice versa).

A few assumptions about the system:

  1. The format on our end is unlikely to change, and therefore our objects are unlikely to change
  2. When the data is translated back to the original source, we can assume that everything that's required will be there. The actual behavior for out-bound requests is small, focused and well-defined
like image 626
Ryon von Schmuck Avatar asked Oct 29 '25 08:10

Ryon von Schmuck


1 Answers

Adapter Pattern is your friend. Let's say you have a legacy Customer class.

public class CustomerLegacy
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime Birthday { get; set; }
}

The first thing you might want to do is to extract of that class. This step is optional but it makes the new class testable. So, you will have ICustomerLegacy interface that looks like below.

public interface ICustomerLegacy
{
    string FirstName { get; set; }

    string LastName { get; set; }

    DateTime Birthday { get; set; }
}

Then refactor CustomerLegacy class to implement the new interface.

public class CustomerLegacy
    : ICustomerLegacy

The next step is to create an adapter that takes ICustomerLegacy as a constructor's argument. You can add new properties to serve your needs.

public class CustomerAdapter
{
    private readonly ICustomerLegacy customer;

    public CustomerAdapter(ICustomerLegacy customer)
    {
        this.customer = customer;
    }

    public string FullName
    {
        get
        {
            return this.customer.FirstName + " " + this.customer.LastName;
        }
    }

    public int Age
    {
        get
        {
            return DateTime.UtcNow.Year - this.customer.Birthday.Year;
        }
        set
        {
            // your logic here.
        }
    }

    public void Save()
    {
        //this.customer.DoSomething();
    }
}

As you can see, Adapter Pattern can help you refactor existing product, make it testable, and tidy up the legacy code in one place.

like image 61
Ekk Avatar answered Nov 01 '25 13:11

Ekk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!