I was looking at a blog about good API design link text
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:
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 */);
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?
Thanks
You enforce the rules by only providing bind() as creator, and no public constructor on SocketConnected. There's no other way of instantiating a SocketConnected except through the API. Yes, you can declare an object of that class, but you cannot create one by yourself; hence you cannot call any instance methods until the proper creator has been called.
ADDED: Re your comment on bind().connect(): that's just an example of chaining, somewhat like a fluent interface, but with type restrictions controlling the order of calls. Think about what happens. The first bind() call creates an instance, on which you then can call connect(). The final code example the likned author provides is a contrast: that's what things would look like with a traditional Berkeley style socket library, where the s is a socket on which both bind() and connect() are possible to call, in any order, without the compiler complaining.
ADDED: Re design pattern - I don't think this has been named. It probably should be. It supports a variation of the design criterion of fail fast, by failing as early as at the compiler stage.
The point is that he's creating interfaces that are defined only to return bound sockets. You get a provider that is only defined to return bound/connected sockets.
if you have an instance of his SocketBound
public interface SocketBound {
SocketConnected connect(Address<?> address, int port);
}
You can only get a SocketConnected from it.
Related
I'm trying to learn Akka (with Java) and understand some code. I have seen something like this, this method signature in a Actor class :
#Override
public void aroundReceive(PartialFunction<Object, BoxedUnit> receive, Object msg)
I've never heard of that method before and don't understand it. What is the purpose of that method ? Where does this PartialFunction<Object, BoxedUnit> receive argument comes from ? I thought it was up to the programmer to implement receive object.
As for PartialFunction<Object, BoxedUnit>, the receive function in an (untyped) actor is an instance of that (this is made abundantly clear in the Scala API, and somewhat less-so in the Java API).
An Actor implementing this (typically via a Scala mixin or extending an abstract class which overrides it) would take the receive function from the actor implemented by the programmer and intercept calls to certain messages (e.g. timing messages) or do pre-/post-processing of messages which are passed onto the given receive.
PartialFunction<Object, BoxedUnit> basically means:
this is a function which doesn't promise to have a result for any particular input; it's the responsibility of the caller to check beforehand (isDefinedAt) if the function will have a result or to accept that the function will throw an exception. (PartialFunction: a function which is not defined over the entirety of its domain)
Object (or in Scala terms Any (technically AnyRef, but autoboxing lets us forget that for a moment)): the function can theoretically accept anything
BoxedUnit indicates that the function returns no useful result (Unit in Scala is like void in Java, but is actually an object (a singleton to be precise)).
(to some extent PartialFunction<Object, BoxedUnit> is the type which tells us and the compiler the least information possible).
First, I am using Akka in Scala, and not in Java. I hope this answer will give you a lead.
In Scala, this method is #InternalApi. The docs of that in Scala is:
Marks APIs that are considered internal to Akka and may change at any point in time without any
warning.
For example, this annotation should be used when the Scala {#code private[akka]} access
restriction is used, as Java has no way of representing this package restricted access and such
methods and classes are represented as {#code public} in byte-code
One purpose of this method is to wrap the receive method with custom behaviour. You can see an example for that in the Timers trait.
Randomly I came across this site: http://resources.mpi-inf.mpg.de/d5/teaching/ss05/is05/javadoc/java/io/FileNotFoundException.html
The class FileNotFoundException has three defined constructors:
FileNotFoundException()
Constructs a FileNotFoundException with null as its error detail message.
FileNotFoundException(String s)
Constructs a FileNotFoundException with the specified detail message.
private FileNotFoundException(String path, String reason)
Constructs a FileNotFoundException with a detail message consisting of the given pathname string followed by the given reason string.
But the last constructor is defined as private?
Again, here: http://www.docjar.com/html/api/java/io/FileNotFoundException.java.html we can see the full class definition. There is no other code, so the singleton pattern is obviously not used for that case, nor we can see, why it should be prevented to instantiate the class outside of the object, nor is it a factory method, static (utility class) method or an constants-only class.
I am C# dev so I might not be aware about some stuff that is going on here but I would still be interested why it is defined as private, for what it is used and if there is any example or an use case for that last constructor.
The comment mentions:
This private constructor is invoked only by native I/O methods.
Anybody explain this a bit further in detail?
Keep in mind: a lot of the libraries of the JVM are written in Java, like that exception. But when interacting with "the rest of the world"; sooner or later Java doesn't do any more - there is a need to talk C/C++ in order to make real system calls.
Meaning: certain operations related to file IO can't be completely implemented in Java. Thus native code comes in (compiled binaries). But of course, such a call can fail as well. But then one needs a mean to communicate that on the Java side - in other words: an exception needs to be thrown.
Given the comments that you are quoting this seems pretty straight forward: when certain IO related native operations fail; they will use that private constructor to create the exception that is then thrown at "you". And yes, native methods can call private methods!
Edit: but when looking at the implementation - there is really nothing specific about that constructor One could easily construct such an exception using the exact same message that this private ctor would create.
private FileNotFoundException(String path, String reason) {
super(path + ((reason == null)
? ""
: " (" + reason + ")"));
}
So, my personal guess: this could even be some "leftover". Something that had a certain meaning 15 years ago; but isn't of "real meaning" any more. Or even more simple, a convenience method allowing native code to either pass a null or a non-null reason string.
The constructor in question is private so that no other class can use it to initialize an instance. It could, in principle, be used by the class itself -- that sort of thing is not unusual when one constructor is intended to be invoked by another, or by a factory method.
In this case, however, the documentation presents a different reason, which you in fact quoted:
This private constructor is invoked only by native I/O methods.
That seems clear enough to me, but I suppose your confusion may revolve around details of Java access control -- in particular, that it does not apply to native methods. Thus the native methods by which various I/O functionalities are implemented can instantiate FileNotFoundException via the private constructor, regardless of which class they belong to.
Why should one use a "Dynamic Proxy class" instead of the "standard proxy" pattern?
What are the disadvantages or advantages of both?
It seems like they both have the same end result, except that they are implemented differently.
Dynamic proxy class
https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
A dynamic proxy class is a class that implements a list of interfaces
specified at runtime such that a method invocation through one of the
interfaces on an instance of the class will be encoded and dispatched
to another object through a uniform interface. Thus, a dynamic proxy
class can be used to create a type-safe proxy object for a list of
interfaces without requiring pre-generation of the proxy class, such
as with compile-time tools. Method invocations on an instance of a
dynamic proxy class are dispatched to a single method in the
instance's invocation handler, and they are encoded with a
java.lang.reflect.Method object identifying the method that was
invoked and an array of type Object containing the arguments.
Standard proxy pattern https://en.wikipedia.org/wiki/Proxy_pattern
A proxy, in its most general form, is a class functioning as an
interface to something else. The proxy could interface to anything: a
network connection, a large object in memory, a file, or some other
resource that is expensive or impossible to duplicate. In short, a
proxy is a wrapper or agent object that is being called by the client
to access the real serving object behind the scenes. In the proxy
extra functionality can be provided, for example caching when
operations on the real object are resource intensive, or checking
preconditions before operations on the real object are invoked. For
the client, usage of a proxy object is similar to using the real
object, because both implement the same interface.
You have appeared to answer your own question. You should use the one which is easier to implement for your use case.
You need to dynamic proxy when you do not have an implementation for each method at compile time.
For example, mocking test libraries use the dynamic proxies so that can write code to handle any method generically.
Hi I'm implementing a given design in java. Basically I have an abstract class which is called base and I have a number of concrete classes which are extending Base and implementing an interface from a different package. Each concrete class will be implementing a different interface. Now these interfaces contain both event-based and non event-based method signatures in them. My question here is; I'm only expected to implement non-event based methods in my concrete classes, however because of the implements keyword java forces me to insert an auto generated method body, which is basically return null. They might be implementing those event based methods later on but not at the moment. What would be an appropriate way to let the API user know that these methods do not contain an implementation. Here are my thoughts;
Use deprecated keyword
Create an exception class and throw that exception inside of the method and let the API user handle it.
I do not have the option of making changes to the existing architecture. Any idea really appreciated. Thank you.
According to Oracle, the reasons to deprecate an API include
It is insecure, buggy, or highly inefficient
It is going away in a future release
It encourages bad coding practices
neither of which actually fits your case.
Personally, I would favor throwing an UnsupportedOperationException which is already provided by the Standard Library in order to
indicate that the requested operation is not supported.
To me, this sounds more like what you actually want.
You can create your own interface which lists all the method you want users of your component to be able to access. Make this the only interface they use and additional public methods will not be visible.
Option (2) is good, but as you are following interfaces you'll want unchecked exceptions. And document the methods as unimplemented.
Deprecated implies a history, i.e., it works but should no longer be used. Since you are explicitly stating that the methods do not work, marking as deprecated will not prevent use nor indicate that the methods are unimplemented.
I would suggest use some mix bag of design patterns. That will help you solve this problem efficiently and make the code maintainable as well.
Based on my knowledge, you can use the Abstract Factory pattern here. See the design sketch below in the figure.
Method1 and method2 in subclass1 and subclass2 are the ones which are supposed to be exposed while method3 and method4 in subclass1 and subclass2 are the ones which we don't want to expose.
Create a Genericsubclass interface and create some methods in this interface depending upon the nature of methods you have in subclasses. For ex: i have create one method in this interface called nonEventbasedmethod1
Create a factory corresponding to every sub class and each factory will implement the GenericSubclass interface. Then implementation of nonEventbasedmethod1 method in subclass1Factory would be some thing like
nonEventbasedmethod1(){
subclass1.method1();
}
and implementation of nonEventbasedmethod1 method in subclass2Factory would be some thing like
nonEventbasedmethod1(){
subclass2.method3();
}
Then create a SubclassAbstract Factory which will return one of the subclass factories and then without worrying about which factory has been returned (that decision has already been taken in SubclassAbstractFactory before returning the appropriate factory) simply call the desired method from GenericSubclass interface and underneath one of the methods from the subclass1 or subclass2 will be invoked.
Hope this helps.
If you plain to throw an exception for "NotSupported" or "NotImplemented" Exception - consider the exception of NotImplementedException (at org.apache.commons).
However, I would reconsider to revisit your design and see if you can avoid having this - maybe you need to define another interface, which will hold the methods that are always implemented, and extend it in another interface (or provide an interface with no extension to the previous one) for the methods you not always implement.
public void foo(){
throw new Exception("foo");
}
public void bar(){
foo();
}
Is it possible to inspect the method bar() in order to know that foo() is called without a try catch inside bar()?
You may be interested in wrapping the whole class inside a Proxy and watch it with an InvocationHandler:
http://www.javalobby.org/java/forums/t18631.html
Your InvocationHandler would do something special if it sees that "foo" is called immediatly after "bar", I guess.
It seems like your intention is to have your application code check a method implementation, and conditional branch when that method fails to use try-catch internally.
Unless you are writing unit tests, let me discourage doing this for two reasons:
1. A developer should understand his application logic.
You should already know what your code is doing. If the method is part of a
closed-source API, check the documentation for thrown Exception types.
2. It adds unnecessary complexity.
Because flow of
execution depends on method implementation, you will have an
application whose behavior is dependent upon the state of its own
source. (eg. Changing the method can create side-effects, which
makes debugging more difficult.)
If you can determine method behavior by checking the source code or API documentation, what is the need for verifying at run-time?
As far as my knowledge is concern, there is no such reflection API which allows to see the inside implementations. You can only inspect the methods present in the Class, but can not the logic written in the method.