1. 程式人生 > >反射機制下的工廠模式(寫完具體類,馬上就能用)

反射機制下的工廠模式(寫完具體類,馬上就能用)

先修知識

多型

  1. 介面與父類可作返回型別,引用宣告型別.
  2. 實現類與繼承類可作構造型別,反射強制轉換型別,反射(子類.class)獲取元型別

反射

反射一定是用在通用的場景,故利用反射機制時不應該出現具體類的名字,最多用到介面或抽象類.

  1. 定義輸入引數:public static Object getClass(Class<?extends Shape> clazz)//定義元型別Class的範圍,必須滿足是Shape的子類

ps:哪些情況可以輸入(Class clazz)元型別? 類的元型別 Object.class = Class clazz 以及物件的元型別 obj.getClass() = Class clazz.

  1. 獲取元型別物件對應的型別名:clazz.getName()
  2. 根據類名載入對應的類,執行其中的靜態方法:Class.forName(clazz.getName())
  3. 載入完後建立對應的例項:Object obj = Class.forNmae(clazz.getName()).getInstance();
  4. return obj;

應用反射工廠類時人們一般都寫好了具體類,人們是知道類名的

  1. 利用反射機制獲取對應類的類物件:Object obj = ShapeFactory.getClass(Square.clss)
  2. 用具體類強制轉換:Square square = (Square) ShapeFactory.getClass(Square.class);
  3. 完美實現子類的拓展,且不用修改工廠類的原始碼

1. 工廠模式

Factory建立物件,用於不同條件建立不同例項時.比如用三大協議連線伺服器.

優點:

想建立一個物件只要知道名稱即可.想增加一個產品線,拓展一個工廠類和具體類即可.無需知道具體實現

缺點:

每增加一個產品線,必須新增一個具體類(實驗室)和物件實現工廠.

建立介面

public interface Shape{
    void draw;
}

介面的具體類

public class Rectangle implements Shape{
    @Override
    public void draw(){
        System.
out.println("InsideRectangle::draw() method."); } }
Square
Circle

單一工廠

依據輸入的資訊,生產對應的產品

public class ShapeFactory{ public Shape getShape(String shapeType){ if(shapeType == null){ return null; } if(shapeType.equalsIgnoreCase(“CIRCLE”)){ return new Circle(); }else if(shapeType.equalsIgnoreCase(“Square”)){ return new Square(); }else if(shapeType.equalsIgnoreCase(“Rectangle”)){ return new Rectangle(); } return null;//若有輸入但資訊錯誤,則返回null

}

}

使用工廠類,生成對應產品,並訪問對應的功能

public class FactoryPatternDemo{
    public static void main(String[] args){
        ShapeFactory shapeFactory = new ShapeFactory();
        Shape shape1 = shapeFactory.getShape("Circle");
        shape1.draw();
        Shape shape2 = shapeFactory.getShape("Rectangle");
        shape2.draw();
        Shape shape3 = shapeFactory.getShape("Square");
        shape3.draw();
    }
}

採用反射機制重構工廠類

擺脫必須在原始碼中 if(具體類) return new 具體類的尷尬

尷尬是因為原始碼中寫了多少就只能用多少,想用新產品必須修改原始碼,非常麻煩

public class ShapeFactory{ public static Object getClass(Class<?extends Shape> clazz){//限制必須是Shape的子類 Object obj = null;//萬能多型物件 try{ obj = Class.forName(clazz.getNmae()).newInstance(); }catch(ClassNotFoundException e){ e.printStackTrace(); } return obj; } }

使用時強制轉換一下即可

public class FactoryPatternDemo{
    public static void main(String[] args){
        Rectangle rect = (Rectangle)ShapeFactory.getClass(Rectangle.class);
        rect.draw();
        Square square = ShapeFactory.getClass(Rectangle.class);
        square.draw();
    }
}