ClarityOfAccessModifiers
From APIDesign
(→Fuzzy Access Modifiers) |
(→Meanings of public) |
||
Line 33: | Line 33: | ||
==== Meanings of '''public''' ==== | ==== Meanings of '''public''' ==== | ||
+ | |||
+ | Obviously the primary meaning is to allow anyone to call such method. However there is secondary, yet quite important additional interpretation: one can also re-implement the method in a subclass. | ||
+ | |||
+ | How dangerous this double meaning can be has been demonstrated in the ''Arithmetica'' example. What troubles such missing [[clarity]] can result in has been described in [[AlternativeBehaviours]] page. However better than knowing how to cure the problem, is to avoid it: eliminate '''public''' (without no additional modifier) methods for your [[API]]! | ||
==== Meanings of '''protected'''' ==== | ==== Meanings of '''protected'''' ==== |
Revision as of 09:27, 23 March 2009
An important aspect of any API is its Clarity. As API is about communication between the API writer and API user, the Clarity here needs to be applied to the communication. If the communication is clear, if the intention of the API writer correctly re-emerges in API users' heads then the API is clear enough.
Easy, one might thing. However expressing yourself clearly in some language requires deep understanding of meaning of its words, sentences and other language constructs. This is true for English as well as Java. For example guess what the following API can be useful for:
Code from Arithmetica.java:
See the whole file.public class Arithmetica { public int sumTwo(int one, int second) { return one + second; } public int sumAll(int... numbers) { if (numbers.length == 0) { return 0; } int sum = numbers[0]; for (int i = 1; i < numbers.length; i++) { sum = sumTwo(sum, numbers[i]); } return sum; } public int sumRange(int from, int to) { int len = to - from; if (len < 0) { len = -len; from = to; } int[] array = new int[len + 1]; for (int i = 0; i <= len; i++) { array[i] = from + i; } return sumAll(array); } }
Is this class useful only for summing up two numbers, few numbers and a range? Not at all! With a little bit of invention one can sufficiently use it to compute factorial:
Code from Factorial.java:
See the whole file.public final class Factorial extends Arithmetica { public static int factorial(int n) { return new Factorial().sumRange(1, n); } @Override public int sumTwo(int one, int second) { return one * second; } }
At first this might look as perfect example of object oriented reuse, however if you are a maintainer of such API and you want to provide new enhanced version, this can easily lead to BackwardCompatibility nightmare (as described in AlternativeBehaviours).
Contents |
Fuzzy Access Modifiers
What is cause of the problem? The problem is that in the world of API design access modifiers have different meaning than one could originally thought. Why is that? Probably because the public, protected, package private and private modifiers were originally approach from point of security. When I own something I can lock it, I can label it as confidential and show only to some friends or I can share only with my children. This sounds logical and from the point of security it even may be. Yet in combination with abstract and final (or virtual in other languages than Java) this can cause a complete nightmare when used during API design.
Clarity is important. The easiest way to hurt clarity is to give one thing multiple meanings. Nobody can then know if someones understanding of the thing is correct, full and the same as understanding someone else, or even the author of the API.
Meanings of public
Obviously the primary meaning is to allow anyone to call such method. However there is secondary, yet quite important additional interpretation: one can also re-implement the method in a subclass.
How dangerous this double meaning can be has been demonstrated in the Arithmetica example. What troubles such missing clarity can result in has been described in AlternativeBehaviours page. However better than knowing how to cure the problem, is to avoid it: eliminate public (without no additional modifier) methods for your API!
Meanings of protected'
What a user of an API is supposed to think when there is a protected method? Is it something that shall be called or something that shall be overriden and implemented?
It can be both. Again, this can be seen as example of power of object oriented languages, but I can guarantee that users of your API will find such missing clarity confusing. What is this method good for? I am supposed to use it to communicate with the super class or will super class call it when it finds the need to call it?
Nobody can easily tell the meaning of protected method in an API class. It is too fuzzy and in the name of Clarity it deserves to be avoided.
Meanings of public abstract
Single Meaning Access Modifiers
Meaning of public final
Meaning of protected final
Meaning of protected abstract
Converting Fuzzy Modifiers to Single Meaning Ones
TBD