[英]How to reduce the usage of IF - ELSE by reflection ? Can I get the code example
我試圖對PizzaFactory類的代碼使用反射,以便刪除if else條件並使代碼更具動態性。 但是我不知道怎么做。
Pizza.java
package PizzaTrail;
import java.util.List;
//this is the main abstract factory which will be extended by the concrete factory
public abstract class Pizza { public abstract List fetchIngredients(String Type); }
PizzaFactory.java
package PizzaTrail;
import java.util.List;
//this is the concrete factory
public class PizzaFactory extends Pizza
{
public static Pizza getConcretePizza(String PType)
{
Pizza p=null;
if (PType.equals("Cheese"))
{
p=new CheesePizza();
} else if (PType.equals("Pepperoni"))
{
p=new PepperoniPizza();
}
else if (PType.equals("Clam"))
{
p = new CalmPizza();
}
else if (PType.equals("Veggie"))
{
p= new VeggiePizza();
}
return(p);
}
}
ChessePizza.java
package PizzaTrail;
import java.util.ArrayList;
import java.util.List;
public class CheesePizza extends Pizza {
List ing = new ArrayList();
@Override
public List fetchIngredients(String Type)
{
ing.add("Ingredient : Shredded Mozzarella Cheese");
ing.add("Ingredient : Peppers");
ing.add("Ingredient : Feta cheese");
ing.add("Ingredient : Pesto");
return (ing);
}
}
}
誰能幫助我獲得在pizzaFactory類中使用的反射,以便我可以動態調用類CheesePizza等?
請記住,使用反射來解決問題通常會給您帶來兩個問題-使用enum
怎么樣?
enum Pizzas {
Cheese {
@Override
Pizza make() {
return new CheesePizza();
}
},
Pepperoni {
@Override
Pizza make() {
return new PepperoniPizza();
}
},
Clam {
@Override
Pizza make() {
return new ClamPizza();
}
},
Veggie {
@Override
Pizza make() {
return new VeggiePizza();
}
};
abstract Pizza make();
public static Pizza make(String type) {
return Pizzas.valueOf(type).make();
}
}
public void test() {
Pizza pizza = Pizzas.make("Cheese");
}
您可以將concreate披薩的類提供給factory方法-
public static <T extends Pizza> T getConcretePizza(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
為了減少“ if-else”的使用率來回答您的問題,您可以動態確定要使用的類,例如,而不是
if (PType.equals("Cheese")) {
p=new CheesePizza();
你可以用
Class.forName(PType + "Pizza").newInstance(); // might need a package
(以上假設無參數構造函數)
這樣就可以消除任何交換式行為。
但是我不推薦這個 。 上面的代碼很難調試並且不明顯。 您的IDE可能會將此類標記為未使用,並且可能在將來的重構期間將其標記為刪除。 在絕大多數情況下,我希望澄清。
簡而言之,我寧願通過if / else序列,基於字符串的開關,字符串到方法對象的映射等來指定可用披薩的規格,而不是通過任何復雜的,非顯而易見的,可能是脆弱的機制來指定。
假設您有自己的接口Pizza public interface Pizza { \\*some methods *\\}
以及諸如public class CheesePizza implements Pizza {}
您可以創建枚舉PizzaType
enum PizzaType {
Cheese(CheesePizza.class);
Class<?> type;
PizzaType(Class<?> type) {
this.type = type;
}
Pizza create() {
try {
return (Pizza) type.newInstance();
} catch (Exception e) {
return null;
}
}
}
現在要創建新的新鮮比薩,您所需要做的就是
Pizza pizza = PizzaType.Cheese.create();
您可以維護這樣的地圖:
private static final Map<String, Class<? extends Pizza>> PIZZAS;
static {
Map<String, Class<? extends Pizza>> pizzas = new HashMap<String, Class<? extends Pizza>>();
pizzas.put("Cheese", CheesePizza.class);
pizzas.put("Pepperoni", PepperoniPizza.class);
PIZZAS = Collections.unmodifiableMap(pizzas);
}
然后,例如:
public static Pizza getConcretePizza(String type) {
Class<? extends Pizza> clazz = PIZZAS.get(type);
if (clazz == null) {
throw new IllegalStateException("No pizza of type " + type);
}
try {
return clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateException("Unable to instantiate pizza of type " + clazz.getSimpleName(), e);
}
}
您將無法避免使用帶有反射的條件,否則您的代碼有時會失敗。 但是,根據您的要求,您可以執行以下操作:
public static Object getConcretePizza(String type) throws Exception{
String pizza = String.format("pizza_trail.%sPizza", type);
Class<?> clazz = Class.forName(pizza);
Object pizzaClass = clazz.newInstance();
return pizzaClass;
}
然后,在實施期間,您可以使用if條件檢查來確定所需的披薩類型:
Object pizzaObject = PizzaFactory.getConcretePizza("Cheese");
if(pizzaObject instanceof CheesePizza){
CheesePizza pizza = (CheezePizza) pizzaObject;
// call CheesePizza related methods here.
}
PS我注意到您在包裹名稱中使用了Camelcase。 習慣在包中使用小寫字母,如果涉及到多個單詞,請使用下划線。 這只是Java約定,盡管不是必需的。
希望這對您有用。
//public static Pizza getConcretePizza(String PType){
public static Pizza getConcretePizza(Class cType){
/**
*
if (PType.equals("Cheese"))
{
p=new CheesePizza();
}//..............
*/
Constructor ctor = cType.getConstructor();
Object object = ctor.newInstance();
p = object;
//....
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.