Oh dear! BBspot - Which File Extension Are You? tells me I am a .cgi, they clearly do not know anything about me ;-))
Archive for October, 2004
code_poet writes about it class naming conventions. I’d like to submit my own.
Interfaces
Interfaces are named after the Business Objects that it defines, the Party, Thing, Service or the like.
Examples:
- Person
- PersonManager
- TimeCurrencyConverter
I do not use a “Marker Letter” or any other special convention because I’d like to use a “Person” later on and the code does not care if it’s an Interface or an Implementation the object has to behave like a Person, not a IPerson or PersonIntf.
AbstractImplementations
For abstract classes that might implement an interface I use AbstractXXX.
Examples:
- AbstractPerson
- AbstractPersonDAO
- AbstractCurrencyConveter
I use the AbstractPrefix to make clear that this class cannot be instanited but the implementation must be “completed” first.
Default Implementations
For the standard or default implementation of an interface or abstract class I use DefaultXXX. This makes clear the the implementation does not depend on any special features like a certain persistence framework, e.g.
Examples:
- DefaultCurrencyConverter
JavaBeans and ValueObjects
All those little JavaBeans and value objects I pass around in my business layer are named XXXBean if they follow the Bean specification and do not depend on any special external feature.
Examples:
- PersonBean - a in memory implementation of Person
- CurrencyConverterBean - an implementation of CurrencyConverter that follows the Bean spec.
Implementations that depend on special external features
For classes implementating an interface and that depend on a certain external feature like a persistence framework I use FrameworknameXXXX.
Examples:
- HibernatePersonManager
- HibernateCurrencyConverter
Utilitiy classes
The little hepler classes the contain all the usefull things are name XXXUtil, where XXX is a JDK class, or JDK or external feature it extends or completes.
Exmples:
- MapUtils, ListUtils
- JTableUtils
- HibernateUtils
ONJava.com: Reporting Application Errors by Email talks about logging your application errors via an smtp appender for log4j or java.util.logging. Please consider what I wrote ealier on about the 10500 Messages in my inbox.
What did I learn?
- Do not use an active notification if the error is permanent.
- Do not report the same error again and again.
- Write some log4j appender that would filter or aggregate the messages in this case. ;-)
I played around with groovy and groovy’s antbuilder. After a while I came to the follwing buildfile which resolves
dependencies in a quite general way:
new JavaLibArtifact(
sources: "src/java",
testsources: "src/test",
libdir: "lib",
testlibs: "/usr/share/java/junit.jar",
testlibdir: "lib",
targetdir: "target"
).build()
]]>
This is quite nice. If you want to look under the hood, here is the complete code:
class Artifact {
ant = new AntBuilder()
private uptodate = false
public isUptodate() {
return uptodate
}
public build() {
if(uptodate) { return }
buildOnce()
uptodate = true
}
}
class ArtifactSet extends Artifact {
property artifacts
public void buildOnce() {
artifacts.each { it.build() }
}
}
class JarArtifact extends Artifact {
JavaCompilerArtifact classes
String destfile
public void buildOnce() {
ant.jar(destfile: destfile,
basedir: classes.destdir)
}
}
class JavaCompilerArtifact extends Artifact {
property sources
String destdir
property classpath
private classpaths
void buildOnce() {
ant.mkdir(dir: destdir)
classpaths = ant.path()
classpath.each() {
classpaths.add(it.path())
}
ant.javac(srcdir: sources,
classpath: classpaths,
destdir: destdir)
}
destdir() {
build()
return destdir
}
path(includeClassPath) {
build()
path = ant.path {
pathelement(path: destdir)
}
if(!includeClassPath) {
path.addExisting(classpaths)
}
return path
}
}
class ClasspathArtifact extends Artifact {
String libdir;
private libs;
private classpath;
void buildOnce() {
if(libdir) {
classpath = ant.path {
fileset(dir: "${libdir}") {
include(name: "*.jar")
}
}
}
if(libs) {
libs.each() {
classpath.add(classpath.pathElement(it))
}
}
}
public path() {
build()
return classpath
}
public String toString() {
build()
return "Classpath: " + (libs ? libs.join(" ") + " " : "")
+ (libdir ? libdir + "/**" : "")
}
}
class JUnitArtifact extends Artifact {
property classes
property testclasses
String packages
void buildOnce() {
junit = ant.junit(printsummary: true, fork: true)
testpath = junit.createClasspath()
if(classes) {
classes.each {
testpath.add(it.path())
}
}
if(testclasses) {
testclasses.each {
testpath.add(it.path())
}
}
bt = junit.createBatchTest()
testclasses.each() {
bt.addFileSet(ant.fileset(dir: it.destdir) {
include(name: "*")
})
}
bt.elements().each() {
}
junit.setFork(true)
junit.execute()
}
}
class JavaLibArtifact extends Artifact {
String sources
String testsources
String targetdir
property libs
String libdir
property testlibs
String testlibdir
void buildOnce() {
mainClasspath = new ClasspathArtifact(libdir: libdir,
libs: libs)
testClasspath = new ClasspathArtifact(libdir: testlibdir,
libs: testlibs)
mainClasses = new JavaCompilerArtifact(
sources: sources,
destdir: "${targetdir}/classes",
classpath: mainClasspath)
testClasses = new JavaCompilerArtifact(
sources: testsources,
destdir: "${targetdir}/test-classes",
classpath: [mainClasses, mainClasspath,
testClasspath])
jar = new JarArtifact(destfile: “${targetdir}/test.jar”,
classes: mainClasses)
junit = new JUnitArtifact(classes: mainClasses,
testclasses: testClasses)
new ArtifactSet(artifacts: [junit, jar]).build()
}
}
new JavaLibArtifact(
sources: “src/java”,
testsources: “src/test”,
libdir: “lib”,
testlibs: “/usr/share/java/junit.jar”,
testlibdir: “lib”,
targetdir: “target”
).build()