反射機制下的工廠模式(寫完具體類,馬上就能用)
先修知識
多型
- 介面與父類可作返回型別,引用宣告型別.
- 實現類與繼承類可作構造型別,反射強制轉換型別,反射(子類.class)獲取元型別
反射
反射一定是用在通用的場景,故利用反射機制時不應該出現具體類的名字,最多用到介面或抽象類.
- 定義輸入引數:public static Object getClass(Class<?extends Shape> clazz)//定義元型別Class的範圍,必須滿足是Shape的子類
ps:哪些情況可以輸入(Class clazz)元型別? 類的元型別 Object.class = Class clazz 以及物件的元型別 obj.getClass() = Class clazz.
- 獲取元型別物件對應的型別名:clazz.getName()
- 根據類名載入對應的類,執行其中的靜態方法:Class.forName(clazz.getName())
- 載入完後建立對應的例項:Object obj = Class.forNmae(clazz.getName()).getInstance();
- return obj;
應用反射工廠類時人們一般都寫好了具體類,人們是知道類名的
- 利用反射機制獲取對應類的類物件:Object obj = ShapeFactory.getClass(Square.clss)
- 用具體類強制轉換:Square square = (Square) ShapeFactory.getClass(Square.class);
- 完美實現子類的拓展,且不用修改工廠類的原始碼
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();
}
}