Java – large inner classes and private variables
One thing I've experienced several times is that a service class (such as JBoss service) has become too large due to the helper's internal class I haven't found a good way to break the class These assistants are usually threads Here is an example:
/** Asset service keeps track of the Metadata about assets that live on other * systems. Complications include the fact the assets have a lifecycle and their * physical representation lives on other systems that have to be polled to find * out if the Asset is still there. */ public class AssetService { //...varIoUs private variables //...varIoUs methods public AssetService() { Job pollerJob = jobService.schedule( new AssetPoller() ); Job lifeCycleJob = jobService.schedule( AssetLifecycleMonitor() ); } class AssetPoller { public void run() { // contact remote systems and update this service's private variables that // track the assets. } } class AssetLifecycleMonitor { public void run() { // look for assets that have meet criteria for a lifecycle shift // and update this service's private variables as relevant. } } }
So, if I have several helpers and they are very complex, the overall class file can become very large I like inner classes because it makes it clear that these classes are fully owned by the service and only exist to help the service I have tried to break the class and pass the parent service as a reference. This work is mainly work, but what I don't like is: > I finally exposed the package level accessor, so the decomposed class can obtain variables. Before I exposed the setter, because the internal class has direct access. > In addition, things are a little more lengthy because I keep calling accessors instead of base variables A small, awarded. > Convenience methods (such as checkassetisvalid() or some) require package level exposure, so help classes can call them. As mentioned earlier, inner classes can be private. > What's worse, I need to pass the service implementation class to the auxiliary class constructor, because I don't want to expose these helpers methods in the interface of the service implementation, because it forces them to be exposed This may cause some unit test / mockery problems What's worse, any synchronization I want to do is leaked through some external convenient methods (such as lockdownassets () during poller update) Before, the inner class can access the private key
So in short, breaking these courses will lose some of my favorite packages But letting them in may lead to some large java files I haven't found a good way to deal with this problem C has the concept of "friend" that I rarely miss, but it is actually helpful in this case
reflection?
Solution
At the bytecode level, internal classes are simply Java classes Because the Java bytecode validator does not allow access to private members, it generates synthetic accessor methods for each private field you use In addition, in order to link the inner class with its surrounding instance, the compiler adds a composite pointer to the external "this"
With this in mind, inner classes are just a layer of syntax sugar They are convenient. You listed some good points, so I listed some negative aspects you might want to consider:
>Your inner class has hidden dependencies on the entire parent class, blurring its inbound interface If you unzip it into the package - private class, you have a chance to improve your design and make it easier to maintain At first, it is more lengthy, but it is often found that:
>Instead of exposing 10 accessors, you actually want to share a value object Usually you will find that you really don't need to reference the entire external class This also applies to IOC. > Instead of providing explicit locking methods, it is more maintainable to encapsulate the operation and its context in a separate class (or move it to one of the two classes - outer or formerly inner). > Convenience methods belong to the package private utility class You can use Java 5 static import to make it appear local
>Your external class can bypass any level of protection and directly access private members of internal courses This is not bad in itself, but it eliminates one of the language means to express your design. > Because your inner class is embedded in an outer class, the only way to reuse it is to subclass the outer class Another way is to pass an explicit reference to the package private interface implemented by an external class This will allow you to laugh at the outside and better test the inner classes. > Although the recent debugger is very good, I have encountered problems before debugging internal classes (conditional breakpoint range confusion, unable to stop at breakpoint, etc.) private courses will expand your bytecode See my first paragraph - there is usually an API to use and reduce the number of composites
PS: I'm talking about extraordinary inner classes (especially inner classes that don't implement any interfaces) The realization of third - line audience is good