2016-10-09 6 views
10

यह पाइपलाइन के कार्यान्वयन के संबंध में एक डिज़ाइन प्रश्न है। निम्नलिखित मेरा निष्पक्ष कार्यान्वयन है। पाइप लाइन में कदम/चरणों में सेपाइपलाइन डिजाइन पैटर्न कार्यान्वयन

public interface Step<T, U> { 
    public U execute(T input); 
} 

कंक्रीट कार्यान्वयन:

public class StepOne implements Step<Integer, Integer> { 
    @Override 
    public Integer execute(Integer input) { 
     return input + 100; 
    } 
} 

public class StepTwo implements Step<Integer, Integer> { 
    @Override 
    public Integer execute(Integer input) { 
     return input + 500; 
    } 
} 

public class StepThree implements Step<Integer, String> { 
    @Override 
    public String execute(Integer input) { 
     return "The final amount is " + input; 
    } 
} 

पाइपलाइन वर्ग पकड़/पाइप लाइन में चरणों में दर्ज किए जाएंगे और

पाइप लाइन में अलग-अलग चरणों/चरणों के लिए इंटरफ़ेस उन्हें एक के बाद निष्पादित करें:

public class Pipeline { 
    private List<Step> pipelineSteps = new ArrayList<>(); 
    private Object firstStepInput = 100; 

    public void addStep(Step step) { 
     pipelineSteps.add(step); 
    } 

    public void execute() { 
     for (Step step : pipelineSteps) { 
      Object out = step.execute(firstStepInput); 
      firstStepInput = out; 
     } 
    } 
} 

डाइवर प्रोग्राम निष्पादन ते पाइपलाइन:

public class Main { 
    public static void main(String[] args) { 
     Pipeline pipeline = new Pipeline(); 
     pipeline.addStep(new StepOne()); 
     pipeline.addStep(new StepTwo()); 
     pipeline.addStep(new StepThree()); 

     pipeline.execute(); 
    } 
} 

हालांकि, जैसा कि आप देख सकते हैं कि निष्पक्ष कार्यान्वयन में कई सीमाएं हैं।

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

क्या कोई मुझे कोड किए गए समाधान को जोड़कर समाधान तैयार करने में मदद कर सकता है, या इसे हल करने के लिए मुझे पहले से मौजूद मौजूदा पैटर्न की ओर इशारा कर सकता है?

+1

[इस सवाल] (http://stackoverflow.com/questions/5686332/pipeline-pattern-implementation-in-java) [इस दस्तावेज़] के लिंक (http://parlab.eecs.berkeley.edu/wiki/_media/patterns/pipeline-v1.pdf) जो पैटर्न का संदर्भ देता है। –

+0

पेपर को इंगित करने के लिए @ निकबेल धन्यवाद। हालांकि, कागज के माध्यम से, मैं समझ नहीं पा रहा हूं कि पाइपलाइन को कैसे डिजाइन किया जा सकता है ताकि यह विभिन्न आउटपुट प्रकारों के चरणों/चरणों को संभाल सके। –

+2

मैं [जावा 1.8+ धाराओं] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) को देखने पर विचार करता हूं क्योंकि वे [कार्यक्षमता] प्रदान करते हैं (https://docs.oracle.com/javase/tutorial/collections/streams/)/[डॉक्टर] [http://www.oracle.com/technetwork/articles/java/ma14-java-se-8- स्ट्रीम- 2177646.html) उदाहरण के लिए आपने कहा है। [डुप्लिकेट] के लिए यहां देखें (http://stackoverflow.com/questions/8680610/java-generics-chaining-together-generic-function-object) –

उत्तर

6

मैं मैं पाइपलाइन गलत तरीके से में कदम तार हैं तो

पर ध्यान केंद्रित करेंगे, एप्लिकेशन विफल हो जाएगा।

हां, यह एक समस्या है। StepThree यहां अजनबी है। मुझे नहीं लगता कि एक साधारण पैटर्न मदद कर सकता है, मुझे लगता है कि यह रणनीति और निर्माता पैटर्न का संयोजन होना चाहिए। उदाहरण के द्वारा:

Pipeline<Integer,Integer> intPipe = new Pipeline<>(); 
intPipe = intPipe.add(new StepOne()); // increment 100 
intPipe = intPipe.add(new StepTwo()); // increment 500 
Pipeline<String, Integer> strPipe = intPipe.add(new StepThree()); // convert 

जिस पाइप लाइन इस तरह है:

public static class Pipeline<IN, OUT> { 
    //... 
    public<A> Pipeline<OUT,A> add(Step<IN,A> step) { 
    pipelineSteps.add(step); 
    return (Pipeline<OUT,A>)this; 
    } 
} 

तेजी से बिल्डर-वाक्य रचना का उपयोग इस काम हो सकता है:

Pipeline<String, Integer> pipe = new Pipeline<Integer, Integer>() 
    .add(new StepOne()).add(new StepTwo()).add(new StepThree()); 

इस के बाद से जेनरिक का हिस्सा नहीं हैं काम करना चाहिए बाइटकोड

+0

सवाल का जवाब देने के लिए पीटर धन्यवाद! :) –

+0

@PrashantChauhan आपकी सेवा में; डी –

2

आपका दृष्टिकोण बहुत अच्छा है। हालांकि, मैं इस तरह पाइपलाइन वर्ग कोड चाहते हैं:

public class Pipeline { 
    private List<Step> pipelineSteps = new ArrayList<>(); 
    private Object firstStepInput = 100; 

    public Pipeline() { 
     pipelineSteps.add(new StepOne()); 
     pipelineSteps.add(new StepTwo()); 
     pipelineSteps.add(new StepThree()); 
    } 

    public void execute() { 
     for (Step step : pipelineSteps) { 
      Object out = step.execute(firstStepInput); 
      firstStepInput = out; 
     } 
    } 

    public String getResult() { 
     return (String) firstStepInput; 
    } 
} 

इस तरह, विशिष्ट चरण ज्ञान के सभी पाइपलाइन कक्षा में समझाया गया है।

इस मामले में, निष्पादन विधि लूप निष्पादित कर सकती है। हालांकि, यदि आवश्यक हो तो निष्पादन वर्ग एक-एक करके कदम उठा सकता है।

+0

पाइपलाइन कक्षा को सही ढंग से समाहित करने के तरीके को इंगित करने के लिए धन्यवाद। –

2

आपको अतिरिक्त कक्षा Pipeline क्यों चाहिए? मुझे लगता है कि आप मध्य आदमी को हटा सकते हैं।इस वसीयत उदाहरण के लिए, अपने एपीआई सरल बना देता है:

interface Step<I, O> { 

    O execute(I value); 

    default <R> Step<I, R> pipe(Step<O, R> source) { 
     return value -> source.execute(execute(value)); 
    } 

    static <I, O> Step<I, O> of(Step<I, O> source) { 
     return source; 
    } 
} 
पहले जावा संस्करण में

आप एक अमूर्त वर्ग के बजाय का उपयोग कर सकते हैं::

Step<Integer, String> source = Step.of(Object::toString); 
Step<Integer, Integer> toHex = source.pipe(it -> Integer.parseInt(it, 16)); 

toHex.execute(11/*0x11*/);// return 17; 

आप बस में नीचे के रूप में अपने पाइप लाइन पैटर्न को लागू करता है सकते हैं

abstract static class Step<I, O> { 

    public abstract O execute(I value); 

    public <R> Step<I, R> pipe(Step<O, R> source) { 
     return new Step<I, R>() { 
      @Override 
      public R execute(I value) { 
       return source.execute(Step.this.execute(value)); 
      } 
     }; 
    } 

    public static <I, O> Step<I, O> of(Step<I, O> source) { 
     return source; 
    } 
} 
+0

निर्णय से, अंडररेड उत्तर! –

0

सार्वजनिक वर्ग पाइपलाइन {

private List<Step> pipelineSteps = new ArrayList<>(); 
private Object firstStepInput = 100; 

public Pipeline() { 
    pipelineSteps.add(new StepOne()); 
    pipelineSteps.add(new StepTwo()); 
    pipelineSteps.add(new StepThree()); 

}

+0

कृपया प्रारूपित करें (जब आप अपना उत्तर लिखते हैं तो एक पूर्वावलोकन विंडो होती है) और ** ** अपना उत्तर समझाएं। आप चाहते हैं कि लोग समझें कि आपने क्या किया है, है ना? – Rafalon

संबंधित मुद्दे