I have a StringValidator. A StringValidator is either a Regex or a string pattern using '*' wildcards. I want the StringValidator.StringIsValid() to perform one action or a different one, depending on which overloaded constructor was used. I can think of several ways to do this, but I have no idea of the best way.Note that this is a simplified example, and I know I can convert strings to Regexs. That's not the type of solution I'm looking for.For example, I could set a flag in each constructor to indicate which one was called. Or, I could condition the behavior on which variable was null.I'm not sure the overall thrust of what I'm trying to do is even a good idea.
How can I generalize multiple distinct classes as a single class, united by purpose?
c#;design patterns;object oriented
What you described here is a textbook example of a strategy pattern. You define an interface for validation, implement as many different implementations as you need, and then instantiate the implementation you need based on what you decide is needed.The following is tested code.The Strategy Pattern part:public interface IValidationStrategy{    bool Validate(string pStringToValidate);}public class RegexValidator : IValidationStrategy{    private Regex regEx;    public RegexValidator(Regex regEx)    {        this.regEx = regEx;    }    public bool Validate(string stringToValidate)    {        return regEx.IsMatch(stringToValidate);    }}public class WildCardValidator : IValidationStrategy{    private string wildCard;    public WildCardValidator(string wildCard)    {        this.wildCard = wildCard;    }    public bool Validate(string pStringToValidate)    {        //http://stackoverflow.com/questions/30299671/matching-strings-with-wildcard        string regex = Regex.Escape(wildCard).Replace(\\*, .*);        return Regex.IsMatch(pStringToValidate, ^ + regex + $);    }}Accepting a Dependency Injection (IValidationStrategy) and using a nested builder class to construct the different strategy implementations in an immutable way:public class StringValidator{    private IValidationStrategy validationStrategy;    //Dependendency Injection constructor    public StringValidator(IValidationStrategy validationStrategy)    {        this.validationStrategy = validationStrategy;    }    public bool Validate(string stringToValidate)    {        return validationStrategy.Validate(stringToValidate);    }    public class Builder    {        public StringValidator Regex(string regex)        {            return new StringValidator(new RegexValidator(new Regex(regex)));        }        public StringValidator WildCard(string wildCard)        {            return new StringValidator(new WildCardValidator(wildCard));        }    }}Two different ways to test: class Program{    static void Main(string[] args)    {        Console.Out.WriteLine(            IsValid: {0},            new StringValidator.Builder()                .Regex(@\d+)                .Validate(55)        );        Console.Out.WriteLine(            IsValid: {0},            new StringValidator.Builder()                .WildCard(*)                .Validate(Whatever string to be validated)        );        // Or, if you hate using nameless temporary objects        Console.Out.WriteLine();        StringValidator.Builder stringValidatorBuilder = new StringValidator.Builder();        string regex = @\d+;        StringValidator regValidator = stringValidatorBuilder.Regex(regex);        bool isValid = regValidator.Validate(55);        Console.Out.WriteLine(IsValid: {0}, isValid);        string wildCard = *;        StringValidator wildCardValidator = stringValidatorBuilder.WildCard(wildCard);        isValid = wildCardValidator.Validate(Whatever string to be validated);        Console.Out.WriteLine(IsValid: {0}, isValid);    }}Outputs:IsValid: TrueIsValid: TrueIsValid: TrueIsValid: True