尽管我完全同意“静态是在这里使用的错误东西”这一点,但我理解你在这里要解决的问题。仍然实例的行为应该是工作的方式,但是如果你坚持这是我会做的:
从你的评论开始“我需要创建它的一个实例来获得一个真正静态的字符串”
这不完全正确。如果你看起来很好,你不会改变你的基类的行为,只是改变一个方法的参数。换句话说,你正在改变数据,而不是算法。
当一个新的子类想要改变一个方法的工作方式时,如果你只需要改变类使用的“数据”来工作,那么继承就更有用。
class ModelBase {
// Initialize the queries
private static Map selectMap = new HashMap(); static {
selectMap.put( "Album", "select field_1, field_2 from album");
selectMap.put( "Artist", "select field_1, field_2 from artist");
selectMap.put( "Track", "select field_1, field_2 from track");
}
// Finds all the objects for the specified class...
// Note: it is better to use "List" rather than "ArrayList" I'll explain this later.
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
//etc...
return ....
}
// Return the correct select sql..
private static String getSelectSQL( Class classToFind ){
String statement = tableMap.get( classToFind.getSimpleName() );
if( statement == null ) {
throw new IllegalArgumentException("Class " +
classToFind.getSimpleName + " is not mapped");
}
return statement;
}
}也就是说,用Map映射所有的语句。下一步“明显”是从外部资源(例如属性文件或xml或甚至(为什么不))加载映射,以获得额外的灵活性。
通过这种方式,您可以让您的班级客户(和您的自己)高兴,因为您不需要“创建实例”来完成这项工作。
// Client usage:
...
List albums = ModelBase.findAll( Album.class );...
另一种方法是从后面创建实例,并在使用实例方法时保持客户端接口完好无损,方法被标记为“受保护”以避免外部调用。以前面的样本类似的方式,你也可以做到这一点
// Second option, instance used under the hood.
class ModelBase {
// Initialize the queries
private static Map daoMap = new HashMap(); static {
selectMap.put( "Album", new AlbumModel() );
selectMap.put( "Artist", new ArtistModel());
selectMap.put( "Track", new TrackModel());
}
// Finds all the objects for the specified class...
// Note: it is better to use "List" rather than "ArrayList" I'll explain this later.
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
//etc...
return ....
}
// Return the correct select sql..
private static String getSelectSQL( Class classToFind ){
ModelBase dao = tableMap.get( classToFind.getSimpleName() );
if( statement == null ) {
throw new IllegalArgumentException("Class " +
classToFind.getSimpleName + " is not mapped");
}
return dao.selectSql();
}
// Instance class to be overrided...
// this is "protected" ...
protected abstract String selectSql();
}
class AlbumModel extends ModelBase {
public String selectSql(){
return "select ... from album";
}
}
class ArtistModel extends ModelBase {
public String selectSql(){
return "select ... from artist";
}
}
class TrackModel extends ModelBase {
public String selectSql(){
return "select ... from track";
}
}而且您不需要更改客户端代码,并且仍然具有多态性的能力。
// Client usage:
...
List albums = ModelBase.findAll( Album.class ); // Does not know , behind the scenes you use instances....
我希望这有帮助。
关于使用List与ArrayList的最后一点注意事项。编程到接口比实现更好,这样你可以使你的代码更加灵活。您可以使用另一个更快的List实现,或者执行其他操作,而无需更改客户端代码。