কোনও অবজেক্টের মডেল পরিবর্তনের প্রচারের প্যাটার্নস ..?


22

এখানে একটি সাধারণ দৃশ্য যা আমার সাথে মোকাবিলা করতে সর্বদা হতাশাবোধ করে।

আমার প্যারেন্ট অবজেক্টের সাথে একটি অবজেক্ট মডেল রয়েছে। পিতামাতার মধ্যে কিছু শিশু অবজেক্ট থাকে। এটার মতো কিছু.

public class Zoo
{
    public List<Animal> Animals { get; set; }
    public bool IsDirty { get; set; }
}

প্রতিটি শিশু অবজেক্টের বিভিন্ন ডেটা এবং পদ্ধতি রয়েছে

public class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public void MakeMess()
    {
        ...
    }
}

যখন শিশু পরিবর্তন হয়, এক্ষেত্রে যখন মেকমেস পদ্ধতিটি ডাকা হয় তখন পিতামাতার কিছু মান আপডেট করা দরকার। ধরা যাক যখন অ্যানিম্যালিজের একটি নির্দিষ্ট দোরগোড়ায় কোনও গোলমাল শুরু হয়, তখন চিড়িয়াখানার ইসডার্টি পতাকা সেট করা দরকার।

এই দৃশ্যটি পরিচালনা করার কয়েকটি উপায় রয়েছে (যা আমি জানি)।

1) প্রতিটি প্রাণীর পরিবর্তনের সাথে যোগাযোগের জন্য পিতামাতার চিড়িয়াখানা উল্লেখ থাকতে পারে।

public class Animal
{
    public Zoo Parent { get; set; }
    ...

    public void MakeMess()
    {
        Parent.OnAnimalMadeMess();
    }
}

এটি সবচেয়ে খারাপ বিকল্প হিসাবে অনুভব করে যেহেতু এটি প্রাণীটিকে তার প্যারেন্ট অবজেক্টের সাথে সংযুক্ত করে। আমি যদি এমন একটি প্রাণী চাই যা ঘরে থাকে?

2) আরেকটি বিকল্প, আপনি যদি এমন ভাষা ব্যবহার করেন যা ইভেন্টগুলিকে সমর্থন করে (সি # এর মতো) তবে ইভেন্টগুলি পরিবর্তনের জন্য পিতামাতার সদস্যতা নেওয়া।

public class Animal
{
    public event OnMakeMessDelegate OnMakeMess;

    public void MakeMess()
    {
        OnMakeMess();
    }
}

public class Zoo
{
    ...

    public void SubscribeToChanges()
    {
        foreach (var animal in Animals)
        {
            animal.OnMakeMess += new OnMakeMessDelegate(OnMakeMessHandler);
        }
    }

    public void OnMakeMessHandler(object sender, EventArgs e)
    {
        ...
    }
}

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

3) অন্য বিকল্পটি হ'ল লজিককে পিতামাতার কাছে নিয়ে যাওয়া।

public class Zoo
{
    public void AnimalMakesMess(Animal animal)
    {
        ...
    }
}

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

public class House
{
    // Now I have to duplicate this logic
    public void AnimalMakesMess(Animal animal)
    {
        ...
    }
}

এই পরিস্থিতিগুলি মোকাবেলার জন্য আমি এখনও ভাল কৌশল খুঁজে পাইনি। আর কি পাওয়া যায়? এটিকে কীভাবে সহজ করা যায়?


আপনি # 1 খারাপ হওয়ার বিষয়ে ঠিক বলেছেন, এবং আমি # 2 নিয়েও আগ্রহী নই; সাধারণত আপনি পার্শ্ব প্রতিক্রিয়া এড়াতে চান এবং পরিবর্তে আপনি সেগুলি বাড়িয়ে তুলছেন। বিকল্প # 3 সম্পর্কিত, আপনি কেন অ্যানিম্যালমেকমেসকে একটি স্থির পদ্ধতিতে কল করতে পারবেন না যা সমস্ত শ্রেণি কল করতে পারে?
ডোভাল

4
# 1 অগত্যা খারাপ হয় না যদি আপনি সেই নির্দিষ্ট অভিভাবক শ্রেণীর পরিবর্তে কোনও ইন্টারফেসের (আইএনিমালঅবার্সার) মাধ্যমে যোগাযোগ করেন।
coredump

উত্তর:


11

আমি কয়েকবার এটি মোকাবেলা করতে হয়েছিল। আমি প্রথমবারের মতো বিকল্প 2 (ইভেন্ট) ব্যবহার করেছি এবং আপনি যেমন বলেছিলেন এটি সত্যিই জটিল হয়ে উঠেছে। আপনি যদি সেই রাস্তাটিতে যান তবে আমি আপনাকে পরামর্শ দিচ্ছি যে ঘটনাগুলি সঠিকভাবে সম্পন্ন হয়েছে এবং আপনি ঝুঁকির উল্লেখগুলি ছাড়ছেন না তা নিশ্চিত করার জন্য আপনার খুব সূক্ষ্ম ইউনিট পরীক্ষার প্রয়োজন, অন্যথায় এটি ডিবাগ করা সত্যিই বড় ব্যথা।

দ্বিতীয়বার, আমি সবেমাত্র পিতামাতার সম্পত্তি বাচ্চাদের একটি ক্রিয়াকলাপ হিসাবে প্রয়োগ করেছি, তাই Dirtyপ্রতিটি প্রাণীর উপর একটি সম্পত্তি রাখুন এবং Animal.IsDirtyফিরে আসুন this.Animals.Any(x => x.IsDirty)। মডেল ছিল। মডেলের উপরে একজন কন্ট্রোলার ছিল এবং কন্ট্রোলারের কাজটি জানা ছিল যে আমি মডেলটি পরিবর্তন করার পরে (মডেলটির সমস্ত ক্রিয়াকলাপ নিয়ন্ত্রণকারীর মধ্য দিয়ে গেছে তাই এটি জানত যে কোনও কিছু বদলেছে), তখন এটি জানত যে এটি নির্দিষ্ট কিছুকে কল করতে হয়েছিল মূল্যায়ন ফাংশন, যেমনটি আবার নোংরা ছিল ZooMaintenanceকিনা তা পরীক্ষা করতে বিভাগটিকে ট্রিগার Zooকরা। বিকল্পভাবে আমি ZooMaintenanceকিছু সময় নির্ধারিত সময় (প্রতি 100 এমএস, 1 সেকেন্ড, 2 মিনিট, 24 ঘন্টা, যা যা প্রয়োজন ঠিক না হওয়া অবধি) পরীক্ষা বন্ধ রাখতে পারতাম could

আমি দেখতে পেয়েছি যে পরবর্তীকৃতটি বজায় রাখা খুব সহজ হয়েছে এবং আমার কর্মক্ষমতা সমস্যার ভয়টি কখনই বাস্তবায়িত হয়নি।

সম্পাদন করা

এটির সাথে মোকাবিলা করার আরেকটি উপায় হ'ল একটি বার্তা বাসের ধরণ। Controllerআমার উদাহরণে একটি পছন্দ ব্যবহার করার পরিবর্তে , আপনি একটি IMessageBusপরিষেবা দিয়ে প্রতিটি বস্তুকে ইনজেক্ট করেন । Animalবর্গ তারপর "মেস তৈরি" মত একটি বার্তা প্রকাশ করতে পারবেন, এবং আপনার Zooশ্রেণী "মেস তৈরি" বার্তা সদস্যতা নিতে পারেন। বার্তা বাস পরিষেবা Zooকোনও প্রাণী যখন এই বার্তাগুলির মধ্যে একটি প্রকাশ করে তা জানাতে যত্ন নেবে এবং এটি তার IsDirtyসম্পত্তিটির পুনরায় মূল্যায়ন করতে পারে ।

এটির সুবিধাটি রয়েছে যে Animalsআর কোনও Zooরেফারেন্সের প্রয়োজন নেই , এবং Zooপ্রতিটি একক থেকে ইভেন্টগুলি সাবস্ক্রাইব এবং সদস্যতা সম্পর্কে চিন্তা করার দরকার নেই Animal। পেনাল্টিটি হ'ল এই Zooবার্তায় সাবস্ক্রাইব করা সমস্ত শ্রেণিকে তাদের সম্পত্তিগুলির পুনরায় মূল্যায়ন করতে হবে, যদিও এটি তার প্রাণীর মধ্যে একটিও ছিল না। এটি বড় ব্যাপার হতে পারে বা নাও হতে পারে। যদি কেবল একটি বা দুটি Zooউদাহরণ থাকে তবে সম্ভবত এটি ভাল।

সম্পাদনা 2

অপশনটির সরলতাটি ডিসকাউন্ট করবেন না। কোডটি পুনর্বিবেচনা করা যে কোনও ব্যক্তির এটি বুঝতে খুব বেশি সমস্যা হবে না। ক্লাসটির দিকে তাকিয়ে থাকা কারও কাছে এটি স্পষ্ট হবে Animalযে যখন MakeMessবলা হয় যে এটি বার্তাটি প্রচার করে Zooএবং এটি Zooক্লাসের কাছে স্পষ্ট হবে যেখানে সেখান থেকে বার্তা এসেছে। মনে রাখবেন যে অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ে একটি পদ্ধতি কলকে "বার্তা" বলা হত। প্রকৃতপক্ষে, কেবল বিকল্পটি 1 থেকে বিরতিতে এটি কেবলমাত্র তখনই বোঝা যায় যদি মেস Zooগোল হয়ে যায় তবে কেবলমাত্র তাকে অবহিত করতে হবে Animal। যদি আরও অবজেক্ট থাকত যেগুলিকে অবহিত করার দরকার পড়ে, তবে আমি সম্ভবত একটি বার্তা বাস বা একটি নিয়ামকের কাছে চলে যেতে চাই।


5

আমি একটি সাধারণ শ্রেণীর চিত্র করেছি যা আপনার ডোমেনটিকে বর্ণনা করে: এখানে চিত্র বর্ণনা লিখুন

প্রত্যেকের Animal একটি Habitat এটি গণ্ডগোল করে।

Habitatগ্রাহ্য না করে কি বা কিভাবে অনেক প্রাণী এটা আছে (যদি না তা মৌলিকভাবে আপনার নকশা যা এই ক্ষেত্রে আপনি তা না হয় বর্ণনা অংশ)।

তবে Animalযত্নশীল, কারণ এটি প্রতিটি ক্ষেত্রে আলাদাভাবে আচরণ করবে Habitat

এই চিত্রটি কৌশল নকশা প্যাটার্নের ইউএমএল চিত্রের মতো , তবে আমরা এটি আলাদাভাবে ব্যবহার করব।

এখানে জাভাতে কয়েকটি কোডের উদাহরণ দেওয়া আছে (আমি কোনও সি # নির্দিষ্ট ভুল করতে চাই না)।

অবশ্যই আপনি এই নিজস্ব নকশা, ভাষা এবং প্রয়োজনীয়তাগুলিতে নিজের সামঞ্জস্য করতে পারেন।

এটি কৌশল ইন্টারফেস:

public interface Habitat {
    public void messUp(float magnitude);

    public float getCleanliness();
}

কংক্রিটের উদাহরণ Habitat। অবশ্যই প্রতিটি Habitatসাবক্লাস এই পদ্ধতিগুলি আলাদাভাবে প্রয়োগ করতে পারে।

public class Zoo implements Habitat {
    public float cleanliness = 1;

    public float getCleanliness() {
        return cleanliness;
    }

    public void messUp(float magnitude) {
        cleanliness -= magnitude;
    }
}

অবশ্যই আপনার একাধিক প্রাণী উপশ্রেন থাকতে পারে, যেখানে প্রত্যেকে একে একে আলাদা করে ফেলে:

public class Animel {
    private Habitat habitat;

    public void makeMess() {
        habitat.messUp(.05f);
    }

    public Animel addTo(Habitat habitat) {
        this.habitat = habitat;
        return this;
    }
}

এটি ক্লায়েন্ট শ্রেণি, এটি মূলত ব্যাখ্যা করে যে আপনি কীভাবে এই নকশাটি ব্যবহার করতে পারেন।

public class ZooKeeper {
    public Habitat zoo = new Zoo();

    public ZooKeeper() {
        new Animal()
            .addTo( zoo )
            .makeMess();

        if (zoo.getCleanliness() < 0.5f) {
            System.out.println("The zoo is really messy");
        } else {
            System.out.println("The zoo looks clean");
        }
    }
}

অবশ্যই আপনার আসল অ্যাপ্লিকেশনটিতে আপনি যদি প্রয়োজন হয় তা Habitatজানাতে এবং পরিচালনা করতে Animalপারেন।


3

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

interface MessablePlace
{
  void OnMess(object sender, MessEvent e);
}

class MessEvent
{
  String DetailsOrWhatever;
}

ইন্টারফেস বিকল্পটি আপনার বিকল্প 1 এর মতো প্রায় সরল হওয়ার সুবিধা রয়েছে, তবে আপনি একটি Houseবা তে খুব অনায়াসে প্রাণী রাখতে পারবেন FairlyLand


3
  • বিকল্প 1 আসলে বেশ সোজা is এটি কেবল একটি ব্যাক-রেফারেন্স। তবে এটিকে বলা ইন্টারফেসের সাথে সাধারণকরণ করুন এবং এটিতে Dwellingএকটি MakeMessপদ্ধতি সরবরাহ করুন। যা বৃত্তাকার নির্ভরতা ভঙ্গ করে। তারপরে প্রাণীটি কোনও গোলমাল করলে, এটিও কল dwelling.MakeMess()করে।

আত্মা লেক্স parsimoniae , আমি এই এক সঙ্গে যেতে যদিও আমি সম্ভবত নিচের চেইন সমাধান ব্যবহার করতে চাই, আমাকে বুদ্ধিমান যাচ্ছি। (এটি কেবল একই মডেল যা @ বেঞ্জামিন অ্যালবার্ট পরামর্শ দেয়।)

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

  • এই ধারণাটি আরও দূরে নিয়ে আপনি একটি শৃঙ্খলিত আর্কিটেকচার ব্যবহার করতে পারেন। এটি হ'ল একটি ইন্টারফেস তৈরি করুন Messableএবং প্রতিটি মেসেবল আইটেমের সাথে একটি রেফারেন্স অন্তর্ভুক্ত করুন next। কোনও গণ্ডগোল তৈরি করার পরে, MakeMessপরবর্তী আইটেমটিতে কল করুন।

সুতরাং এখানে চিড়িয়াখানা একটি জগাখিচুড়ি করার সাথে জড়িত, কারণ এটিও অগোছালো হয়ে যায়। আছে:

Zoo implements Messable
House implements Messable
Animal implements Messable
   Messable next

   MakeMess()
       messy = true
       next.MakeMess

সুতরাং এখন আপনার কাছে এমন একটি শৃঙ্খলা রয়েছে যা এই বার্তাটি পেয়ে যায় যে কোনও বিশৃঙ্খলা তৈরি হয়েছে।

  • বিকল্প 2, একটি প্রকাশ / সাবস্ক্রাইব করা মডেল এখানে কাজ করতে পারে তবে সত্যই ভারী ওজন অনুভব করে। অবজেক্ট এবং ধারকটির একটি সুসম্পর্কিত সম্পর্ক রয়েছে, সুতরাং এর থেকে সাধারণ কিছু ব্যবহার করতে কিছুটা ভারী হাতে মনে হচ্ছে।

  • বিকল্প 3: এই বিশেষ ক্ষেত্রে, কল করা Zoo.MakeMess(animal)বা House.MakeMess(animal)আসলে কোনও খারাপ বিকল্প নয়, কারণ একটি বাড়িতে চিড়িয়াখানার চেয়ে অগোছালো হওয়ার জন্য আলাদা আলাদা শব্দার্থ থাকতে পারে।

এমনকি যদি আপনি চেইন রুটে নীচে না যান, তবে মনে হয় এখানে দুটি সমস্যা রয়েছে: 1) সমস্যাটি কোনও বস্তু থেকে তার ধারকটিতে পরিবর্তনের প্রচারের বিষয়ে, 2) আপনি মনে করেন যে আপনি কোনও ইন্টারফেসটি স্পিন করতে চান প্রাণী যেখানে বাস করতে পারে সেখানে বিমূর্ত করার ধারক।

...

আপনার যদি প্রথম-শ্রেণীর ফাংশন থাকে তবে আপনি কোনও ফাংশন (বা ডেলিগেট) অ্যানিমালটিতে কল করতে গেলে কল করতে পারেন। এটি একটি ইন্টারফেসের পরিবর্তে কোনও ফাংশন বাদে চেইন আইডিয়াটির মতো কিছুটা।

public Animal
    Function afterMess

    public MakeMess()
        messy = true
        afterMess()

প্রাণীটি চললে কেবল একটি নতুন প্রতিনিধি নির্ধারণ করুন deleg

  • চূড়ান্ত দিকে নিয়ে যাওয়া, আপনি মেকমেসের পরামর্শের পরে "পরে" দিয়ে এ্যাসপেক্ট ওরিয়েন্টেড প্রোগ্রামিং (এওপি) ব্যবহার করতে পারেন।

2

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

কিছুটা এইরকম :

public interface IAnimal
{
    string Name { get; set; }
    int Age { get; set; }

    void MakeMess();
}

public class Animal : IAnimal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public void MakeMess()
    {
        // makes mess
    }
}

public class ZooAnimals
{
    class AnimalInZoo : IAnimal
    {
        public IAnimal _animal;
        public ZooAnimals _zoo;

        public AnimalInZoo(IAnimal animal, ZooAnimals zoo)
        {
            _animal = animal;
            _zoo = zoo;
        }

        public string Name { get { return _animal.Name; } set { _animal.Name = value; } }
        public int Age { get { return _animal.Age; } set { _animal.Age = value; } }

        public void MakeMess()
        {
            _animal.MakeMess();
            _zoo.IsDirty = true;
        }
    }

    private Collection<AnimalInZoo> animals = new Collection<AnimalInZoo>();

    public IAnimal Add(IAnimal animal)
    {
        if (animal is AnimalInZoo)
        {
            var inZoo = (AnimalInZoo)animal;
            if (inZoo._zoo != this)
            {
                // animal is in a different zoo, what to do ?
                // either move animal to this zoo
                // or throw an exception so caller is forced to remove the animal from previous zoo first
            }
        }

        var anim = new AnimalInZoo(animal, this);
        animals.Add(anim);
        return anim;
    }

    public IAnimal Remove(IAnimal animal)
    {
        if (!(animal is AnimalInZoo))
        {
            // animal is not in zoo, throw an exception?
        }
        var inZoo = (AnimalInZoo)animal;
        if (inZoo._zoo != this)
        {
            // animal is in a different zoo, throw an exception?
        }

        animals.Remove(inZoo);
        return inZoo._animal;
    }

    public bool IsDirty { get; set; }
}

বাস্তবে কিছু ওআরএম সত্তাগুলিতে তাদের পরিবর্তন ট্র্যাক করে। তারা সত্তার চারপাশে মোড়ক তৈরি করে এবং আপনাকে সেগুলির সাথে কাজ করে। এই মোড়কগুলি সাধারণত প্রতিবিম্ব এবং গতিশীল কোড জেনারেশন ব্যবহার করে তৈরি করা হয়।


1

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

একটি বিকল্প পদ্ধতির (যা আসলে তিনটি বিকল্পের যে কোনওটির সাথে ব্যবহার করা যেতে পারে) কনটেন্ট ব্যবহার করা। এমন একটি এ্যানিমাল কনটেনার তৈরি করুন (বা এমনকি এটি একটি সংগ্রহ করুন) যা ঘরে বা চিড়িয়াখানায় বা অন্য যে কোনও কিছুতে থাকতে পারে। এটি প্রাণীদের সাথে সম্পর্কিত ট্র্যাকিং কার্যকারিতা সরবরাহ করে তবে উত্তরাধিকার সংক্রান্ত সমস্যাগুলি এড়িয়ে যায় কারণ এটি যে কোনও বস্তুর প্রয়োজন যা এতে অন্তর্ভুক্ত করা যেতে পারে।


0

আপনি একটি প্রাথমিক ব্যর্থতা দিয়ে শুরু: শিশু অবজেক্টগুলি তাদের পিতামাতার সম্পর্কে জানা উচিত নয়।

স্ট্রিংগুলি কি তারা জানেন যে তারা একটি তালিকায় রয়েছে? না। তারিখগুলি কি জানা যায় যে তারা একটি ক্যালেন্ডারে রয়েছে? না।

সর্বোত্তম বিকল্পটি হ'ল আপনার নকশাটি পরিবর্তন করা যাতে এই ধরণের দৃশ্যের অস্তিত্ব না থাকে।

এর পরে, নিয়ন্ত্রণের বিপরীতে বিবেচনা করুন consider পরিবর্তে MakeMessউপর Animalএকটি পার্শ্ব প্রতিক্রিয়া বা ঘটনা সঙ্গে, পাস Zooপদ্ধতি মধ্যে। বিকল্প 1 টি যদি আপনার আক্রমণকারীকে সুরক্ষিত করা দরকার যা Animalসর্বদা কোথাও বেঁচে থাকার প্রয়োজন। এটি কোনও পিতা-মাতার নয়, তবে সমবয়সী সমিতি।

মাঝেমধ্যে 2 এবং 3 ঠিক হয়ে যায়, তবে অনুসরণ করার মূল স্থাপত্য নীতিটি হ'ল বাচ্চারা তাদের পিতামাতার সম্পর্কে জানে না।


আমি সন্দেহ করি এটি কোনও তালিকার স্ট্রিংয়ের চেয়ে ফর্মের একটি জমা বোতামের মতো।
এসভিডজেন

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