我为我的产品类实现了嵌入式静态构建器,它在构造函数调用中接收了另一个类。这应该通过以下方式调用:
StudentFeatureBuilder studentFeatureBuilder=new StudentFeature.StudentFeatureBuilder<StudentFeatureBuilder>(studentModel);
StudentFeature feature=studentFeatureBuilder.build();
所有这些类(StudentFeatureBuilder,StudentFeature和StudentModel)都应该由最终用户使用和扩展,因此可以创建FooStudentFeatureBuilder,FooStudentFeature和FooStudentModel。所有要素类都作为集合注册到一个管理器类,并且应该有一种方法可以为所提供的学生模型构建所有已注册的要素。 我设法做的唯一方法是向StudentFeature和将使用构建器的所有子类添加一个额外的静态构建方法:
public static StudentFeature build(StudentModel studentModel){
return new StudentFeatureBuilder<StudentFeatureBuilder>(studentModel).build();
}
然后我有了触发它的方法:
for(Class<? extends StudentFeature> featureClass:featuresClasses){
Method buildMethod=featureClass.getMethod("build", studentModel.getClass());
StudentFeature feature= (StudentFeature) buildMethod.invoke(null,studentModel);
但是,我不喜欢这个解决方案,因为它迫使最终用户编写2次冗余构建方法。我希望有一些更优雅的解决方案。
谢谢, 卓然
除了我原来的帖子,这是我现在的代码,似乎也有效。
//*******************************************************
//StudentFeature class
//*******************************************************
public class StudentFeature {
private String name;
private List<StudentFeature> dependsOn;
public String getName() {
return name;
}
public void setName(String fName) {
this.name = fName;
}
public List<StudentFeature> getDependsOn() {
return dependsOn;
}
public void setDependsOn(List<StudentFeature> dependsOn) {
this.dependsOn = dependsOn;
}
public void addDependsOn(StudentFeature dependsOn){
if(dependsOn!=null && !this.dependsOn.contains(dependsOn)){
this.dependsOn.add(dependsOn);
}
}
public static class Builder<T extends Builder>{
public Builder(){
System.out.println("Default Feature Builder called");
}
public StudentFeature build(StudentModel studentModel){
System.out.println("Build Student Feature");
return new StudentFeature();
}
}
}
//*******************************************************
//FooStudentFeature class
//*******************************************************
public class FooStudentFeature extends StudentFeature{
private double value=0.0;
protected FooStudentFeature() {
}
public static class Builder extends StudentFeature.Builder<Builder> {
StudentModel studentModel;
public Builder(){
System.out.println("Foo student feature builder constructor");
}
public StudentFeature build(StudentModel studentModel){
System.out.println("Build Foo Student Feature");
return new FooStudentFeature();
}
}
}
//*******************************************************
//StudentModel class
//*******************************************************
public abstract class StudentModel {
private List<StudentFeature> features;
private PersonalData personalData;
public StudentModel(){
setFeatures(new ArrayList<StudentFeature>());
}
public List<StudentFeature> getFeatures() {
return features;
}
public void setFeatures(List<StudentFeature> features) {
this.features = features;
}
public void addFeature(StudentFeature feature){
System.out.println("called add feature");
if(feature!=null && !this.features.contains(feature)){
System.out.println("adding feature:"+feature.getClass().getName());
this.features.add(feature);
}
}
public void removeFeature(StudentFeature feature){
if(feature!=null && this.features.contains(feature)){
this.features.remove(feature);
}
}
public PersonalData getPersonalData() {
return personalData;
}
public void setPersonalData(PersonalData personalData) {
this.personalData = personalData;
}
}
//*******************************************************
//DefaultStudentModel
//*******************************************************
public class DefaultStudentModel extends StudentModel{
}
//*******************************************************
//FooStudentModel
//*******************************************************
public class FooStudentModel extends DefaultStudentModel {
public FooStudentModel(){
System.out.println("Created an instance of FooStudentModel");
}
}
//*******************************************************
//StudentModelFactory class
//*******************************************************
public class StudentModelFactory {
private List<Class<? extends StudentFeature>> featuresClasses;
private Class<? extends StudentModel> studentModelClass;
public StudentModelFactory(Class<? extends StudentModel> studentModelClass) {
featuresClasses = new ArrayList<Class<? extends StudentFeature>>();
setStudentModelClass(studentModelClass);
}
public void addFeatureClass(Class<? extends StudentFeature> featureClass){
if(!this.featuresClasses.contains(featureClass)){
this.featuresClasses.add(featureClass);
}
}
public void setStudentModelClass(
Class<? extends StudentModel> studentModelClass) {
this.studentModelClass = studentModelClass;
}
public StudentModel makeStudentModel() {
StudentModel studentModel = null;
try {
studentModel = (StudentModel) studentModelClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return studentModel;
}
//****************************************************************************
//This method is called to build all features for different student models
//****************************************************************************
public void buildFeatures(StudentModel studentModel) {
List<StudentFeature> updatedFeatures=new ArrayList<StudentFeature>();
for(Class<? extends StudentFeature> featureClass:featuresClasses){
try {
Class<?>[] innerClasses=featureClass.getDeclaredClasses();
for(Class innerClass:innerClasses){
try{
((StudentFeature.Builder<Builder>) innerClass.newInstance()).build(studentModel);
}catch(Exception ex){
System.out.println("Error:"+ex.getLocalizedMessage());
}
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
studentModel.setFeatures(updatedFeatures);
}
}