পর্যবেক্ষকরা একে অপরের থেকে স্বতন্ত্র না থাকলে পর্যবেক্ষক প্যাটার্ন কি উপযুক্ত?


9

আমার একটি রয়েছে class Carযার 2 টি বৈশিষ্ট্য রয়েছে: int priceএবং boolean inStock। এটি একটি ঝুলিতে Listএর abstract class State(খালি বর্গ)। এখানে 2 টি রাজ্য রয়েছে যা গাড়িতে প্রয়োগ করা যেতে পারে এবং প্রত্যেকটির নিজস্ব শ্রেণি দ্বারা প্রতিনিধিত্ব করা হয়: class Upgrade extends Stateএবং class Shipping extends State

Car2 টি রাজ্যের প্রতিটি সংখ্যক ধারণ করতে পারে। রাজ্যগুলির নিম্নলিখিত নিয়ম রয়েছে:

  • Upgrade: 1নিজের পরে গাড়িতে প্রয়োগ করা প্রতিটি রাজ্যের জন্য দাম যুক্ত করে।
  • Shipping: তালিকায় যদি কমপক্ষে 1 টি Shippingরাষ্ট্র থাকে তবে inStockসেট করা আছে false

উদাহরণস্বরূপ, price = 1এবং দিয়ে শুরু inStock = true:

add Shipping s1    --> price: 1, inStock: false
add Upgrade g1     --> price: 1, inStock: false
add Shipping s2    --> price: 2, inStock: false
add Shipping s3    --> price: 3, inStock: false
remove Shipping s2 --> price: 2, inStock: false
remove Upgrade g1  --> price: 1, inStock: false
remove Shipping s1 --> price: 1, inStock: false
remove Shipping s3 --> price: 1, inStock: true

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

abstract class State implements Observer {

    public abstract void update();
}

class Car extends Observable {

    List<State> states = new ArrayList<>();
    int price = 100;
    boolean inStock = true;

    void addState(State state) {

        if (states.add(state)) {
            addObserver(state);
            setChanged();
            notifyObservers();
        }
    }

    void removeState(State state) {

        if (states.remove(state)) {
            deleteObserver(state);
            setChanged();
            notifyObservers();
        }
    }
}

class Upgrade extends State {

    @Override
    public void update(Observable o, Object arg) {

        Car c = (Car) o;
        int bonus = c.states.size() - c.states.indexOf(this) - 1;
        c.price += bonus;
        System.out.println(c.inStock + " " + c.price);
    }
}

class Shipping extends State {

    @Override
    public void update(Observable o, Object arg) {

        Car c = (Car) o;
        c.inStock = false;
        System.out.println(c.inStock + " " + c.price);
    }
}

স্পষ্টতই, এটি কাজ করে না। যখন একটি Shippingসরানো হয়, কোনও কিছুতে অন্য কোনও রাষ্ট্রের inStockমিথ্যা হিসাবে সেট করা আছে কিনা তা পরীক্ষা করে দেখতে হয় , সুতরাং অপসারণ Shippingকেবল তা করতে পারে না inStock = true। প্রতিটি কল এ Upgradeবৃদ্ধি price। আমি তখন ডিফল্ট মানগুলির জন্য ধ্রুবকগুলি যুক্ত করেছিলাম এবং সেগুলির উপর ভিত্তি করে পুনরায় গণনার চেষ্টা করেছি।

আমি কোনওভাবেই কোনও নিদর্শন চাপানোর চেষ্টা করছি না, আমি কেবল উপরের প্রয়োজনীয়তার জন্য একটি সমাধান খুঁজতে চাইছি। নোট করুন যে অনুশীলনে Carঅনেক সম্পত্তি রয়েছে এবং এমন অনেকগুলি রাজ্য রয়েছে যা এই পদ্ধতিতে প্রয়োগ করা যেতে পারে। আমি এটি করার কয়েকটি উপায় সম্পর্কে ভেবেছিলাম:

  1. যেহেতু প্রতিটি পর্যবেক্ষক প্রাপ্ত হন Car, এটি বর্তমানে নিবন্ধিত অন্যান্য সমস্ত পর্যবেক্ষকের দিকে নজর রাখতে পারে এবং তার ভিত্তিতে পরিবর্তন আনতে পারে। আমি জানি না যে এটি পর্যবেক্ষককে এভাবে জড়িয়ে ফেলতে স্মার্ট কিনা।
  2. যখন কোনও পর্যবেক্ষক যুক্ত করা হয় বা এতে সরানো হয় Car, তখন পুনরায় গণনা হবে। যাইহোক, এই পুনরায় গণনাটি কেবলমাত্র যুক্ত করা / অপসারণের ক্ষেত্রে নির্বিশেষে সকল পর্যবেক্ষকদের জন্যই করতে হবে।
  3. একটি বাহ্যিক "ম্যানেজার" ক্লাস করুন যা অ্যাডকে কল করবে এবং পদ্ধতিগুলি মুছে ফেলবে এবং পুনঃ গণনা করবে।

বর্ণিত আচরণ বাস্তবায়নের জন্য একটি ভাল ডিজাইনের ধরণ কী এবং এটি কীভাবে কাজ করবে?


1
স্টেটকে তার নিজস্ব শ্রেণিতে বিমূর্ত করার বিষয়টি হ'ল লজিককে আলাদা করা যা কোড একে অপরের সাথে একে অপরের সাথে যোগাযোগ করে না। তবে আপনার ব্যবসায়ের যুক্তি নির্দেশ করে যে তাদের লজিক যুক্ত হয়েছে, এবং সেইজন্য আপনাকে লিঙ্কটিতে ফিরে যেতে হবে, ফলস্বরূপ এই Godশ্বরের ভয়ঙ্কর জগাখিচুড়ি হতে হবে। এটি এখানে যে পর্যবেক্ষক প্যাটার্নই সমস্যা তা নয়, আপনি রাষ্ট্রের সাথে প্রয়োগ করছেন এমন ভূমিকা রীতি।
আরটিস

আপনি যদি হাত দ্বারা এটি করতেন তবে আপনি কীভাবে সমস্যার সমাধান করবেন?
জেমস ইয়ংম্যান

@ জামেস ইয়ংম্যান আমি আমার ৩ য় বিকল্পটি ব্যবহার করে শেষ করেছি - একজন বাহ্যিক পরিচালক manager এই মামলার জন্য আপনার কাগজে লেখার নিয়মগুলি সহজ, তবে ভাষা প্রয়োগের জন্য আপনাকে যে বিকল্পগুলি দেয় সেগুলি এই ক্ষেত্রে সীমাবদ্ধ । সুতরাং একটি নকশা প্যাটার্ন জন্য প্রয়োজন। "আপনি কীভাবে এটি হাত দিয়ে করবেন" সম্পর্কে চিন্তাভাবনাগুলি একটি স্পষ্ট নিয়ম প্রয়োগের চেয়ে অ্যালগরিদমের পক্ষে বেশি কাজ করে।
ব্যবহারকারী1803551

@ ব্যবহারকারী1803551 আপনি ভাল পছন্দ করেছেন।
তুলাইনস কর্ডোভা

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

উত্তর:


1

আপনি যদি সিস্টেমটিকে অন্যভাবে ফ্যাক্ট করেন তবে পর্যবেক্ষকরা দুর্দান্ত কাজ করবে। রাষ্ট্রগুলিকে পর্যবেক্ষক হিসাবে পরিণত করার পরিবর্তে, আপনি "রাষ্ট্রীয় পরিবর্তন পর্যবেক্ষক" হিসাবে 2 টি নতুন শ্রেণি তৈরি করতে পারেন: একজন পর্যবেক্ষক "দাম" আপডেট করবেন, অন্য একটি "ইনস্টক" আপডেট করবেন। ইনস্টক বা তদ্বিপরীতের উপর নির্ভর করে দামের জন্য যদি আপনার কাছে নিয়ম না থাকে তবে তারা স্বাধীন হবে, অর্থাত্ রাষ্ট্রের পরিবর্তনগুলি দেখে সমস্ত কিছু গণনা করা যেতে পারে। এই কৌশলটিকে "ইভেন্ট সোর্সিং" বলা হয় (উদাহরণস্বরূপ - https://ookami86.github.io/event-sourcing-in-pੈਕਟ/ )। এটি প্রোগ্রামিংয়ের একটি প্যাটার্ন যার কয়েকটি উল্লেখযোগ্য অ্যাপ্লিকেশন রয়েছে।

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


0

আমি বাহ্যিক পরিচালক ব্যবহার করে 3 বিকল্পটি দিয়ে শেষ করেছি। পরিচালকগুলি Stateএর থেকে যোগ করা এবং অপসারণ Carএবং এই পরিবর্তনগুলি যখন ঘটে তখন পর্যবেক্ষকদের অবহিত করার জন্য দায়ী responsible

এখানে আমি কোডটি সংশোধন করেছি। আমি জেডিকে Observable/ কে সরিয়ে দিয়েছি Observerকারণ আমি আমার নিজস্ব বাস্তবায়ন করছি।

প্রতিটি এটি প্রয়োগ করা Stateএকটি রেফারেন্স রাখে Car

abstract class State {

    Car car;

    State(Card car) { this.car = car; }

    public abstract void update();
}

class Upgrade extends State {

    @Override
    public void update() {

        int bonus = car.states.size() - car.states.indexOf(this) - 1;
        car.price += bonus;
        System.out.println(car.inStock + " " + car.price);
    }
}

class Shipping extends State {

    @Override
    public void update() {

        car.inStock = false;
        System.out.println(car.inStock + " " + car.price);
    }
}

Carশুধুমাত্র তার অবস্থা ধরে রাখে (বিভ্রান্তি এড়াতে: বৈশিষ্ট্যগুলি) এবং এর যোগ এবং অপসারণ পরিচালনা করে না State:

class Car extends Observable {

    List<State> states = new ArrayList<>();
    int price = 100;
    boolean inStock = true;
}

এই ম্যানেজার। এটি এর (পর্যবেক্ষক) Carপরিচালনার কাজকে State(পর্যবেক্ষণযোগ্য) ছাড়িয়ে গেছে।

class StatesManager {

    public void addState(Card car, State state) {

        car.states.add(state);
        for (State state : car. states)
            state.update;
    }

    public void removeState(Card car, State state) {

        car.states.remove(state);
        for (State state : car. states)
            state.update;
    }
}

কিছু বিষয় মনে রাখতে হবে:

  • সমস্ত পর্যবেক্ষক প্রতিটি পরিবর্তন সম্পর্কে অবহিত করা হয়। আরও চতুর ইভেন্ট বিতরণ প্রকল্পটি পর্যবেক্ষকদের updateপদ্ধতিতে বিনা ছাড়ানো কলগুলি দূর করতে পারে ।
  • পর্যবেক্ষকরা বিভিন্ন অনুষ্ঠানে আরও "আপডেট" -র মতো পদ্ধতি প্রকাশ করতে চাইতে পারেন। যেমন একটি উদাহরণ হিসাবে, তারা বর্তমান updateপদ্ধতিটি বিভক্ত করতে পারে updateOnAddএবং updateOnRemoveযদি তারা কেবলমাত্র এই পরিবর্তনের একটিতে আগ্রহী হয়। তারপরে addStateএবং removeStateপদ্ধতিগুলি সেই অনুযায়ী আপডেট করা হবে। পূর্ববর্তী পয়েন্টের পাশাপাশি এই পদ্ধতির একটি দৃ ex়, এক্সটেনসিবল এবং নমনীয় প্রক্রিয়া হিসাবে শেষ হতে পারে।
  • এসগুলিকে যুক্ত করতে এবং সরানোর জন্য কী নির্দেশনা দেয় এবং আমি Stateযখন তা করি তা প্রশ্নের জন্য গুরুত্বপূর্ণ নয় বলে আমি নির্দিষ্ট করেছিলাম না । তবে, এই উত্তরের ক্ষেত্রে, নিম্নলিখিত বিষয়গুলি বিবেচনা করতে হবে। যেহেতু Stateএখন Carম্যানেজারের পদ্ধতিটি কল করার আগে অবশ্যই এটির (কোনও খালি নির্মাণকারীর উদ্ভাসিত নয়) তৈরি করা উচিত , addStateএবং removeStateপদ্ধতিগুলি গ্রহণ করার প্রয়োজন নেই Carএবং এটি কেবল এটি থেকে পড়তে পারে state.car
  • পর্যবেক্ষকরা ডিফল্টরূপে পর্যবেক্ষণযোগ্যতে নিবন্ধকরণের জন্য অবহিত হন। একটি আলাদা অর্ডার নির্দিষ্ট করা যেতে পারে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.