Results 1 to 5 of 5
- 07-22-2010, 05:47 AM #1
Member
- Join Date
- Jul 2010
- Posts
- 2
- Rep Power
- 0
How is Java inheritance being used to enforce program requirements?
I was looking at a blog about good API design here
In one of the example sections titled 'Reinventing the Socket', it showed a design of how to enforce certain rules and prerequisite on the client code that uses it. eg. the client must call bind() before it can call connect(), and it must be connected before it's allowed to send() or receive() data.
I'm more familiar with C/C++ so I'm having some trouble fully comprehending how the class design is enforcing the API rules. Like for example, how do you prevent client code from making calls into this API with something like this:
How and why would the compiler catch that error? If I'm understanding the subclass inheritance correctly, SocketConnected is-a SocketBound which is-a Socket. But if the client code is able to declare a SocketConnected object, how can you enforce the rule that bind() and connect() must be called before send() and receive() are allowed?Java Code:SocketConnected s = socket.bind(localaddress, 1000); //client doesn't call the connect() method //and just calls the send() method right away. //this line should give compile-time error //because only bind() was called but not connect() s.send(/* some data goes here */);
I get what most of the code is doing but the part that confuses me is near the bottom where the author says:
How could that type of usage be equivalent toJava Code:s.bind(localAddr, 1000); s.connect(remoteAddr, 70);
?Java Code:SocketConnected s = socket.bind(localAddr, 1000).connect(remoteAddr, 70)
Also is there a design pattern that generalizes this example?
Thank
- 07-22-2010, 06:06 AM #2
First, I think I'll mention that calling send() without both bind() and connect() would result in a runtime error rather than a compile-time error. (The blog author also mentions this: "Any attempt to perform these operations out of order will result in a runtime error.") Basically, the reason this happens is that the Socket object has some way of detecting whether or not it's connected; if it's not, then it will not perform the send() actions. Basically this:
Java Code:public void send(String data) { if (this.connected == false) { return; } // Some code to send data. }
Second, note that in his interfaces, his return values are Sockets also. So when he talks about this code:
It's equivalent to the first code because the bind() has returned a Socket object.Java Code:SocketConnected s = socket.bind(localAddr, 1000).connect(remoteAddr, 70)
I'll explain that a bit further:
Let's imagine you have some class A, which has two class variables:
You will notice that the return types are void; therefore they're not returning anything. So something like this would be invalid:Java Code:public class A { int var1; boolean var2; public void SetV1(int val) { this.var1 = val; } public void SetV2(boolean val) { this.var2 = val; } }
Now imagine that class A is now this:Java Code:(new A()).SetV1(5).SetV2(true);
Now, instead of returning void, it returns an "A" object. This allows us to "chain" the commands together, because each function returns an A object:Java Code:public class A { int var1; boolean var2; public A SetV1(int val) { this.var1 = val; return this; } public A SetV2(boolean val) { this.var2 = val; return this; } }
Java Code:A Something = new A(); Something.SetV1(5); Something.SetV2(true);
Java Code:A Something = new A(); Something.SetV1(5).SetV2(true);
All of the above are equivalent.Java Code:A Something = (new A()).SetV1(5).SetV2(true);
Now I hope I've answered your question... if not you'll have to be a little more specific about the information you're after.
Best of luck!Last edited by Zack; 07-22-2010 at 06:11 AM. Reason: Added code example for first half.
- 07-22-2010, 09:10 AM #3
Moderator
- Join Date
- Apr 2009
- Posts
- 10,484
- Rep Power
- 16
Actually, the author is stating that the current Socket implementation will result in a runtime error. His proposal would result in a compile time error.
This is all about coding to interfaces. He suggests a Socket interface that simply allows you to bind(). You would get this Socket object, presumably, from some form of Factory, so you would never actually create one yourself using new.
The concrete class of this object is irrelevant to you when you code, but I would imagine it would actually implement all 3 interfaces, and simply return itself on the bind() and connet().
But the point is that with this mechanism you cannot connect() before you have run bind(), and you cannot transmit() before you have connect()ed. The compiler will throw an error. Thus you can (help) prevent misuse.
ETA: Just to clarify. The Socket interface provides access to the SocketBound interface which then provides access to the SocketConnected interface. You cannot get access to a SocketBound or a SocketConnected without successfully running a method from one of the earlier interfaces.
- 07-22-2010, 10:27 AM #4
Member
- Join Date
- Jul 2010
- Posts
- 2
- Rep Power
- 0
Thank you for the response and clarification everyone.
Ok, in other words, under the new redesigned socket interfaces, the following usage in client code is valid then:
or client code could also use it like so:Java Code://assuming CreateSocketFactory() instantiates a concrete socket object Socket socket = CreateSocketFactory(); //the way this was demo in author's example code SocketConnected s = socket.bind(localAddr, 1000).connect(remoteAddr, 70);
and finally the code snippet below was how the client would use the original socket API but under the new redesigned API it would generate a compile error:Java Code:Socket socket = CreateSocketFactory(); //lengthier way to do the same thing SocketBound sockbound = socket.bind(localAddr, 1000); SocketConnected s = sockbound.connect(remoteAddr, 70);
Java Code:s.bind(localAddr, 1000); s.connect(remoteAddr, 70);
- 07-22-2010, 11:22 AM #5
Moderator
- Join Date
- Apr 2009
- Posts
- 10,484
- Rep Power
- 16
That's pretty much it.
In the original you could do bind() then connect() (on the same Socket object).
In the proposed setup you couldn't actually do that because no interface has both those methods...well, short of casting the Socket to an possible ConcreteSocketClass which has all the interfaces. ;)
Similar Threads
-
different requirements on the same server
By ra78 in forum NetworkingReplies: 12Last Post: 06-28-2010, 05:50 PM -
Requirements for building a SSL VPN
By adityag in forum New To JavaReplies: 0Last Post: 01-19-2010, 04:46 PM -
New to Java.. What are the requirements?
By konn in forum New To JavaReplies: 10Last Post: 03-27-2009, 12:50 PM -
External DTD requirements
By jwilley44 in forum XMLReplies: 0Last Post: 03-06-2009, 09:25 PM -
Inheritance Program
By Schaput in forum New To JavaReplies: 6Last Post: 11-14-2008, 12:42 AM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks