2010-11-29 2 views
6

में रचना और इंटरफेस का उपयोग कर डिजाइन मैं एक समस्या के लिए निम्नलिखित बनाया गया है।जावा

चूंकि जावा एकाधिक विरासत का समर्थन नहीं करता है, इसलिए मुझे Rhinoceros बनाने में परेशानी है जो एक हॉर्न और पूंछ वाला जानवर है। चारों ओर पूछने के बाद, किसी ने रचना और इंटरफेस का उपयोग करने की सिफारिश की। मैं निम्नलिखित के साथ आया:

class Animal { 
// ... 
} 
class Guppy extends Animal { ... } 
class Pigeon extends Animal { ... } 
class Ram extends Animal implements IHorned { ... } 
class Cat extends Animal implements ITailed { ... } 
class Dog extends Animal implements ITailed { 
BasicTail t = new BasicTail(); 
public Object getTail() { 
    return t.getTail(); 
} 
public void setTail(Object in) { 
    t.setTail(in); 
} 
} 

interface ITailed { 
public Object getTail(); 
public void setTail(Object in); 
//... 
} 

class BasicTail implements ITailed { 
Object myTail; 
public Object getTail() { return myTail; } 
public void setTail(Object t) { myTail = t; } 
} 

interface IHorned { 
// getters and setters 
} 

public static void main(String[] args) { 
Animal a = getSomeAnimal(); 
a.doSomething(); 
    // how do I check if a is horned or tailed? 
} 

मेरे इंटरफ़ेस में गेटर्स और सेटर्स हैं। क्या इससे बचने का कोई तरीका है? यह मानते हुए कि पूंछ और हॉर्न के व्यवहार को अमूर्त करने का कोई तरीका नहीं है, और इन्हें मुख्य रूप से डेटा धारकों के रूप में उपयोग किया जा रहा है। मैं कैसे निर्धारित करूं कि मेरा पशु शर्मीला है या पूंछ है?

+0

3. 'isinstance IHorned' – khachik

+1

Khachik, मेरा मानना ​​है कि यह 'instanceof IHorned' –

+0

हाँ, 3. –

उत्तर

4

मुझे लगता है कि आपको सामान्य रूप से सेटर्स से बचना चाहिए। यदि आप कर सकते हैं, अपरिवर्तनीय वस्तुओं का उपयोग करें, और अपने निजी डेटा अपने कन्स्ट्रक्टर में शुरू करें।

जानवरों को अलग करने के लिए, मैंने एक और पैटर्न, आगंतुक एक का उपयोग किया। यह verbose है, लेकिन आप सीधे परीक्षण करने की जरूरत नहीं है कि आप कौन सा जानवर प्रसंस्करण कर रहे हैं।

public class Animals { 
private Animals() { 
} 

interface Animal { 
    void accept(final AnimalProcessor visitor); 
} 

interface AnimalProcessor { 
    void visitTailed(final TailedAnimal tailedAnimal); 

    void visitHorned(final HornedAnimal hornedAnimal); 
} 

interface TailedAnimal extends Animal { 
    void moveTail(); 
} 

interface HornedAnimal extends Animal { 
    void hitWithHorns(); 
} 

static class Dog implements TailedAnimal { 
    public void moveTail() { 
     //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public void accept(final AnimalProcessor visitor) { 
     visitor.visitTailed(this); 
    } 
} 

static class Cat implements TailedAnimal { 
    public void moveTail() { 
     //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public void accept(final AnimalProcessor visitor) { 
     visitor.visitTailed(this); 
    } 
} 

static class Ram implements HornedAnimal { 
    public void hitWithHorns() { 
     //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public void accept(final AnimalProcessor visitor) { 
     visitor.visitHorned(this); 
    } 
} 

static class Rhinoceros implements HornedAnimal, TailedAnimal { 
    public void hitWithHorns() { 
     //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public void moveTail() { 
     //To change body of implemented methods use File | Settings | File Templates. 
    } 

    public void accept(final AnimalProcessor visitor) { 
     visitor.visitTailed(this); 
     visitor.visitHorned(this); 
    } 
} 

public static void main(String[] args) { 
    Collection<Animal> animals = new ArrayList<Animal>(Arrays.asList(new Dog(), new Cat(), new Rhinoceros())); 
    for (final Animal animal : animals) { 
     animal.accept(new AnimalProcessor() { 
      public void visitTailed(final TailedAnimal tailedAnimal) { 
       // you do what you want when it's a tailed animal 
      } 

      public void visitHorned(final HornedAnimal hornedAnimal) { 
       // you do what you want when it's a horned animal 
      } 
     }); 
    } 
} 
} 
+0

आगंतुक पैटर्न का जवाब के लिए धन्यवाद अक्सर वास्तव में एक बहुत लचीला एक (इस मामले में) के रूप में, विशेष रूप से, क्योंकि यह बचा जाता है बुरा 'उदाहरण' चेक। विधि नाम – Mot

1

मैंने अपना पिछला उत्तर संपादित कर लिया है। मैंने कुछ बेहतर सोचा। यदि आप उत्सुक हैं तो इस पोस्ट के लिए संशोधन देखें।

विशिष्टता पैटर्न का उपयोग करें। यह बिल बिलकुल फिट बैठता है - सजावट से ज्यादा रास्ता। अगर किसी जानवर को सींग किया गया तो आपने "जांच" करने को कहा। सजावट पैटर्न पारदर्शिता प्रदान करता है, जबकि इस स्थिति में आप भेदभाव के लिए पूछ रहे हैं।

विशिष्टता पैटर्न कुछ मानदंडों का मूल्यांकन करने के तरीके के बारे में ज्ञान को समाहित करता है। हमारे मामले में, हम कुछ चाहते हैं:

public interface Specification { 

    public boolean isSatisfiedBy(Animal aCriteria); 

} 

public class HornedAnimalSpecification implements Specification { 

    @Override 
    public boolean isSatisfiedBy(Animal aCriteria) { 
     //Right here is where the heart of your problem 
     //can be solved. 
     // 
     //Reserved conquering grounds. 
    } 

} 

अब आप अपने पशु पदानुक्रम को परिभाषित कर सकते हैं हालांकि आप चाहते हैं। केवल एक चीज जो आपको अब करने की ज़रूरत है वह है एक जानवर को सींग का बना देता है। उस प्रश्न का आपका उत्तर विशिष्टता वर्ग में जाता है। फिर आपका मुख्य कार्य पाई के रूप में आसान है।

public class Zoo { 

    public static void main(String[] args) { 
     Animal ram = getHornedAnimal(); //Instantiate however you'd like. 
     Specification specification = new HornedAnimalSpecification(); 

     if (specification.isSatisfiedBy(ram)) { 
      //Bingo, it's horned. 
     } else { 
      //Not horned! 
     } 
    } 

} 
8

मैं यहां रणनीति पैटर्न का सुझाव दूंगा। संक्षेप में:

interface TailedAnimal { 
    void moveTail(); 
} 
interface HornedAnimal { 
    void hitWithHorn(); 
} 
class Rhinoceros() implements TailedAnimal, HornedAnimal { 
    private TailedAnimal tail; //Instantiate it somehow e.g. constructor, setter 
    private HornedAnimal horn; //Instantiate is somehow e.g. constructor, setter 
    public void moveTail() { 
     tail.moveTail(); 
    } 
    public void hitWithHorn() { 
     horn.hitWithHorn(); 
    } 
} 

इस का उपयोग कर आप इंटरफेस के ठोस कार्यान्वयन, andmay आसान शेयर में कुछ जानवरों के लिए बिल्कुल वैसा ही व्यवहार में व्यवहार, साथ ही रन-टाइम में यह परिवर्तन संपुटित।

+1

+1, मुझे पहले मिल गया;)। वैसे भी, यह जवाब मेरी तुलना में अधिक "कॉम्पैक्ट" है –

+0

हे के लिए –