尽管我完全同意“静态不应该在这里使用”的观点,但我有点理解你在这里要表达的意思。尽管实例行为应该是工作的方式,但如果你坚持这样做,我会这样做:
从你的评论“我需要创建它的一个实例,只是为了获得一个真正具有静态行为的字符串”开始
这并不完全正确。如果你仔细看一下,你并没有改变基类的行为,只是改变了方法的参数。换句话说,你只是在改变数据,而不是算法。
当一个新的子类想要改变方法的工作方式时,继承更有用,如果你只需要改变类用来工作的“数据”,那么像这样的方法可能就可以解决问题。
class ModelBase {
private static Map<String,String> selectMap = new HashMap<String,String>(); 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");
}
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
return ....
}
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 )
另一种方法是从后面创建实例,并在使用实例方法时保持客户端接口不变,这些方法被标记为“protected”以避免外部调用。与前一个示例类似,您也可以这样做。
class ModelBase {
private static Map<String,ModelBase> daoMap = new HashMap<String,ModelBase>(); static {
selectMap.put( "Album", new AlbumModel() );
selectMap.put( "Artist", new ArtistModel());
selectMap.put( "Track", new TrackModel());
}
public static List findAll(Class classToFind ) {
String sql = getSelectSQL( classToFind );
results = execute( sql );
return ....
}
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();
}
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 )
我希望这可以帮到你。
关于使用List还是ArrayList的最后一点说明。编程时遵循面向接口而不是实现的原则总是更好的选择,这样可以使你的代码更加灵活。你可以使用另一个更快或者执行其他任务的List实现,而无需修改客户端代码。