0

I have a number of methods, each of which checks the same set of conditions and returns a null value if none of the conditions are met, otherwise returns an object of different classes. Is there a way to not have to write all of these terms for each function and use less code?

    public A methode1()
    {
        if ///something
            return A("xxx")
        else if ///something
            return A("yyy")
        else if ///something
            return A("zzzz")
        else 
            return Error() // or return null
    }
    public B methode2()
    {
        if ///something
            return B("mmmm")
        else if ///something
            return B("nnn")
        else if ///something
            return B("bbbb")
        else
            return Error() // or return null
    }

    public C methode3()
    {
        if ///something
            return C("oooo")
        else if ///something
            return C("ggg")
        else if ///something
            return C("llll")
        else
            return Error() // or return null
    }
4
  • Easiest way is changing return part to Func<T>. Commented Aug 11, 2020 at 15:13
  • can you tell more? or create an Answer to Explain it? Commented Aug 11, 2020 at 15:14
  • Are you asking about Java or C#? Answer will be different for different frameworks. Commented Aug 14, 2020 at 6:32
  • No matter what the language, I want to know what is available approach in Java or C#. If you have an idea, please let me know. Commented Aug 14, 2020 at 8:19

5 Answers 5

1

You can combine template method pattern with generics:

public abstract class AbstractTemplate<T>
{
    public T methode()
    {
        if ///something
            return Do1();
        else if ///something
            return Do2();
        else if ///something
            return Do3();
        else 
            return Error() // or return null
    }
    protected abstract T Do1();
    protected abstract T Do2();
    protected abstract T Do3();
}

public class ConcreteATemplate : AbstractTemplate<A>
{
    protected override T Do1() => A("xxx");
    protected override T Do2() => A("yyy");
    protected override T Do3() => A("zzzz");
}

And use it inside your methods:

public A methode1() => new ConcreteATemplate().methode(); // also can "cache" instance in your case in static readonly field.
Sign up to request clarification or add additional context in comments.

Comments

1

Standard approch is , you can use a factory class with interface/abstract class

public interface IOutput {
}
public class Output1 : IOutput{
}
public class Output2 : IOutput{
}
public class MyFactory
{
    public IOutput Get()// add args list of any
    {
       if(condition) // you can use args in condition if necessary
           return new Output1();
       else
           return new Output2();
    }
}

2 Comments

can you please describe more or make an Example using my Example
Sure, I can add a demo code based on your code, please check below.
0

You can use generic method and repository pattern. Here is a generic method example with C#. I think it may give you some idea..

public static async Task<List<ObjectType>> GetDataList<ObjectType>(UserAuthorization token) where ObjectType : BaseModel
        {
            List<ObjectType> data = new List<ObjectType>();
            try
            {
                if(token.UserTypes.Count > 0)
                {
                    Type genericClass = typeof(Repository<>);
                    Type constructedClass = genericClass.MakeGenericType(typeof(ObjectType));
                    MERPDbContext mERPContext = new MERPDbContext();
                    var created = (Repository<ObjectType>)Activator.CreateInstance(constructedClass, mERPContext);
                    if (token.UserTypes[0].Id == (byte)UserTypes.SuperAdmin)
                    {
                        var sub = await created.GetAsync();
                        data = sub.ToList();
                    }
                    else if (token.UserTypes[0].Id == (byte)UserTypes.InstituteAdmin)
                    {
                        data = await created.FilterListAsync
                                            (x => x.InstituteId == token.InstituteID);
                    }
                    else
                    {
                        data = await created.FilterListAsync(x =>
                                            x.InstituteId == token.InstituteID && x.CampusId == token.CampusID);
                    }
                }
            }
            catch (Exception e)
            {
                
            }
            return data;
        }

Comments

0

You could use a method with a generic type parameter and a set of initial values.

private T GetIfOkay<T>(string a, string b, string c)
    where T : new()
{
    if (something)
        return new T(a);
    else if (something else)
        return new T(b);
    else if (yet something else)
        return new T(c);
    else
        return null;
}

public A methode1()
{
    return GetIfOkay<A>("xxx", "yyy", "zzzz");
}

public B methode2()
{
    return GetIfOkay<B>("mmmm", "nnn", "bbbb");
}

// etc.

If you need a more dynamic behaviour, @donggas90's solution.

See:

Comments

0

According to your comment, I tried to rewrite your sample, hope this will help you. ask freely if you need more clarity.

class Program
{
    static void Main(string[] args)
    {
        var objFactory = new MyFactory();
        // Get and cast return object
        A a1= (A) objFactory.ConsolidatedMethod("Condition 1 for Objct A", "xxx");

        // Or Directly assian to base object
        IOutput a2 = objFactory.ConsolidatedMethod("Condition 2 for Objct A", "yyyy");

        // use anonymous object
        var b1= objFactory.ConsolidatedMethod("Condition 1 for Objct B", "mmmm");

        var nullcheck1 = objFactory.ConsolidatedMethod("null conditionj", "i'm null");
    }
}

interface IOutput
{
}

class A : IOutput
{
    public A(string objParam)
    {
    }
}

class B : IOutput
{
    public B(string objParam)
    {
    }
}

class NullOutput : IOutput
{
    public NullOutput(string objParam)
    {
    }
}

class MyFactory
{
    /// <summary>
    /// Demo 
    /// </summary>
    /// <param name="arg">you can use this based on your requirement </param>
    /// <param name="objparam">you can use this based on your requirement </param>
    /// <returns>IOutput</returns>
    public IOutput ConsolidatedMethod(string arg, string objparam)
    {
        IOutput _output=default;

        if (arg == "Condition 1 for Objct A")
            _output = new A(objparam);
        else if (arg == "Condition 2 for Objct A")
            _output = new A(objparam);
        else if (arg == "Condition 1 for Objct b")
            _output = new B(objparam);
        else if (arg == "Condition 2 for Objct B")
            _output = new B(objparam);
        else
            _output = new NullOutput(objparam);

        return _output;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.