jeudi 26 juillet 2018

Injecting A Factory Into A Class

I'm developing an application feature for generating some sorts of strings. I have an interface:

interface IStringGenerator
{
    string GenerateNext();
}

and for now I have implemented this interface in a class having a single constructor with one parameter:

class FixedLengthStringGenerator : IStringGenerator
{
    public FixedLengthStringGenerator(int length)
    { . . . }

    public string GenerateNext()
    { . . . }

    .
    .
    .
}

This implementation only generates the desired strings of a fixed given length length. GenerateNext() on each call returns a desired string, until there are no one left and then it returns null. Considering these, I need another implementation of IStringGenerator which can generate strings of length between a minimum and a maximum. I think it's natural to have something like this:

class MinMaxLengthStringGenerator : IStringGenerator
{
    int _MinLength;
    int _MaxLength;
    int _Length;
    IStringGenerator _StringGenerator;

    public MinMaxLengthStringGenerator(int minLength, int maxLength)
    {
        _MinLength = minLength;
        _MaxLength = maxLength;

        _Length = minLength;
        _StringGenerator = new FixedLengthStringGenerator(_Length);
    }

    public string GenerateNext()
    {
        if(_Length > _MaxLength)
            return null;

        string generatedString = _StringGenerator.GenerateNext();

        if(generatedString == null)
        {
            _Length++;
            if(_Length <= _MaxLength)
            {
                _StringGenerator = new FixedLengthStringGenerator(_Length);
                return _StringGenerator.GenerateNext();
            }
            else
                return null;
        }
        else
            return generatedString;
    }
}

But creating instances directly is not a good idea. Instead I can use a factory to get an instance of FixedLengthStringGenerator. But I still think it's not a good practice, because it depends on FixedLengthStringGenerator. And if I want to use another alternative class in the future, this way it's not possible to receive it from outside.

My question is whether it's right (from the patterns point of view) to inject a factory into my MinMaxLengthStringGenerator or not?

More precisely, consider

interface IFixedLengthStringGeneratorFactory
{
    FixedLengthStringGenerator Create(int length);
}

Should I declare MinMaxLengthStringGenerator's constructor like following?

public MinMaxLengthStringGenerator(int minLength, int maxLength, IFixedLengthStringGeneratorFactory factory)
{ . . . }

Aucun commentaire:

Enregistrer un commentaire