Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
344 views
in Technique[技术] by (71.8m points)

java - Bulider Design Pattern to make generic method for methods having large number of parameters

I have an interface Itest and ClassA & ClassB are implementing this interface. testA & testB are methods in these classes respectively.

testA(String a, String b, String c, D d, E e)

testB(String a, String b, String c, F f, G g) 

Here D, E, F, G are custom data types (related to databases). I simplified the methods actually they have more number of parameters.

I need to make a generic method in testAB in Itest interface and implement that in both classes rather than having their own method.

testAB(String a, String b, String c, D d, E e, F f, G g)

As the number of parameters is more, generic method testAB will be pain for the user as he has to pass so many null values.

  • Is this a usecase for Bulider Design Pattern?

  • If yes, how to achieve this using this design pattern?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Looks like the core requirement that you have is that you don't want the client to be passing additional parameters when they are not required. You can solve your problem using plain old method overloading :

Alter your ITest interface to have a single method called test

public interface ITest {
     public void test(String a,String b,String c,D d,E e,F f,G g);
}

Alter A as follows :

public class A implements ITest {

     //this is an overload - v1
     public void test(String a,String b,String c,D d,E e) {
            //dispatch the call to the overriden method
            test(a,b,c,d,e,null,null);
     }

     //this is an overload - v2
     public void test(String a,String b,String c,E e,F f) {
           //dispatch the call to the overriden method
           test(a,b,c,null,null,e,f);
     }

     @Override
     //this is an overriden method - v3
     public void test(String a,String b,String c,D d,E e,F f,G g) {
            if(d!=null && e!=null) {
                //use a,b,c,d,e and do something
            } 

            if(f!=null && g!=null) {
                //use a,b,c,f,g and do something
            }
     }
}

Now the client code can call whichever overloaded form they want without the need to pass null. Your overloaded methods will simply dispatch the call to a common method (which gives you the advantage of code reuse):

classAObj.test("1","2","3",new D(),new E());//calls overloaded method - v1
classAObj.test("1","2","3",new F(),new G());//calls overloaded method - v2
classAObj.test("1","2","3",new D(),new E(),new F(),new G());//calls overriden method - v3

Notice how the client code does not have to worry about passing additional parameters when they are not required. Also notice how clean the client calls look. Similar changes can be made in B as well.


1. You have an option to make ITest an abstract class. This will allow you to make the test method in it have the protected access specifier. The reason for wanting a protected access specifier is to restrict client classes from being able to access the method and always go through the overloaded forms instead. This is an add-on feature you can consider implementing in the future if you are stuck with using an interface at the moment.

2. You could also take advantage of Generics to avoid the need to write a new class every-time a new object type is introduced but as you can see from the other answers, this can easily complicate your code to a great extent. You could also add the overloaded methods to ITest interface to make it a part of its contract. However, I am deliberately leaving these parts out of my answer because the crux of your problem can be solved by using overloading.

3. The Builder pattern is a creational pattern. It's an overkill in this particular case since classes such as D,E,F and G are domain objects. Class A and B don't really depend on them in the real sense but use them as a source of data instead.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...