0

Consider the following code:

public interface MyClass {
    public final String getMyObject1();
    public final String getMyObject2();
}

public class MyClass1 implements MyClass {
    private String myObject1;
    private String myObject2;
    public MyClass1(String myObject1, String myObject2) {
        this.myObject1 = myObject1;
        this.myObject2 = myObject2;
    }
    public String getMyObject1() {
        return myObject1;
    }
    public String getMyObject2() {
        return myObject2;
    }
}

public interface MyClass2 extends MyClass {
    public static MyClass2 newInstance(String myObject1, String myObject2) {
        return new MyClass2() {
            public String getMyObject1() {
                return myObject1;
            }
            public String getMyObject2() {
                return myObject2;
            }
        };
    }
}

And I use them like

public static void func(MyClass m) {
    m.getMyObject1();
    m.getMyObject2();
}
func(new MyClass1(o1, o2));
func(MyClass2.newInstance(o1, o2));

I wonder how they differ and if I only need to read from the values (i.e. to use MyClass as a "struct" to pass values), using the anonymous class can it be a simpler approach?

Otherwise, what are the draw backs?

GhostCat
  • 137,827
  • 25
  • 176
  • 248
user1589188
  • 5,316
  • 17
  • 67
  • 130

2 Answers2

7

One core rule of programming: try to not surprise your readers.

Your approach here to use a static class within an interface as "factory" method is very surprising (and believe me: I have seen a lot of Java code).

If at all, the more "common" way of handling such things: create a static class with a slightly similar name, you know, like there is java.lang.Object and java.lang.Objects that carries some useful static helper methods.

And beyond that, there is already a class in Java that helps with arbitrary numbers of "named" values; and that is called a Map!

Finally: there are some good arguments for "DTO"s (data transfer objects) but esp. for "beginners", you should rather look into "real" OO designs; based on the SOLID principles. In that sense: design real classes that exactly model your problem domain; and that provide helpful abstractions. A struct with an arbitrary number of members ... doesn't fall into either category.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Thanks. So you do not like MyClass2. Does that mean that you think MyClass1 is better? – user1589188 Feb 26 '17 at 20:08
  • I don't like the overall approach. MyClass1 is like the more default, less surprising way of doing things. – GhostCat Feb 26 '17 at 20:09
  • Yes ok, I just don't like to have extra private members just to copy the values in constructor and later get their values in MyClass1. While MyClass2 gets rid of the private members. – user1589188 Feb 26 '17 at 20:22
  • As said: I find the *overall* thing dubious. And we really shouldn't get into discussion mode; as that would kinda prove that point about "bad questions leading to discussions". – GhostCat Feb 26 '17 at 20:24
0

The problem here is not the code necessarily but the design. I would be interested to know the real world use case you are trying to design here.

Surely there are limitations in the second approach like you cannot update the value of your objects at all once your class is created as you just have a way to get the value of the passed objects back.

Coming back to Design:

An interface is supposed to be an action which your class can perform if it implements that interface. In your case you are trying to return the value of two instance variables using the two methods in your interface which is a kind of action but it ignores the basic principle of encapsulation.

If your class defines/owns those instance variables it should have the getters and setters for that. You should not require an interface to do that. So ideally your interface should not be required. Any other class which uses MyClass1 object should directly use the getters and setters of the MyClass1.

Sundeep
  • 384
  • 2
  • 6
  • Thanks. In my use case, MyClass is like a "struct" that holds arbitrary number of values and one class creates and fill up a MyClass values then passes to another class responsible to read and process the values. So there is no need to have setters and see in MyClass1 the values are final after construction. – user1589188 Feb 26 '17 at 20:18