At work, I make this application that takes values from an external file (Excel sheet, text file ...) and translates these values into complex instructions that are transferred to another system.
The code below is a bit simplified (no instructions or very simple logic), but the idea remains the same. I have about 60 different translators who manage different types of business logic. Some use only one argument to run. Others accept several arguments.
I have an abstract translator class. The class user will use two public methods: Translate to start the translation logic, and CanTranslate allows you to see if the translator is ready to run.
A developer using this abstract class must implement the DoTranslate method, which will contain the actual business logic. By default, CanTranslate always returns true, but if validation is required, it can be overridden.
Here's the base class of an abstract translator:
// Contains some base logic which is the same for all translators public abstract class BaseTranslator { // Public translate method public void Translate() { if (CanTranslate()) DoTranslate(); } // Checks if we are ready to translate // True by default public virtual bool CanTranslate() { return true; } // This method is used to implement business logic public abstract void DoTranslate(); }
And here is the implementation of a specific translator class:
// Translates beer names public class ReverseTranslator : BaseTranslator { // Use of properties to allow strongly typed arguments // which can be seen by the developer at design time public string BeerName { get; set; } // Validation public override bool CanTranslate() { if (BeerName.Equals("Budweiser") || BeerName.Equals("Stella")) return true; else return false; } // Implementation of the business logic public override void DoTranslate() { char[] letters = BeerName.ToCharArray(); Array.Reverse(letters); Console.WriteLine(new string(letters)); } }
And here is what it looks like when using:
class Program { public static void Main(string[] args) { var translator = new ReverseTranslator(); translator.BeerName = "Stella"; translator.Translate(); translator.BeerName = "I'm not a beer";
Pro's:
- Separates specific business logic from small supported units.
- translators are easy to reuse in other parts of the application.
- translators can be easily tested
- allow the translator user to see which arguments are required
My problem:
- different controller classes are used by many translators. I have too many connections.
I was thinking about using the Factory pattern to create a translator, but then I cannot use properties as argument hints during development.
So, I'm basically looking for a solution in which during development you can easily see which arguments are required. And at the same time, I hope to reduce communication by not having every controller that has 30 new xTranslator instructions.
PS: I will limit myself to using .NET 3.5 for this code.