over 4 years ago

閒談軟體架構：關於Android App Architecture

Figure 1 - Android App Conceptual Architecture

DAO Implementation是platform-dependent的，所以用橘色標示沒什麼大問題，但Web Service Implementation卻是被標示為紫色，主要是因為以JSON格式傳遞資料的Restful Web Services，是有機會只用以Java SE和Android SDK交集的API，搭配Android上也能使用的JSON Library來完成，也就是Web Service Implementation不一定是platform-dependent的實作，有機會能用JUnit來測試。

over 4 years ago

Protected Methods in Objective C

I discussed Java for several weeks, but in my job, the primary language I used is Objective-C in the recent one year. When I was still at school, I studied Objective-C for fun, but never used it in real projects. Thus, I didn't realize the interesting part of Objective-C. After I used Objective-C to develop projects in my job, I found that Objective-C is a charming language. It is a static-typed and complied language, but any message sending (calling a method) is determined at runtime, therefore, it also provides many features usually visible in the dynamic languages. It is an object-oriented language, and has @protocol (as the Interface in UML) and @interface (as the Class in UML), but does not provide obvious mechanism to control the access of an encapsulation, for example, the today's topic: protected methods.

To discuss the topic is because I am pair programming with two programmers new to Objective-C, and both of them asked me the same question: how to declare and use protected methods in Objective-C? For Java, C++, or C# programmers, using protected methods is just as nature as drinking water. I was not used to the absence of protected methods in Objective-C (although Objective-C has @public, @protected, and @private modifiers, they can only be used on member data), same as JavaScript. For the question, I reviewed the projects I developed in the recently years, and I found that protected methods become less. It may due to that I used lots of interface declaration and implementations, and reduced the depth of class hierarchy.

Figure 1 is a common-seen class diagram. In the figure, the orange dash line represents a boundary -- inside the boundary is a system or a package, and outside the boundary is the outer system. In the package, AbstractClass implements the interfaceMethod() method of the SomeInterface interface, and then add an abstract method protectedMethodB(). ConcreteClass extends AbstractClass to implement protectedMethodB(). Then, in the outer system, Context uses the ConcreteClass and a customized CustomizedClass. In such a design, Context can only see two methods: interfaceMethod() and publicMethod(). Only AbstractClass can see all methods. For ConcreteClass and CustomizedClass, the methods other than privateMethod() are visible.

Figure 1 - A class hierarchy

The programming languages trends to be dynamic languages. Therefore, the visibility is usually checked at compile time. Using Java as an example, calling private methods directly in code will get a compiler error, but with the reflection API, calling private methods indirectly is allowed. Same as Objective-C, the methods declared in the Header file are public methods, and the methods only placed in the Implementation file are private methods, but both can be invoked through the method objc_msgSend provided in Objective-C Runtime. Therefore, the simulation discussed here is to simulate the visibility of protected methods only at compile time.

The simulation uses the extension feature -- separate the header file into two parts. One part is AbstractClass.h as shown in Code List 2 that imports the SomeInterface in Code List 1 and declares the publicMethod() method. Another part is AbstractClass_Protected.h that declares the protectedMethodA() and protectedMethodB() methods as shown in Code List 3. Then, in Code List 4, AbstractClass.m imports AbstractClass_Protected.h and implements the interfaceMethod(), publicMethod(), protectedMethodA(), and privateMethod() methods. Objective-C does not have the concept of abstract methods, so AbstractClass.m throws exception to simulate the abstract methods.

So far so good. And then discuss how to make the protectedMethodA() and protectedMethoB() methods visible in the inherted classes. ConcreteClass imports AbstractClass_Protected.h, overrides the protectedMethodB() method, as shown in Code List 5 and Code List 6, and in the overridden method publicMethod(), both the methods protectedMethodA() and protectedMethodB() can be used directly. The problem seems to be solved. Well, only a part of problem is solved. Another problem is derived from the extension: should I open AbstractClass_Protected.h to the outer system?

Like C++ language, a class is separated into a header file and a implementation file. Although the header file exposes the private methods (variables) to the user, the compiler will check the legality of the method access. In C# or Java language that does not have header files, the visibility is compiled into the bytecode. So while using a packed DLL file or JAR file, the visibility of a method can be checked by the compiler. However, the visibility of a method is Objective-C is determined by whether the header file that have the metod delcaration can be accessed or not. That is if AbstractClass_Protected.h is opened to the outer system, not only CustomizedClass can see the protectedMethodA and protectedMethodB methods, but also Context. Otherwise, neither CustomizedClas nor Context can see the protected methods.

Table 1 lists the comparsion of the protected methods visibility simulated by opened and closed extension. In the table, 'o' means visible, and 'x' means invisible. The first column lists the different class, the second column lists the expected visibility (protected methods are invisible only in Context), the third column lists the actual visibility if the extension is opened (protected methods are visible in all classes), and the forth column lists the actual visibility if the extension is closed to outer system (protected methods are invisible in the Context and CustomizedClass). It is unfortunate that the extension can simulate the protected methods, but not perfectly. The trade-off to open or not open the extension depends on the actual situation. In fact, opening the extension header file is the same as declaring the protected methods in the original header file, so I prefer not to open the extension header file.

Table 1 - Protected methods visibility comparison

Class Expected Opened Extension Closed Extension
Context x o x
AbstractClass o o o
ConcreteClass o o o
CustomizedClass o o x

over 4 years ago

Protected Methods in Objective C

Figure 1是一個常見的類別圖，橘色虛線代表一個邊界，虛線內屬於同一個套件或系統，虛線外則是外部系統，首先看套件內，AbstractClass實作SomeInterfaceinterfaceMethod()，然後留下protectedMethodB()這個抽象函式，ConcreteClass繼承AbstractClass並提供protectedMethodB()的實作。接著看外部系統，Context使用ConcreteClass和額外擴充的CustomizedClass。最後，Context實際上能看見的，就只有interfaceMethod()publicMethod()兩個函式。對AbstractClass來說能看到所有的函式，對ConcreteClassCustomizedClass而言，可以看到privateMethod()以外的所有函式。

Figure 1 - A class hierarchy

Table 1將用Extension模擬protected methods在開放與不開放的可見度做個比較，o表示可見，x表示不可見，第一欄列出不同的類別，第二欄是普遍預期的可見度(只有Context看不到)，第三欄則是開放Extension標頭檔後的可見度(全都看的到)，第四欄則是不開放Extension標頭檔的可見度(ContextCustomizedClass看不到)。很可惜，用Extension無法百分之百模擬protected methods，至於開不開放，我想就留給使用的人依據個別情況決定。事實上，開放Extension標頭檔和直接把protected methods宣告在原本標頭檔意義上是差不多的，所以我個人是傾向不開放。

Table 1 - Protected methods visibility comparison

Class Expected Opened Extension Closed Extension
Context x o x
AbstractClass o o o
ConcreteClass o o o
CustomizedClass o o x

over 4 years ago

Quick Glance of Java 8 - Parallel Array Sort

Since I was laid-back recently, today only a small feature is discussed. Comparing the API Document of the utility class Arrays in J2SE 7 and J2SE 8, several static overloading methods are added: stream(T[]), setAll(T[], IntFunction<T>), parallelSetAll(T[], IntFunction<T>), parallelPrefix(T[], BinaryOperator<T>), spliterator(T[] array) and parallelSort(T[], Comparator<T>). The stream(T[]) method has been discussed in the previous article, and it wraps an array as a stream object.

Both the methods setAll(T[], IntFunction<T>) and parallelSetAll(T[], IntFunction<T>) provide the same functionality: using the return value of IntFunction to initialize an array. The IntFunction accepts one integer as parameter, i.e., the index in the array, and returns a value based on the index. These two methods are useful to generate a sequence of numbers, e.g., arithmetic sequence, geometric sequence, etc. The difference between these two methods is the later one processes the array elements in parallel that make the later one faster (but with more resources).

The method parallelPrefix(T[], BinaryOperator<T>) uses the previous element (as the left value of the binary operator) and the current indexed element (as the right value of the binary operator) to calculate the return value for the indexed element (something interesting is that Arrays does not provide non-parallel method). Since the return value is updated to the original array, the left value of the binary operator is the updated value. The example shown in the offical document is that given an array [2, 1, 0, 3] and a BinaryOperator<T> to perform addition, the resulting array is [2, 3, 3, 6]. 6 is calculated from the third element (left value) and the forth element (right value) and replaced the forth element.

The spliterator(T[] array) method is used to split the array. I guess that when parallelSort(T[], Comparator<T>) is called or the parallel() method of the stream object returned by the stream(T[] array)is called, the internal implementation uses spliterator(T[]) method to obtain the Spliterator object that manages of array separation for parallel processing.

The new added methods of Arrays are almost discussed and the left one is the today's topic: parallelSort(T[], Comparator<T>). The Arrays class provides methods for sorting for many years. These methods use merge sort algorithm to sort the given array, and the only needed is the Comparator to determine the ordering of two objects. The new added methods parallelSort(T[], Comparator<T>) sort elements (still with merge sort algorithm) in parallel. Therefore, I want to know how much performance can the parallel version improve?

As shown in Code List 2, an interface SortStrategy<T> is declared first. Then, in Code List 3 and Code List 4, the SimpleSortStrategy implementation provides the non-parallel sorting, and the ParallelSortStrategy implementation provides the parallel sorting, respectively. And in Code List 5, a method called generateRandomValues(int) that can generate a given sized array full-filled with random values.

All preparation is completed to examine the performance difference between the non-parallel and parallel sorting. In Code List 6, through the argument setting, the program can run many times with the specified initial array size. Each run, the array size is doubled, so we can discover the relationship between the array size and improvement, e.g., the more elements to sort, the more improvement can make. Since the amount of comparison and swapping affects the sorting time, Code List 6 uses generateRandomValues(int) to generate a list full-filled with random values, and before each strategy starting to sort, the list is transformed to an array (the transformation time is not included) to ensure that each strategy sorts the same random sequence. The environment is similar to the previous experiment Lazy Evaluation & Parallel Stream. The only difference is that the JVM is upgraded from 1.8.0-b132 to 1.8.0_05-b13.

The result is listed in Table 1. The test run seven times, the array size is from 1 M to 64 M, but the seventh test (64 M) failed because of the OutOfMemoryError. Therefore, Table 1 only lists six records.

Table 1 - The experiment result

Strategy 1 M 2 M 4 M 8 M 16 M 32 M
SimpleSortStrategy 539 760 1781 4120 8700 23016
ParallelSortStrategy 200 286 663 1515 3374 7724
2.70x 2.66x 2.69x 2.72x 2.58x 2.98x

From Table 1, it is obvious that parallelSort(T[], Comparator<T> can improve about 2.5 times to almost 3 times of performance. Therefore, to sort huge size of data, it is recommended to use parallelSort(T[], Comparator<T>.

over 4 years ago

Java 8 初探 - Parallel Array Sort

setAll(T[], IntFunction<T>)parallelSetAll(T[], IntFunction<T>)的功能是一樣的：用IntFunction的回傳值填滿整個array，IntFunction接受一個整數作為參數(即array的索引值)。這類函式在產生特定數列時挺好用的，例如用來產生等差數列或等比數列。兩個函式只差在後者是以平行處理的方式填滿array，速度較快(也較耗資源)。

parallelPrefix(T[], BinaryOperator<T>)可以用目前索引的前一個數值(binary operator的left值)和目前索引所指的值(binary operator的right值)計算出新的數值(有趣的是，Arrays沒提供非parallel的版本)，回傳值會填入原陣列中，所以binary operator的left值都會是變更後的值。官方的例子假設元數列式[2, 1, 0, 3]，然後BinaryOperator<T>做加法運算，則運算後的數列是[2, 3, 3, 6]，6是根據陣列的第三個數(left值)加上第四個數(right值)取代原有的第四個數。

spliterator(T[] array)是用來切割陣列，我猜當呼叫parallelSort(T[], Comparator<T>)或是用stream(T[] array)取得stream物件後，再次呼叫parallel()時，內部會用spliterator(T[])取得Spliterator物件管理陣列的切割，用來做平行處理。

Arrays的其他函式都介紹完了，該看今天的重點：parallelSort(T[], Comparator<T>)。在很早之前Arrays就有提供排序的函式，內部用的是merge sort演算法，使用時只需要提供比較任意兩物件順序的Comparator即可，這次新增的parallelSort(T[], Comparator<T>)就是平行處理的版本，所以我比較想知道平行處理版本所帶來的效能增益有多少？

Table 1 - The experiment result

Strategy 1 M 2 M 4 M 8 M 16 M 32 M
SimpleSortStrategy 539 760 1781 4120 8700 23016
ParallelSortStrategy 200 286 663 1515 3374 7724
2.70x 2.66x 2.69x 2.72x 2.58x 2.98x

over 4 years ago

Quick Glance of Java 8 - Base64

The topoc today is about a samll change - finally, Java 8 added the Base64 encodder/decoder into the java.util package. Although Base64 increases the actual data transmission length, in the plain-text Internet protocols, Base64 is commonly used to encode the binary data as text (e.g, MIME email). Therefore, it is surprised that the Base64 support is added until Java 8. Before Java 8, it needs the third-party library, for example, Apache Commons Codec, to provide Base64 encoder and decoder.

In the past work, I was developing a system X, a job is to receive the user uploaded file A. For some reason, system X does not have the capacity for storing files, and the uploaded file is actually stored in another system Y that provides file content indexing. Another similar job is that when the user downloads a (machine generated) file B from the system X, the file is also stored in the system Y for auditing. Both the system X and the system Y are RESTful Web Service. The file content transmitting through HTTP between the system X and the system Y is Base64 encoded as text in a JSON object. And the enocder and decoder I used is Apache Commons Codec.

Since Java 8 includes the Base64 encoder and decoder, it's time to write some codes with the encoder and decoder. However, using the IOUils.copy(InputStream, OutputStream) method in Apache Commons IO to handle reading something from input and putting the data into output is my personal habit. If the Apache Commons IO is not used, the helper method in Code List 1 is usefaul - writing while loop to copy data from the input to output is not needed any more.

With the helper method, the first program uses Base64 encoder to enocde the data from the InputStream and then write the encoded data into the OutputStream. In Code List 2, the encode(InputStream, OutputStream, Base64.Encoder) method accepts three parameters. The first is the data source and the second is the encoded data destination. These two are easy to understand, but how about the third parameter? Why do I have to specify the encoder? Are there different kinds of Base64 encoders? Yes! Base64 has variants in different protocols. Java 8 provides three kinds of Base64 encoders/decoders. The first kind is the basic (using Base64.getEncoder() and Base64.getDecoder() to get the basic encoder and decoder, respectively) which only uses 0-9, a-z, A-Z, +, /, and = alphabet to perform encoding, and the content is not line-separated. The second kind is the URL and Filename safe (using Base64.getUrlEncoder() and Base64.getUrlDecoder() to get the encoder and decoder). Since the symbols + and / have special usages in the URL, and / is illegal to use as filename in many filesystems, the encoder uses - (minus) to replace + and uses _ (underline) to replace /. The third kind is MIME (using Base64.getMimeEncoder() and Base64.getMimeDecoder() to get the encoder and decoder, respectively) which uses the same alphabet as the basic, but adding \r\n after every 76 characters for line-separation. Assume that the basic is commonly used, a method without the third parameter like Code List 2 can be provided for convenient.

After encoding, a decoder can be used to decode the data. In Code List 3, the decode(InputStream, OutputStream, Base64.Decoder) method also accepts three parameters: the first is the encoded data source, the second is the decoded data destination, and the third is the decoder. The three kinds of encoders/decoders mentioned above can not be used hybridly. That is the content encoded with the basic encoder can only be decoded with the basic decoder. The same, a method without the third parameter can be provided for convenient, and in the the following examples, the convenient version with the basic encoder/decoder is not listed for space saving.

With the method that encodes or decodes the content reading from the InputStream and then writes the encoded or decoded data into the OutputStream, variant can be provided for different usages. For example, in Code List 4, the method accepts two files as the input and output. In the method, the files are wrapped by FileInputStream and FileOutputStream and can be fed as the parameters of the methods in Code List 2 and Code List 3 to perform encoding or decoding operation.

Well, the encoded or decoded content is not always written into a file. In the job experience mentioned above, the file content is encoded as a part of the JSON object. For that case, the method in Code List 5 is useful - encoding the file content as a string. The method uses ByteArrayOutputStream as the buffer to store the encoded or decoded bytes, and then call toString(String) to output the content as a string.

The same, the data source may not be a file - a string is also possible. For the case, the method in Code List 6 can be used. The method uses getBytes() to obtain the string content as a byte array and wraps the byte array with ByteArrayInputStream as the input stream, and then feeds the input stream and the output stream for encoding or decoding operation.

Java 8 includes the Base64 encoder and decoder to provide convenience. However, the third-party libraries like Apache Commons Codec usually provide many kinds of encoders and decoders more than Base64 - that is much more convenient. But if your application only needs Base64 encoder and decoder, in the Java 8 environment, the third-party library for Base64 encoder and decoder is not required. Well, only in the Java 8 environment, therefore, using the built-in Base64 encoder and decoder becomes a design trade-off.

Puzzle: try to decode the file (tip: the file is a PNG picture.)

over 4 years ago

Java 8 初探 - Base64

Java 8有了Base64編解碼器，方便不少，不過Apache Commons Codec提供更多常用的編解碼器，其實是更方便的，但如果你的應用程式中只需要Base64編解碼器，在有Java 8的環境中確實不需要將Apache Commons Codec和專案一起打包，對~前提是要有Java 8的環境，變成用不用內建的Base64編解碼器又是一種抉擇了。

over 4 years ago

Quick Glance of Java 8 - Default Methods

Today, the topic is not about the Lambda expression -- is about the other change to the language in Java 8: default methods. In the past, the Java interface can only declare methods, but can not provide implementation (or called define methods). Therefore, in most design, static utility methods are defined in a class. Basically, that is not a big problem. However, someone may think about that should I define a private default constructor for the class?

In addition, Java does not support multiple inheritance, but supports multiple interface implementations. Thus, in the Java library, there is a commonly seen pattern: an interface that declares the required methods, an abstract class that provides the common implementation, and a default class that provides a completed implementation. For example, TableModel declares the minimum method set required by JTable, AbstractTableModel provides some common implementation (e.g., the management of listeners), and DefaultTableModel provides a completed implementation. This pattern may give rise to a problem: if class A has inherited class B, and wants to use (inherit) the abstract class of the interface C to reuse the implementation of C. However, Java does not support multiple inheritance, the only way is that A implements C by itself, but, to a certain extent, that will produce duplicated code.

During the design of Comic Surfer, in order to keep the binary compatibility between the main program and the plug-ins, I used the pattern mentioned above. In the public plug-in SDK, both interfaces and abstract classes are provided. However, in the public developer guide, I encourage the developers to inherit abstract classes to develop the plug-in. In that design, when I want to add methods into existing interfaces, I also add default implementation of new added methods into the abstract classes. Therefore, the plug-in can still run with the new version of Comic Surfer without any revising -- JVM will not complain that the class does not provide the required implementation of some methods.

For the above issues, the default methods can provide a pretty good solution. First, it is no need to define the utility methods in a class anymore. As shown in Code List 1, the implementation of static methods can be defined in an interface directly.

In addition, to a certain extent, if no member data is inside an abstract class, the role of abstract classes can be replaced. Assume that an interface is required for temperature sensors. The TemperatureSensor interface can be desinged like Code List 2: two default methods getTemperatureInCelsius() and getTemperatureInFahrenheit() are provided to convert the Kelvin scale to Celsius scale and Fahrenheit scale, respectively. I knew that the design example is not good enough because the conversion can be extracted into independent classes, however, the simplification is appropriate to show the usage of default methods. Since the implementation has be defined in the interface, the abstract class AbstractTemperatureSensor as shown in Code List 3 is not needed anymore.

No need of the abstract class provides some flexibility in design. For example, trying to write an adapter for a real temperature sensor device (AbstractDeviceControl), if default methods are not supported, due to the single inheritance, the developer needs consider that let the adapter inherit whether AbstractDeviceControl or AbstractTemperatureSensor? Of course, composition over inheritance, but, sometimes, developers need to write more codes. Now, just like Code List 4, the adapter can obtain the implementation from the interface, and the only one chance to inherit a class is left to other designs.

Then, while adding new methods into an existing interface, the default methods in the interface can provide the backward compatibility. For example, in Code List 5, a conversion to a new scale, called Rankine scale, is added into the TemperatureSensor interface with the default implementation. And, TemperatureSensorDevice can be used directly without any modification.

An interface can be extended to a new interface. For example, in some countries, people are used to Fahrenheit scale and many devices only provide the value in Fahrenheit scale. For that, like Code List 6, a new interface FahrenheitTemperatureSensor extends the TemperatureSensor interface. In the extension, the abstract modifier is used to redeclare the getTemperatureInFahrenheit() method that has default implementation as abstract method. A default method can also be overridden, e.g., getTemperatureInCelsius() is overridden to convert the Celsius scale from the Fahrenheit scale directly, saving the conversion between Kelvin scale and Fahrenheit scale.

In fact, many developers discussed a lot about default methods because with both default methods and multiple interface implementations can provide some kind of multiple inheritance like C++ -- except that the member data are not inherited. Good or bad? It depends on how to use. I think default methods helpful. If default methods are not only available in Java 8, I really would like to revise the plug-in interfaces and utility classes with default methods in my Comic Surfer.

over 4 years ago

over 4 years ago

What I want to have in the future Java?

Today, let's discuss something not so serious. After I read "Beyond Java," many years later, I rethink about the Java language. I think that Java puts too much emphasis on the library (J2EE has become a big monster), and ignores the language itself (for example, the auto-closable resource in try-catch in J2SE 7 and the Lambda expression in J2SE 8 are little big-changes to the language itself after the generic and autoboxing in J2SE 5). Java SE 8 has released, and not more than one month (2014/3/18 -> 2014/4/15), Java SE 8 Update 5 also released (the version number jumps fast after Oracle takes charge of Java development). The next version, Java SE 9, is prepared to launch. However, after learned different languages, I hope some language features (not necessarily functional) can be added into the future Java.

The first feature I hope to be added is property. In fact, many languages provide the similar language feature, e.g., Objective C and C#. The property can be accessed like variables. For example, in Code List 1, access the publications of a person by using for(Publication* publication in person.publications), or in Code List 2, change the height of a page by using page.Height = 400. It is not the same as declaring public member data, because a property is consisted of a setter and a getter with access control. Therefore, in Code List 2, the change to the height will notify all handlers (observer pattern) through the setter. And some languages provide default implementation of getters/setters, or mechanism to generate getters/setters automatically, e.g, @synthesize firstName;. Although getters/setters can also be generated automatically with Lombok annotations, that is not a part of the Java language. In addition, I don't like use annotation to generate getters/setters (well, this is a personal preferences).

The second feature is literal data structure declaration. Both JavaScript and Objective C provide this feature, Sometimes, when processing datta, a class with getters/setters is required to process a simple data object -- that is boring. For example, in Code List 3, a company data object is created easily. Yes, in fact, Code List 3 is a feature that Objective C borrowed from JavaScript Object Notation (JSON) as shown in Code List 4. Just use a symbol @ to declare literal data structure, and Java can use the same way! Well, someone can explain why the built-in JSON API only available in J2EE -- client does not need to parse JSON? That is somewhere strange.

The third feature is category. That is my favor feature of Objective C. Category is a way to glue new functions to an existing class, but it is not inheritance because the type is not changed. It is not the same as the partial keyword in C#. The category is very useful to design complicated project. The functionalities of a class can be categoried into different files. For example, the conversion between a POJO (Plain Old Java Object) object and JSON string is the responsibility of the POJO object itself, or someone others?

I would choose the prior one when I was new to the OO language, but after I saw many desings, I prefer the latter. Since an object can be outputted to different formats (JSON or XML), when a new format is required to output, the modification to the class source code againsts the open close principle. Without the source code, modification is impossible. Inheritance can add new functions, but the type is changed. With category, the implementation of the new format output can be glued to the existing class. As shown in Code List 5, the implementation of Person class in Person.h only provides the logics required by the domain model. And the implementation of the JSON conversion is put in the JSON category. If JSON conversion is needed, just import Person+JSON.h to get the implementation; otherwise, only import Person.h, the implementation of the JSON conversion is invisible. The category can glue new functionalities without the source code of the glued class -- I often use the category to add new functions into NSString.

The fourth feature is extension. This is also a feature of Objective C, and I hope this featureadded into Java to improve the testability. Although the modifiers @public, @protected, and @private are available in Objective C, they are used on member data, not member methods. Objective C does not require that all member methods should be declared in the header file (.h). Therefore, in most case, the methods written in the implementatio file (.m) are considered as the private methods. Sometimes, if private methods can become public methods, to write test case will be more easier. It is good chance to use the extension feature. As an example in Code List 6, public methods are declared in the Person.h, and the methods only public on testing are declared in Person_Private.h. Only the Person.h is public to everyone, and the Person_Private.h is not public. While testing, private methods can be seen by importing the Person_Private.h. (In fact, without additional header files, the extension can be used to open the private methods in test class directly.) Although Java does not separate the header file from the implementation file, providing the private interface implementation may be a similar solution.

The fifth feature is the preprocessor that can be integrated with IDE. Many developers started to write programs with simple text editors (well, basic funtionalities like syntax highlighted are still offered in these editors), because many IDEs becomes slow and heavy. However, there are still many developers use IDE to write programs -- I ever tried to find an alternative of the slow Eclipse, but I continue to use it because 4.3 improved a lot on performance. The IDEs of Objective C and C# provides many good integration with languages. There are many good IDEs for Java, but Java does not provide features to support IDE. For example, I like to organize methods in a class baed on their functions, and in Objective C, I would like to use #param mark - UITableViewDelegate Methods to collect the methods for UITableViewDelegate together, and in C#, I can use a pair of #region Properties and #endregion to wrap all properties in the same block. And IDE can optimize the UI based on these preprocessors. In XCode, the navigation bar (Figure 1) will classify the methods based on the name marked in #param mark`, and this will be easier to find a method.

Figure 1 - XCode provides integration with preprocessors

In recent years, new languages focus on the productivity and improve the readability (abstraction level). And most important is that they can develop the domain specific languages easily. That is not easy for Java. In fact, the features mentioned in the article are something like syntax sugar but they can improve the readability and abstraction level. Therefore, I think these features are useful in Java.