dimanche 12 mars 2023

Looking for the design pattern - DI explosion

I am preparing for interviews and as I was doing interview questions in many topics, got different projects I decided to refactor a little the project as its not scaling well.

The structure of the solution is something as follow, below enumeration are the projects.

  1. Arrays
  2. SortingAlgorithms
  3. Trees
  4. Linkedlists
  5. etc

My problem is with displaying the results, I want to make it as minimal as possible:

I have the following classes and interfaces:

IDisplay

public interface IDisplay<T>
{
    void DisplayResult(T[] array);
    void DisplayResult(T[][] matrix);
    void DisplayResult(TreeNode treeNode);
    void DisplayResult(IList<T> treeNodes);
    void DisplayResult(T value);
    void DisplayNewLine();
}

Display implements the IDisplay, implementation is not important at this point.

Then I have a DI explosion in the Tests

    private readonly IDisplay<TreeNode> _display;
    private readonly IDisplay<string> _displayText;
    private readonly IDisplay<int> _displayList;
    private readonly IDisplay<char> _displayChar;
    private readonly IDisplay<bool> _displayBool;

    public Tests(IDisplay<TreeNode> display,
        IDisplay<int> displayList,
        IDisplay<string> displayText,
        IDisplay<char> displayChar,
        IDisplay<bool> displayBool,
        IFreeCodeCampBinaryTrees freeCodeCampBinaryTrees,
        ILeetCodeTrees leetCode,
        TreeTraversal treeTraversal)
    {
        _display = display;
        _displayText = displayText;
        _displayChar = displayChar;
        _displayList = displayList;
        _displayBool = displayBool;
        _freeCodeCampBinaryTrees = freeCodeCampBinaryTrees;
        _leetCode = leetCode;
        _treeTraversal = treeTraversal;
        TreeNode = _freeCodeCampBinaryTrees.InitializeTree3();
        TreeNodeOfChars = _freeCodeCampBinaryTrees.InitializeTree4();
    }

    // Methods look like this
    public void ValueExistsBFS(TreeNode root)
    {
        _displayBool.DisplayResult(_freeCodeCampBinaryTrees.ValueExistsBFS(root, 3));
    }

    public void PostOrderTraversalIterative(TreeNodeOfChar root)
     {
         _displayText.DisplayResult("Postorder Traversal - Iterative");
         _displayChar.DisplayResult(_treeTraversal.PostorderTraversalIterativeOfChars(root));
     }

And I have another class where I instantiate the actual Display and I run all tests in one method:

public class BinaryTreesTestRunner
{
    private Tests _tests;
    private TreeNode _head;
    private TreeNodeOfChar _headOfChars;

    public BinaryTreesTestRunner()
    {
        _tests = new Tests(new Display<TreeNode>(), 
                            new Display<int>(), 
                            new Display<string>(), 
                            new Display<char>(), 
                            new Display<bool>(), 
                            new FreeCodeCampBinaryTrees(), 
                            new LeetCodeTrees(), 
                            new TreeTraversal());
        _head = _tests.TreeNode;
        _headOfChars = _tests.TreeNodeOfChars;
    }

As you can see in constructor, I have the similar issue with trees, here I need to make a tree of int or char, it didn't exploded yet but is the same issue.

I tried two things which I think are wrong and I don't waste rest of the day doing another bad implementation, its better to ask first.

  1. I tried having a class where I get the type of T and use a switch to instantiate Display then I was thinking to inject that class in the constructors but many comments were against that.
  2. I tried factory pattern but then I realized I will need to have a DisplayBool, DisplayString which will implement same methods with a different type.

What I am really looking for is: have a class where I instantiate all the different types, inject that class in a constructor, then I can have _display.DisplayResult(accepts any type), I am ok with _display<sometype>.DisplayResult(param), I am not ok with displayBool.DisplayResult(bool)

Like I don't need some free code, I need some logic, the right design pattern than can accomplish this, I am gonna do the research, I just feel like Factory Pattern is close but not there.

EDIT: For a temporary solution, I just create a class and I instantiate in the constructor Display class with all types I need. I really hope there is a better way

Aucun commentaire:

Enregistrer un commentaire