2012-05-22 14 views
10

मैं अपने सर्वश्रेष्ठ पर व्याख्या करने की कोशिश करूंगा।स्थिर संदर्भ में विशिष्ट वस्तुओं के साथ सामान्य वर्ग का उपयोग कैसे करें?

मैं प्ले फ्रेमवर्क 2 का उपयोग करता हूं, और मैं बहुत सी सीआरयूडी क्रियाएं करूंगा। उनमें से कुछ पहचान में होंगे, इसलिए मैं किस और डीआरवाई करना चाहता हूं इसलिए पहले मैं list, 10, create, update और delete विधियों के साथ सामान्य वस्तु के साथ एक सार वर्ग के बारे में सोच रहा था, और यह निर्दिष्ट करके इस वर्ग को विस्तारित करता हूं

public abstract class CrudController extends Controller { 
    protected static Model.Finder<Long, Model> finder = null; 
    protected static Form<Model> form = null; 

    public static Result list() { 
     // some code here 
    } 

    public static Result details(Long id) { 
     // some code here 
    } 

    public static Result create() { 
     // some code here 
    } 

    public static Result update(Long id) { 
     // some code here 
    } 

    public static Result delete(Long id) { 
     // some code here 
    } 
} 

और एक वर्ग है कि CRUD का उपयोग करेगा:: वस्तु (मॉडल & फॉर्म) का उपयोग करने के

public class Cities extends CrudController { 
    protected static Model.Finder<Long, City> finder = City.find; 
    protected static Form<City> form = form(City.class); 

    // I can override a method in order to change it's behavior : 
    public static Result list() { 
     // some different code here, like adding some where condition 
    } 
} 

यह है कि अगर मैं एक स्थिर संदर्भ में नहीं था काम करेगा।

लेकिन चूंकि यह मामला है, मैं कैसे कर सकता हूं?

+0

क्यों इंस्टेंस विधियों पर स्विच न करें? विरासत जावा में कक्षा विधियों पर काम नहीं करती है। – Vlad

+0

संरचना के साथ विरासत को प्रतिस्थापित करने का एक और विचार हो सकता है: केवल क्रूड कंट्रोलर के उदाहरण हैं और ऑपरेशन को विशिष्ट-निर्दिष्ट निहित ऑब्जेक्ट में प्रतिनिधि दें। (यह सब निश्चित रूप से आपके डिजाइन पर निर्भर करता है।) – Vlad

+0

@Vlad: पहले प्रश्न के लिए, मैं नहीं कर सकता, नियंत्रक के लिए स्थैतिक विधि की आवश्यकता है। अब दूसरे के लिए, मुझे समझ में नहीं आ रहा है, क्या आप विस्तारित कर सकते हैं (या एक नया उत्तर बना सकते हैं)? –

उत्तर

13

इस प्रतिनिधिमंडल का प्रयोग कर प्राप्त किया जा सकता है: CRUD कार्यों तर्क युक्त एक नियमित रूप से जावा वर्ग को परिभाषित:

केवल आपके:
public class Crud<T extends Model> { 

    private final Model.Finder<Long, T> find; 
    private final Form<T> form; 

    public Crud(Model.Finder<Long, T> find, Form<T> form) { 
     this.find = find; 
     this.form = form; 
    } 

    public Result list() { 
     return ok(Json.toJson(find.all())); 
    } 

    public Result create() { 
     Form<T> createForm = form.bindFromRequest(); 
     if (createForm.hasErrors()) { 
      return badRequest(); 
     } else { 
      createForm.get().save(); 
      return ok(); 
     } 
    } 

    public Result read(Long id) { 
     T t = find.byId(id); 
     if (t == null) { 
      return notFound(); 
     } 
     return ok(Json.toJson(t)); 
    } 

    // … same for update and delete 
} 

तो फिर तुम Crud<City> का एक उदाहरण से युक्त एक स्थिर क्षेत्र होने एक प्ले नियंत्रक को परिभाषित कर सकते हैं:

public class Cities extends Controller { 
    public final static Crud<City> crud = new Crud<City>(City.find, form(City.class)); 
} 

और आप लगभग पूर्ण कर लिया Crud कार्यों के लिए मार्गों परिभाषित करने की जरूरत:

GET /     controllers.Cities.crud.list() 
POST /     controllers.Cities.crud.create() 
GET  /:id     controllers.Cities.crud.read(id: Long) 

नोट: इस उदाहरण brevety के लिए JSON प्रतिक्रियाओं का उत्पादन लेकिन यह एचटीएमएल टेम्पलेट्स प्रस्तुत करना संभव है। हालांकि, चूंकि प्ले 2 टेम्पलेट्स को स्थाई रूप से टाइप किया गया है, इसलिए आपको Crud कक्षा के पैरामीटर के रूप में उन सभी को पास करने की आवश्यकता होगी।

+0

नियंत्रक के आधार पर एक दृश्य को वापस करने वाला इमो मुश्किल हिस्सा है, आप इसे कैसे हल करेंगे? –

+0

यह वास्तव में एक दिलचस्प समस्या है। नियंत्रक की स्थिर प्रकृति (जो विरासत को अस्वीकार करता है) के बावजूद कुछ तर्कों का पुन: उपयोग करने के बारे में यह सवाल अधिक था। शायद आपको एक और सवाल खोलना चाहिए? –

+1

सच है, यह वास्तव में इस प्रश्न के दायरे में नहीं है। लेकिन बस जवाब दे रहा था जब आपका जवाब पढ़ रहा था, जो मुझे पसंद है! शायद मैं आज रात एक और सवाल खोलूंगा। –

4

:

निम्नलिखित विचार मदद कर सकता है (अस्वीकरण मैं playframework साथ कोई अनुभव नहीं है।):

public interface IOpImplementation { 
    public static Result list(); 
    public static Result details(Long id); 
    public static Result create(); 
    public static Result update(Long id); 
    public static Result delete(Long id); 
} 

public abstract class CrudController extends Controller { 
    protected static Model.Finder<Long, Model> finder = null; 
    protected static Form<Model> form = null; 

    protected static IOpImplementation impl; 

    public static Result list() { 
     return impl.list(); 
    } 

    public static Result details(Long id) { 
     return impl.details(id); 
    } 
    // other operations defined the same way 
} 

public class Cities extends CrudController { 

    public static Cities() { 
     impl = new CitiesImpl(); 
    } 

} 

इस तरह आप कार्यान्वयन के एक पदानुक्रम बना सकते हैं।

(यह कुछ फैंसी नाम डिज़ाइन पैटर्न होना चाहिए, लेकिन मैं नाम एटीएम पता नहीं है।)

+0

आपके उत्तर के पीछे कुछ अच्छा विचार है, लेकिन जो मैं खोज रहा हूं, डेटाबेस (शहरों, आदि) में संशोधित करने के लिए मॉडल द्वारा कक्षा है। क्योंकि जब मैं मार्गों को परिभाषित करता हूं, तो मुझे उन्हें एक विशिष्ट वर्ग (नियंत्रक) पर इंगित करने की आवश्यकता होती है। यह नियंत्रक परिभाषित करेगा कि कौन सा मॉडल उपयोग करना है। इसलिए यदि क्रूड कंट्रोलर बदलता है तो यह कोई समस्या नहीं है, कोड को विभिन्न वर्गों के बीच समान होने के मामले में प्रत्येक क्रूड नियंत्रक के लिए जितना संभव हो उतना छोटा कोड लिखना होगा। –

+0

@ cx42net: मुझे "मॉडल द्वारा कक्षा रखने" के हिस्से को समझ में नहीं आया। क्या इसका मतलब यह है कि प्रत्येक संभावित 'मॉडल' के लिए 'क्रूड कंट्रोलर' (या शायद 'क्रूडकंट्रोलर'' का एक उदाहरण प्राप्त किया गया एक वर्ग होना चाहिए? – Vlad

+0

ओह, यह काम नहीं करेगा, क्योंकि कोई उदाहरण नहीं है। रुको, मैं इसे अपडेट कर दूंगा। – Vlad