java成员方法初始值设定模式在什么程度上这个设计是正确的错误安全以及对其进行改进的建议

问题描述:

避免在构造函数困境中重载的方法调用this approache委托变量初始化并调用可覆盖的方法给返回引用的成员方法实例自身和例外,如果试图使用实例,而不必调用初始化方法抛出/秒,使对象的创建看起来像这样java成员方法初始值设定模式在什么程度上这个设计是正确的错误安全以及对其进行改进的建议

SuperClass sup = new SuperClass().initialize("big"); 
    SubClass sub = new SubClass().initialize("sato", "try initialzer"); 
    SubClass sub2 = new SubClass().initialize("happy"); 
    SubClass sub3 = new SubClass().initialize(); 

我的超级类应该实现initializable接口的方法,它有两个方法

1)初始化我的ThOD其中我写代码来执行,以便以下

一个)呼叫设置方法和其它初始化代码
b)作出调用重写的方法将它们在该方法的结束
这种方法可以被重载以提供在复杂示例中使用必要参数的版本

2)isInitialzed方法检查初始化是否完成,当我的类中的方法调用引用初始化方法中初始化的变量并且初始化未完成我把我的NonInitializedInstanceException

子类应该重写initialize方法/ S“的所有超类的初始化方法的版本”,并做为了

1以下)初始化它的变量
2)可以调用不乱扔NonInitializedInstanceException超级方法
3)调用超级。初始化()方法
4)调用setter方法“请注意,超级调用制定者,从而避免我们的二传手已经没用了,我们应该把它叫做后超级初始化方法调用”
5)可以调用父类方法抛出NonInitializedInstanceException

通过调用从参数少一个

下面的一个与多个参数进行初始化的

处理重载版本是我的代码

接口

/** 
* @author ahmed mazher 
* @param <T> making class initializable 
* 
*/ 
public interface Initializable<T> { 

    /** 
    * do the initialization job and return reference to the implementing 
    * class current instance 
    * @return 
    */ 
    T initialize(); 

    /** 
    * test the variables that you initialize in the initialize method 
    * if it was initialized or not "or what ever test you see appropriate" 
    * @return 
    */ 
    boolean isInitialized(); 
} 

的NonInitializedInstanceException类使用利用与参数初始化它们

/** 
* @author ahmed mazher 
* testing the initializer pattern 
*/ 
class LearnJava { 

    public static void main(String args[]) { 
     SuperClass sup = new SuperClass().initialize(); 
     SubClass sub = new SubClass().initialize(); 
    } 

} 

class SuperClass implements Initializable<SuperClass> { 

    private String initializeDependentName; 
    private final String nonInitializeDependentVal = "well done"; 
    @Override 
    public SuperClass initialize() { 
     //initializing super Class fields 
     setInitializeDependentName("super class"); 
     //overidable method call in initializer "replacement of 
     //call in constructor" 
     overridablePrintName(); 
     return this; 
    } 

    public final String getInitializeDependentName() throws NonInitializedInstanceException { 
     if (!isInitialized()) { 
      throw new NonInitializedInstanceException(); 
     } 
     return initializeDependentName; 
    } 

    public final void setInitializeDependentName(String initializeDependentName) { 
     this.initializeDependentName = initializeDependentName; 
    } 

    public final void youCanCallMeBeforeInitialization(){ 
     System.out.println(nonInitializeDependentVal); 
    } 

    public void overridablePrintName() { 
     System.out.println("I'm the super method and my name is " + getInitializeDependentName()); 
    } 

    @Override 
    public boolean isInitialized() { 
     return initializeDependentName != null; 
    } 
//to avoid some one messing with isInitialized() make your 
    //private one and use it instead but don't forget to call it inside 
    //the body of isInitialized() to maintian integrity of inheritance hierarchy 
// private boolean privateIsInitialized(){ 
//  return initializeDependentName != null; 
// } 
// @Override 
// public boolean isInitialized() { 
//  return privateIsInitialized(); 
// } 

} 

class SubClass extends SuperClass { 

    private String job; 

    @Override 
    public SubClass initialize() { 
     //initializing subClass fields 
     setJob("testing initialize method"); 
     //call super method that throws nonInitialiezinstanceException 
     //before call super.initialize() method will rise the exception 
     //unless you overided the isInitialized method "welling to take the risk" 
     //------------------------------------------------------------------ 
     //System.out.println(getName().toUpperCase()); 
     //------------------------------------------------------------------ 
     //call super method that not throws nonInitialiezinstanceException 
     //before call super.initialize() method 
     youCanCallMeBeforeInitialization(); 
     setInitializeDependentName("subClass"); 
     //calling super.initialize() method initialize super methods 
     super.initialize();//initialize the super class 
     //call super method that throws nonInitialiezinstanceException 
     //after call super.initialize() method will not rise the exception 
     //unless you overided the isInitialized method in stupid way ^_^ 
     System.out.println(getInitializeDependentName().toUpperCase()); 
     //calling the setter method now to change my property as calling 
     //it before the super initialization is useless as the super 
     //initialization will erase it 
     setInitializeDependentName("subClass"); 
     System.out.println(getInitializeDependentName().toUpperCase()); 
     return this; 
    } 

    public final void setJob(String job) { 
     this.job = job; 
    } 

    @Override 
    public void overridablePrintName() { 
     System.out.println("i'm overriden method and i do " + job); 
    } 

    @Override 
    public boolean isInitialized() { 
     //return false;//stupid version 
     //return true;//take the risk 
     return job != null && super.isInitialized();//a good one 
    } 

} 

一个更复杂的例子的

/** 
* @author Ahmed mazher 
* runtime exception to be thrown by method that reference variables that 
* are initialized by the initialize method of the initializable interface 
* you can test if initialization was done or not by isInialized method 
* of the same interface if false throw the exception 
*/ 
public class NonInitializedInstanceException extends RuntimeException { 

    private static final long serialVersionUID = 1L; 


    @Override 
    public String getMessage() { 
     return super.getMessage() 
       + " you must call instance.initialize() method " 
       + "before calling this method"; 
    } 

} 

例如

class LearnJava { 

    public static void main(String args[]) { 
     SuperClass sup = new SuperClass().initialize("big"); 
     SubClass sub = new SubClass().initialize("sato", "try initializer"); 
     SubClass sub2 = new SubClass().initialize("happy"); 
     SubClass sub3 = new SubClass().initialize(); 
    } 

} 

class SuperClass implements Initializable<SuperClass> { 

    private String initializeDependentName; 
    private final String nonInitializeDependentVal = "well done"; 

    @Override 
    public SuperClass initialize() { 
     return initialize("i'm super with no name"); 
    } 

    public SuperClass initialize(String name) { 
     //initializing super Class fields 
     setInitializeDependentName(name); 
     //overidable method call in initializer "replacement of 
     //call in constructor" 
     overridablePrintName(); 
     return this; 
    } 

    public final String getInitializeDependentName() throws NonInitializedInstanceException { 
     if (!isInitialized()) { 
      throw new NonInitializedInstanceException(); 
     } 
     return initializeDependentName; 
    } 

    public final void setInitializeDependentName(String initializeDependentName) { 
     this.initializeDependentName = initializeDependentName; 
    } 

    public final void youCanCallMeBeforeInitialization() { 
     System.out.println(nonInitializeDependentVal); 
    } 

    public void overridablePrintName() { 
     System.out.println("i'm the super method my name is " + getInitializeDependentName()); 
    } 

    @Override 
    public boolean isInitialized() { 
     return initializeDependentName != null; 
    } 

    //to avoid some one messing with isInitialized() make your 
    //private one and use it instead but don't forget to call it inside 
    //the body of isInitialized() to maintian integrity of inheritance hierarchy 
// private boolean privateIsInitialized(){ 
//  return initializeDependentName != null; 
// } 
// @Override 
// public boolean isInitialized() { 
//  return privateIsInitialized(); 
// } 
} 

class SubClass extends SuperClass { 

    private String job; 

    @Override 
    public SubClass initialize() { 
     return initialize("i'm subclass no one give me name"); 
    } 

    @Override 
    public SubClass initialize(String name) { 
     return initialize(name, "no one give me job"); 
    } 

    public SubClass initialize(String name, String job) { 
     //initializing subClass fields 
     setJob(job); 
     //call super method that throws nonInitialiezinstanceException 
     //before call super.initialize() method will rise the exception 
     //unless you overided the isInitialized method "welling to take the risk" 
     //------------------------------------------------------------------ 
     //System.out.println(getName().toUpperCase()); 
     //------------------------------------------------------------------ 
     //call super method that not throws nonInitialiezinstanceException 
     //before call super.initialize() method 
     youCanCallMeBeforeInitialization(); 
     //calling super.initialize() method initialize super methods 
     super.initialize(name);//initialize the super class 
     //call super method that throws nonInitialiezinstanceException 
     //after call super.initialize() method will not rise the exception 
     //unless you overided the isInitialized method in stuped way ^_^ 
     System.out.println(getInitializeDependentName().toUpperCase()); 
     //calling the setter method now to change my property as calling 
     //it before the super initialization is useless as the super 
     //initialization will erase it 
     setInitializeDependentName("setter called in subclass"); 
     System.out.println(getInitializeDependentName().toUpperCase()); 
     return this; 
    } 

    public final void setJob(String job) { 
     this.job = job; 
    } 

    @Override 
    public void overridablePrintName() { 
     System.out.println("i'm overiden method my name is " 
       + getInitializeDependentName() 
       + " and i do " + job); 
    } 

    @Override 
    public boolean isInitialized() { 
     //return false;//stuped version 
     //return true;//take the risk 
     return job != null && super.isInitialized();//a good one 
    } 

} 

使用静态方法工厂模式作为与建议我预计静态疼痛永远不会结束在这里是我的试验,以适应我的模式变成静态Ë但我失败了,我不知道如何让子类中调用父类创建的方法来影响它的实例

class LearnJava { 

    public static void main(String args[]) { 
     SuperClass.create("nono"); 
     SubClass.create("sato","test factory"); 

    } 

} 

class SuperClass{ 

    private String name; 
    protected SuperClass() { 
    } 

    public static SuperClass create(String name) { 
     SuperClass sup = new SuperClass(); 
     //initializing super Class fields 
     sup.setName(name); 
     //overidable method call useless as i always call the super instance version 
     sup.overridablePrintName(); 
     return sup; 
    } 

    public final String getName(){ 
     return name; 
    } 

    public final void setName(String name) { 
     this.name = name; 
    } 

    public void overridablePrintName() { 
     System.out.println("i'm the super method my name is " + getName()); 
    } 
} 

class SubClass extends SuperClass { 

    private String job; 

    protected SubClass() { 
     super(); 
    } 

    public static SubClass create(String name, String job) { 
     SubClass sub = new SubClass(); 
     //initializing subClass fields 
     sub.setJob(job); 
     //call the super class initializer to affect this sub class instatnce 
     //seems no way to do it 
     sub.create(name); 
     SubClass.create(name); 
     SuperClass.create(name); 
     return sub; 
    } 

    public final void setJob(String job) { 
     this.job = job; 
    } 

    @Override 
    public void overridablePrintName() { 
     System.out.println("i'm overiden method my name is " 
       + getName() 
       + " and i do " + job); 
    } 
} 

我希望这是一个好主意,等待您的意见和建议

+0

这个问题属于上http://codereview.stackexchange.com/ – jaco0646

+0

我应该怎么做这个解释,请我如何能迁移问题发表 –

这是一个好主意寻找一些初始化方法将为您提供一些很好的结构和高品质的代码,但我想你可能指的是Factory Method Pattern这样你就可以提高你的所作所为已经

工厂方法模式是封装对象的方式创建。 没有工厂方法,您只需直接调用该类的构造函数 即可:Foo x = new Foo()。使用这种模式,您可以调用工厂方法 :Foo x = Foo.create()。 构造函数被标记为私有的,所以它们不能在类中被调用,除了 以外,工厂方法被标记为静态,因此可以在没有对象的情况下调用 。

+0

一个很好的教程中我将通过它的感谢 –

+0

静态问题工厂模式是它是静态的“静止的无尽的痛苦^ _^ –

+0

我认为静态工厂模式不那么痛苦,因为你要用一个指令Foo.create()初始化和初始化你的对象,否则你可以使用相同的模式有一些轻微的定制,你可以使构造函数公开,所以你可以用它来实例化你的类,并在你的构造函数中,你可以隐式地调用初始化方法 –