[Pki-devel] Automatic reformatting and code style

Adam Young ayoung at redhat.com
Tue Nov 29 15:54:46 UTC 2011


OK,  here's why I think we should drop the 'm'.


Hmmmm ....OK...let me back up....

An object should conform to a contract.  Once the object is created,  
that contract has been signed, sealed and delivered.  At least,  that is 
the intention.  However,  Java often falls down on this.  We have 
"Init"  methods.  We have Property setters that must be called before we 
have a "valid" object.

Why?  Java is a pretty strongly typed language.  But,  it needs to be 
able to interface with scripting languages,  and  thus it has,  among 
other things,  the reflection API.  Reflection has the  ability to 
enumerate the properties (member variables) of the object,  and to fetch 
values from the object  without having to have a compile time 
dependency.  We can even make variables that are Read Only by tagging 
them as 'final'.

A final field must be defined by the time the constructor has returned.

The dependencies to decide the value for the final field must be passed 
in to the constructror.

The constructor is available via reflection.  the Parameters are 
avialable via  reflection...but....

Not the names of the parameters.  This is possibly the largest oversight 
in the Java language.  Without named parameters,  a scripting language 
cannot do anything to determine which of the values it has maps to which 
of the dependencies of the constructor.  All it can do is try to pass 
them in the right order.

So what happened?

Java has a nasty covention called the bean API.  A naming convention 
get<CapitalizedName> and set<CapitalizedName>.  Want to make somethig 
read only,  drop the set.

Joshua Blcok sets out an important rule of  thumb in Effective Java:  
Favor Immutable Objects.  An immutable object is implicitly thread 
safe.  The Bean API  with its late initialzation of properties makes 
this impossible.

However,  we have hope.  In recent versions of Java,  the Attribute API 
makes it possible to automatically build classes that let us create a 
Dictionary to pass to the constructor  based on the names of the 
parameters.  There is also the possibility of getting named parameters 
into the Java standard in the future.


Regardless,  this is only really an issue for scripting languages.  Our 
application is all Java.  This means that we can use classes and type 
safety to strongly associate the dependecies of a constructor with the 
objects that can fulfil those dependencies.  We don't need to play 
"Everything is a string"  like Javascript does.

We can have immutable objects,  without the bean API.  And we can expose 
the properties of those objects as final properties instead of 
get<CapitalizedName>.  But this only makes sense if the names of the 
properties are the "good name".


This has the potential to make code that is much more readable and 
concise,  while increasing type safety.

Yes,  increasing type safety.  If a string field is immutable,  but it 
needs some business logic,  say to confirm that it complies with a 
pattern,  we create a class that encapsulated that format,  and make an 
immutable instance of that class.  The pattern is confirmed in the 
constructor.  If we try to make an instance that does not conform,  
throw an exception.

Here is how it is done in a beanAPI way:


public class Certificate{
     String  fingerprint;

     String getFingerprint(){
           return fingerprint;
      }

     String setFingerprint(String fingerprint)
     throws IllegalArgumentException
     {
          validateFingerprint(fingerprint);
           this.fingerprint = fingerprint;
      }
}

Note that the logic for fingerprint is encapsulated in the Certificate 
object, and cannot be cleanly separated out.

Here's the refactored solution.

public class Fingerprint{
private String  internal;
public Fingerprint(String) throws InvalidArgumentException{
...
}

String toString(){
...
}
}


public class Certificate{
     public final Fingerprint  fingerprint;
     puiblic Certificate (Fingerprint fingerprint)    {
           this.fingerprint = fingerprint;
      }
}






More information about the Pki-devel mailing list