2014-05-15 2 views
0

PizzaFactory 클래스의 코드에 리플렉션을 사용하여 if else 조건을 제거하고 내 코드를보다 동적으로 만들려고했습니다. 그러나 나는 방법을 알아낼 수 없다.반사에 의한 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); 
     } 

    } 

    } 

누군가가 나에게 내가 클래스 CheesePizza를 호출 할 수 있도록 pizzaFactory 클래스에 사용되는 반사 등 동적으로 얻을 도와 드릴까요?

당신은 팩토리 메소드에 concreate 피자의 클래스를 제공 할 수
+0

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html – JasonSec

+2

내가 반사 방법으로 경우 다른 사람을 대체 할 – Gus

+0

열거 유형을 살펴, 스위치 문을 . 그것과 비슷하게 클래스를 동적으로 호출 할 수 있습니다. 몇 줄의 코드 만 작성할 수 있으며 호출 된 특정 클래스를 확인하고 가져올 수 있습니다. 그렇지 않으면 ... 반사를 사용합니다. 그것은 가능한가? –

답변

0

이 'IF-다른'사용을 줄이는 측면에서 귀하의 질문에 대답하려면, 당신은 동적으로 사용하는 클래스를 결정할 수있다 예 대신

if (PType.equals("Cheese")) { 
    p=new CheesePizza(); 

당신은

Class.forName(PType + "Pizza").newInstance(); // might need a package 

(위의 인자없는 생성자 가정)를 사용

을하고는 전환 형 동작을 제거 할 수 있습니다.

그러나 나는이을 권장하지 않습니다. 위의 내용은 디버그하기가 어렵고 명확하지 않습니다. IDE는 사용되지 않는 클래스와 향후 리팩터링 중에 제거 할 수있는 클래스를 표시합니다. 나는 대다수의 경우에 명확성을 선호합니다.

간단히 말해, if/else 시퀀스, String 기반 스위치, 메소드 객체에 대한 문자열 맵 등을 통해 사용 가능한 피자의 사양을 지정하는 것이 훨씬 복잡합니다. 기구.

+0

감사합니다! 귀하의 대답은 간단했고 동일한 논리를 적용했습니다. 지금은 잘 작동합니다. –

1

-

public static <T extends Pizza> T getConcretePizza(Class<T> clazz) { 
    try { 
     return clazz.newInstance(); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 
+0

해답을 얻은 솔루션에 감사드립니다. –

0

은 인터페이스 피자 당신이 말할 수 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; 
      } 
    } 
    } 

당신이해야 할 일을 모든 새로운 신선한 피자를 만들 수 is

Pizza pizza = PizzaType.Cheese.create();

2

문제를 해결하기 위해 리플렉션을 사용하면 일반적으로 enum을 사용하는 경우 두 가지 문제가 발생합니다. 코드 그렇지 않으면

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); 
    } 
} 
+0

이것은 훨씬 덜 무서운 것 같습니다. 프로그램의 나머지 부분이 어떻게 작동하는지에 따라 문자열 의존성을 완전히 제거하고 열거 형을 사용할 수 있습니다. –

+0

@RichardTingle - 열거 형을 사용하는 것이 훨씬 더 좋은 옵션입니다. – OldCurmudgeon

+0

@RichardTingle 당신의 소중한 제안에 감사드립니다. 그러나 ENUM을 사용하지 않고 Reflection 만 사용하여 목적을 달성했습니다. 그것은 또한 코드가 끔찍하지 않게 만들었습니다. –

0

당신은지도를 유지할 수 어느 시점에서 실패합니다.그러나, 귀하의 요청 주어, 당신은이 작업을 수행 할 수 있습니다

Object pizzaObject = PizzaFactory.getConcretePizza("Cheese"); 
if(pizzaObject instanceof CheesePizza){ 
    CheesePizza pizza = (CheezePizza) pizzaObject; 
    // call CheesePizza related methods here. 

} 

추신 :

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; 
} 

그런 다음, 구현 동안, 당신은 당신이 경우 조건 검사를 사용하여 원하는 피자의 종류를 확인할 수 있습니다 귀하의 패키지 이름에 Camelcase를 사용하고있는 것으로 나타났습니다. 패키지에 소문자를 사용하는 습관을 들여야하며, 여러 단어가 들어있는 경우에는 밑줄을 사용하십시오. 이것은 필수 조건은 아니지만 자바 규칙 일뿐입니다.

이 정보가 도움이되기를 바랍니다.

0

당신은 반사와 조건의 사용을 피할 수 없을 것입니다

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); 
} 

그런 다음, 예를 들어 :

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"); 
} 
+0

의견을 보내 주셔서 감사합니다. –

0
 //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; 


    //.... 
     } 
+0

안녕하세요. 답이 왜 작용하는지에 대한 설명을 게시 한 다음 질문자/다른 사람들은 왜 그것이 효과가 있는지 더 잘 알 수 있습니다. – ElectronicGeek

관련 문제