জাভা সুইংয়ের ভিউ / কন্ট্রোলার থেকে মডেলটিকে কীভাবে সম্পূর্ণ ডিকুয়েল করবেন


10

জাভা সুইং অ্যাপে মডেল ক্লাসগুলি ভিউ / কন্ট্রোলার ক্লাস থেকে আলাদা করার জন্য কি সাধারণভাবে সম্মত-নকশাকৃত নির্দেশিকাটির সংগ্রহ রয়েছে? আমি এতটা উদ্বিগ্ন নই যে ভিউ / কন্ট্রোলার মডেলটি সম্পর্কে অন্য উপায় হিসাবে কিছুই জানেন না: জাভ্যাক্স.সুইংয়ের কোনও কিছুর অজানা থাকতে আমি আমার মডেলটি ডিজাইন করতে চাই। আদর্শভাবে এটির একটি সাধারণ এপিআই থাকা উচিত যা এটি কোনও সিএলআইয়ের মতো আদিম কিছু দ্বারা চালিত করতে সক্ষম করে। এটি হওয়া উচিত, আলগাভাবে বলতে গেলে একটি "ইঞ্জিন"।

মডেলটিতে জিইউআই ইভেন্টগুলি যোগাযোগ করা খুব কঠিন নয় - অ্যাকশন পারফর্মাররা মডেলটির এপিআইতে কল করতে পারেন। তবে কী হবে যখন মডেলটি তার নিজস্ব রাজ্য পরিবর্তন করে যা জিইউআইতে প্রতিবিম্বিত হওয়া প্রয়োজন? এটি "শ্রবণ" এর জন্য যা, তবে "শ্রবণ করা" সম্পূর্ণ প্যাসিভ নয়; এটির প্রয়োজন মডেলটি শ্রোতা যুক্ত করার বিষয়ে জানতে।

যে বিশেষ সমস্যাটি আমাকে ভাবতে পেরেছিল তাতে ফাইলগুলির একটি সারি জড়িত। জিইউআই পাশের DefaultListModelপিছনে একটি রয়েছে JList, এবং ফাইল সিস্টেম থেকে ফাইলগুলি বেছে নিতে এবং এটিকে জেলিস্টে যুক্ত করার জন্য কিছু জিইআইআই স্টাফ রয়েছে। মডেলের দিকে, এটি এই "সারি" এর নীচে থেকে ফাইলগুলি টানতে চায় (তাদের জে এলিস্ট থেকে অদৃশ্য হয়ে যাওয়ার কারণে) এবং কোনও উপায়ে তাদের প্রক্রিয়া করতে চায়। আসলে, মডেল কোডটি ইতিমধ্যে লিখিত - এটি বর্তমানে একটি বজায় রাখে ArrayList<File>এবং একটি সর্বজনীন add(File)পদ্ধতি প্রকাশ করে exp তবে মডেলটিতে কিছু ভারী, সুইং-নির্দিষ্ট পরিবর্তন ছাড়াই কীভাবে আমার মডেলটি ভিউ / কন্ট্রোলারের সাথে কাজ করতে হয় তা নিয়ে আমার ক্ষতি হয়।

আমি জাভা এবং জিইউআই উভয় প্রোগ্রামিংয়েই খুব নতুন, এখন অবধি সর্বদা "ব্যাচ" এবং "ব্যাক-এন্ড" প্রোগ্রামিং করেছি - সুতরাং মডেল এবং ইউআইয়ের মধ্যে কঠোর বিভাজন বজায় রাখার আগ্রহ আমার, যদি এটি সম্ভব হয় এবং পড়াতে হবে।



বিটিডব্লিউ: এমভিসিতে মডেলটি ভিউ এবং ডিফল্টরূপে নিয়ামক থেকে ডিক্লোল করা উচিত। আপনার আবার আপনার পাঠ্যপুস্তকটি পড়া উচিত, আমার ধারণা আপনি ধারণাটি বেশ বুঝতে পারেন নি। এবং আপনি একটি কাস্টম সংগ্রহ বাস্তবায়িত করতে পারেন যা এটি পরিবর্তিত হয় যখন সূচিত হয়, অনেকটা। নেট এর আইএনটিফাইও কালেকশন পরিবর্তনযুক্ত ইন্টারফেসের মতো।
ফ্যালকন

@ ফ্যালকন: লিঙ্কগুলির জন্য ধন্যবাদ। তবে আমি আপনার মন্তব্য বুঝতে পেরেছি তা নিশ্চিত নয় .. "" মডেলটি ভিউ এবং ডিফল্টরূপে নিয়ামক থেকে ডিক্লোল করা উচিত "। আপনি কি পুনরায় ব্যাখ্যা বা বিস্তারিত বলতে পারেন?
চ্যাপ

উত্তর:


10

এমভিসির জন্য কোনও সাধারণভাবে সম্মত- (অর্থাত্ ডিফাক্টো ) নকশার নির্দেশিকা নেই। এটি নিজে করা সম্পূর্ণরূপে কঠিন নয় তবে আপনার ক্লাস এবং কিছু সময় এবং ধৈর্য সম্পর্কে কিছু পরিকল্পনা প্রয়োজন।

কোনও নির্দিষ্ট সমাধান না হওয়ার কারণ হ'ল এমভিসি করার একাধিক উপায় রয়েছে, সবগুলিই তাদের পক্ষে মতামত cons তাই কেবল এটি সম্পর্কে স্মার্ট হয়ে থাকুন এবং আপনার পক্ষে সবচেয়ে ভাল অনুসারে কাজ করুন।

আপনার প্রশ্নের উত্তর দেওয়ার জন্য, আপনি আসলে নিয়ন্ত্রণ থেকে নিয়ামকটিকেও ডুপল করতে চান (যাতে আপনি একটি সুইং অ্যাপ্লিকেশন এবং কনসোল অ্যাপ্লিকেশন উভয়ের জন্য একই ব্যবসায়িক নিয়মের যুক্তি ব্যবহার করতে পারেন)। সুইং উদাহরণে আপনি সুইং থেকে JWindowএবং যে কোনও উইজেট থেকে নিয়ামককে ডিকল করতে চান । আমি যেভাবে করতাম (প্রকৃত ফ্রেমওয়ার্কগুলি ব্যবহার করার আগে) তা হল নিয়ামক যে ভিউটি ব্যবহার করেন তার জন্য একটি ইন্টারফেস তৈরি করা:

public interface PersonView {
    void setPersons(Collection<Person> persons);
}

public class PersonController {

    private PersonView view;
    private PersonModel model;

    public PersonController(PersonView view, PersonModel model) {
        this.view = view;
        this.model = model;
    }
    // ... methods to affect the model etc. 
    // such as refreshing and sort:

    public void refresh() {
        this.view.setPersons(model.getAsList());
    }

    public void sortByName(boolean descending) {
       // do your sorting through the model.
       this.view.setPersons(model.getSortedByName());
    }

}

প্রারম্ভকালে এই সমাধানের জন্য আপনাকে নিয়ামককে ভিউতে নিবন্ধিত করতে হবে।

public class PersonWindow extends JWindow implements PersonView {

    PersonController controller;
    Model model;

    // ... Constructor etc.

    public void initialize() {
        this.controller = new PersonController(this, this.model);

        // do all the other swing stuff

        this.controller.refresh();
    }

    public void setPersons(Collection<Person> persons) {
        // TODO: set the JList (in case that's you are using) 
        // to use the given parameter
    }

}

পরিবর্তে আপনার জন্য সমস্ত সেটআপ করার জন্য আইওসি-ধারক তৈরি করা ভাল ধারণা হতে পারে।

যাইহোক, একই নিয়ন্ত্রক ব্যবহার করে আপনি কনসোল-কেবলমাত্র দৃশ্যগুলি প্রয়োগ করতে পারেন:

public class PersonConsole implements PersonView {

    PersonController controller;
    Model model;

    public static void main(String[] args) {
        new PersonConsole().run();
    }

    public void run() {
        this.model = createModel();
        this.controller = new PersonController(this, this.model);

        this.controller.refresh();
    }

    public void setPersons(Collection<Person> persons) {
        // just output the collection to the console

        StringBuffer output = new StringBuffer();
        for(Person p : persons) {
            output.append(String.format("%s%n", p.getName()));
        }

        System.out.println(output);
    }

    public void createModel() {
        // TODO: create this.model
    }

    // this could be expanded with simple console menu with keyboard
    // input and other console specific stuff

}    

মজাদার অংশটি হল কীভাবে ইভেন্ট হ্যান্ডলিং করা যায়। আমি একটি ইন্টারফেস ব্যবহার করে নিজের দৃষ্টিভুক্তি নিয়ন্ত্রণকারীর কাছে নিবন্ধভুক্ত করার মাধ্যমে এটি প্রয়োগ করেছি, এটি পর্যবেক্ষক প্যাটার্নটি ব্যবহার করে করা হয়েছে (যদি আপনি ব্যবহার করছেন N এখানে একটি সাধারণ "দস্তাবেজ পর্যবেক্ষক" এর উদাহরণ দেওয়া আছে, যা নথিটি সংরক্ষণ বা লোড হওয়ার পরে সংকেত দেয়।

public interface DocumentObserver {
    void onDocumentSave(DocModel saved);
    void onDocumentLoad(DocModel loaded);
}

// in your controller you implement register/unregister methods
private List<DocumentObserver> observers;

// register observer in to the controller
public void addObserver(DocumentObserver o) {
    this.observers.add(o);
}

// unregisters observer from the controller
public void removeObserver(DocumentObserver o) {
    this.observers.remove(o);
}

public saveDoc() {
    DocModel model = model.save();
    for (DocumentObserver o : observers) {
        o.onDocumentSave(model);
    }
}

public loadDoc(String path) {
    DocModel model = model.load(path);
    for (DocumentObserver o : observers) {
        o.onDocumentLoad(model);
    }        
}

এইভাবে, দস্তাবেজ আপডেটগুলিতে সাবস্ক্রাইব হওয়ার কারণে দৃশ্যটি নিজেকে সঠিকভাবে আপডেট করতে পারে। এটি যা করতে হবে তা হ'ল DocumentObserverইন্টারফেসটি প্রয়োগ করা :

public class DocumentWindow extends JWindow 
        implements DocView, DocumentObserver {

    //... all swing stuff

    public void onDocumentSave(DocModel saved) {
        // No-op
    }

    public void onDocumentLoad(DocModel loaded) {
        // do what you need with the loaded model to the
        // swing components, or let the controller do it on
        // the view interface
    }

    // ...

}

আমি আশা করি এই অনুপ্রেরণামূলক উদাহরণগুলি আপনাকে কীভাবে এটি করা যায় সে সম্পর্কে কিছু ধারণা দেয়। তবে আমি আপনাকে দৃ strongly়ভাবে জাভাতে ফ্রেমওয়ার্ক ব্যবহার করার কথা বিবেচনা করার পরামর্শ দিচ্ছি যা আপনার জন্য বেশিরভাগ কাজ করে, অন্যথায় আপনি প্রচুর বয়লারপ্লেট কোড লিখে শেষ করতে পারেন যা লিখতে অনেক সময় নেয় takes এখানে বেশ কয়েকটি রিচ ক্লায়েন্ট প্ল্যাটফর্ম (আরসিপি) রয়েছে যা আপনি সম্ভবত ব্যবহার করতে পারেন এমন কিছু প্রাথমিক কার্যকারিতা বাস্তবায়িত করতে পারে যেমন অ্যাপ্লিকেশন-বিস্তৃত ডকুমেন্ট হ্যান্ডলিং এবং প্রচুর বেসিক ইভেন্ট হ্যান্ডলিং।

আমি আমার মাথা থেকে চিন্তা করতে পারি এমন একটি দম্পতি রয়েছে: গ্রহন এবং নেটবিয়ান আরসিপি'র।

আপনার এখনও নিজের জন্য কন্ট্রোলার এবং মডেল বিকাশ করতে হবে তবে সে কারণেই আপনি একটি ওআরএম ব্যবহার করেন। উদাহরণ হাইবারনেট হবে

আইওসি পাত্রে সমস্ত শীতল, তবে এর জন্য ফ্রেমওয়ার্কও রয়েছে। যেমন স্প্রিং (যা অন্যান্য জিনিসগুলির মধ্যে ডেটা হ্যান্ডলিংও করে)।


এত দীর্ঘ প্রতিক্রিয়া লেখার জন্য সময় দেওয়ার জন্য ধন্যবাদ। বেশিরভাগ সময় আমার মাথার উপরে এই মুহুর্তে, তবে আমি নিশ্চিত উইকিপিডিয়া সাহায্য করবে help আমি Eclipse এবং নেটবিন উভয়ই ব্যবহার করছি এবং উত্তরগুলির দিকে ঝুঁকছি। আমি কীভাবে কন্ট্রোলারকে সেখানে দৃশ্য থেকে আলাদা করতে পারি তা নিশ্চিত নই তবে শীর্ষে থাকা আপনার প্রাক-কাঠামোর উদাহরণটি সহায়তা করে।
চ্যাপ

0

আমার এই বিষয়টি গ্রহণ করা কখনও কখনও আমাদের আপোস করা প্রয়োজন

আপনি যেমনটি বলেছেন, এটি দুর্দান্ত হবে যদি আমরা এর জন্য সুস্পষ্ট অবকাঠামোগত পর্যবেক্ষণ করা অবজেক্টটি না রেখে স্পষ্টভাবে পরিবর্তন বিজ্ঞপ্তি প্রচার করতে পারি। জাভা, সি #, সি ++ এর মতো সাধারণ অপরিহার্য ভাষার জন্য তাদের রানটাইম আর্কিটেকচার এখনকার মতো খুব হালকা। তার অর্থ আমার অর্থ এটি এই মুহুর্তে ভাষা নির্দিষ্টকরণের অংশ নয়।

আপনার বিশেষ ক্ষেত্রে, আমি মনে করি না যে INNFIFPropertyChanged (যেমন সি #) এর মতো কিছু জেনেরিক ইন্টারফেসটি সংজ্ঞায়িত / ব্যবহার করা ঠিক খারাপ জিনিস , যেহেতু এটি যেভাবেই কোনও ভিউতে স্বয়ংক্রিয়ভাবে মিলিত হয় না - এটি কেবল বলে যে যদি আমি পরিবর্তন করি, আমি আপনাকে বলব

আবারও, আমি সম্মত হই যে এটি দুর্দান্ত হবে যদি আমাদের নিজেরাই পরিবর্তনের বিজ্ঞপ্তিটি সংজ্ঞায়িত না করতে হয় তবে আবার যদি এটি সমস্ত শ্রেণীর জন্য অন্তর্নিহিত ছিল তবে এটি ওভারহেড বহন করবে।


আরো আমি এটা সম্পর্কে চিন্তা, আমি তুমি ডান বুঝতে পারছি - মডেল বস্তুর হয়েছে থেকে জড়িত করা হবে কিছু গুই করে একটি পরিবর্তন ঘটেছে করতে ঘোষণা সূচনা মধ্যে ব্যাপ্তি; অন্যথায় জিইউআইকে পরিবর্তনগুলি আবিষ্কার করতে মডেলটি পোল করতে হবে - এবং এটি খারাপ।
চ্যাপ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.