This topic is about general programming and OO-design "best practices".
I'll start it with two questions:

1) Take a look at how the destinction between HalfEdge and SecondaryEdge is made in the bottom class-diagram here.
I could have used a boolean flag to distinct between primary and secondary HalfEdges, but in this case I used the type system to make this destinction. Using a boolean flag would consume one extra byte (extra, not exa! ) of memory for each HalfEdge instance, using the type system doesn't require any extra fields and thus doesn't consume any extra memory. But still, can this be considered "best practice", or is using the type system this way actually a misuse?

2) I've cought myself using public final fields sometimes instead of private fields and public getter/setter methods. Since the fields are final, they can't be modified by client code, but if the referenced objects are mutable they can be altered - basically the effect is very similar to using getter/setter methods, so I wouldn't say that this breaks encapsulation for composite objects. But on the other hand I'm using flexibility - getter/setter methods could be modified (or overridden) to do somthing in addition, or even to do something completely different. The public final field method just gives you read/write access to the object referenced by the field. So I'm feeling a bit bad about this and think that I'll rewrite everything to use getters/setters again.
Would you say that getters/setters are always a requirement for good OO design, or are public final fields allowed in exceptional cases?

Sascha wrote: But still, can this be considered "best practice", or is using the type system this way actually a misuse?

The only things I care about for things like this are:

Is it clear? I hate clever code, because I'm not clever.

Will some change in the Java standard break things?

Would you say that getters/setters are always a requirement for good OO design, or are public final fields allowed in exceptional cases?

Personally, I've got no qualms with directly setting values. It's probably a "bad practice" (because you can't look at the methods and discover the attribute), but so what? What are you protecting the programmer from?

If you think that getters and setters will save you grief in the future, then by all means, use them. If there are side effects, then by all means, use a getter/setter. But otherwise...

If you later need a getter/setter, you can declare the field private, and a good IDE (like Eclipse) will let you know all 5000 places in the code that you need to correct.

Agreed. Saving a few kilobytes of RAM doesn't really justify an ugly design, the times of the Commodore C64 are over. But wasting some megabytes of RAM is ugly design! I guess it's always a tradeoff between memory usage, performance and a clean design. If the performance and memory usage is acceptable, it makes sense to strive for a good design, and ugly hacks are only OK if either memory consumption or performance would be unacceptable otherwise. Most of the time well-designed code will be fast and economical, so the number of hacks that are really justified should be quite small.

If you later need a getter/setter, you can declare the field private, and a good IDE (like Eclipse) will let you know all 5000 places in the code that you need to correct.

But once the API is published and people started writing plug-ins, my IDE won't fix their plug-ins when I decide to change the API. Once the API was published I and all potential plugin-developers will have to live with it until the end of time, so I guess I gotta get it right the first time, there is no second chance. Of course new methods can be added to the public API and other methods can be marked as deprecated, but this should not happen all too often.

Personally, I've got no qualms with directly setting values.

I think that's the reason for the "package private" access modifier (aka the "default", when neither private, protected or public are present). It lets you access the fields/methods from within the same package, yet classes from foreign packages don't have access, not even if they inherit from the class in question (default is more restrictive than protected). I think this is OK from a design perspective, since plugins will be in a foreign package they don't have access to these methods, and if I decide to change them later it won't have any impact on the public API.
If classes are meant to be subclassed by e.g. plugin-code, care has to be taken which methods (or even fields) to declare "protected" instead of "default". Too much access might circumvent encapsulation and expose implementation details to the public API (which cannot be changed later), being too restrictive on the other hand might make the class unusable for subclassing. The same is true for public methods that can be used by client (e.g. plugin) code.

That's exactly the reason why I don't want to publish a plugin API yet (and I think not even with version 1.0). Those things need careful consideration. Nevertheless I'd like to have the API design as clean as possible right now - it will save a lot of refactoring once I'm ready to publish a plugin API.

But once the API is published and people started writing plug-ins, my IDE won't fix their plug-ins when I decide to change the API.

I don't think it should be a real problem. No one ,except project developer/developers, should access internal APIs of the project! Plugin API will drive all external implementations with proper rather stable interfaces.

That's exactly the reason why I don't want to publish a plugin API yet (and I think not even with version 1.0).

Never mind, if jpatch will meet needs, you probably be driven to a good plugin API design in spite of the actual version of jpatch

sascha wrote:But once the API is published and people started writing plug-ins, my IDE won't fix their plug-ins when I decide to change the API. Once the API was published I and all potential plugin-developers will have to live with it until the end of time, so I guess I gotta get it right the first time

IMHO it is not the job of your API to fix the plug-ins added by third parties. It is my opinion, O Great and Glorious Leader, that the plug-in API serves only as a testbed for future additions to JPatch itself, just like plug-ins for AoI and Wings3d.
If a plug-in is good enough, someone will maintain it.

I cannot say anything to that. I do suspect that they might be more lenient than you give them credit for. I don't really know though. The last serious development I did with Java was when the sdk1.2 was bright and shiny and new and full of bugs. And I now find that I have volunteered to work on a shader compiler for jrMan.