আইডি দ্বারা কী বস্তু বনাম অবজেক্টের অ্যারে হিসাবে বর্ণনা করুন


97

রাজ্য আকৃতি ডিজাইনিংয়ের অধ্যায়ে , ডক্সগুলি আপনার রাজ্যটিকে আইডি দ্বারা কীডযুক্ত কোনও বস্তুর মধ্যে রাখার পরামর্শ দেয়:

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

তারা রাষ্ট্র যেতে

অ্যাপ্লিকেশনটির অবস্থাটিকে একটি ডাটাবেস হিসাবে ভাবেন।

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

সুতরাং আমি এটি হিসাবে চিন্তা ছিল

[{
    id: '1',
    name: 'View',
    open: false,
    options: ['10', '11', '12', '13'],
    selectedOption: ['10'],
    parent: null,
  },
  {
    id: '10',
    name: 'Time & Fees',
    open: false,
    options: ['20', '21', '22', '23', '24'],
    selectedOption: null,
    parent: '1',
  }]

তবে দস্তাবেজগুলি আরও পছন্দ মতো একটি বিন্যাসের পরামর্শ দেয়

{
   1: { 
    name: 'View',
    open: false,
    options: ['10', '11', '12', '13'],
    selectedOption: ['10'],
    parent: null,
  },
  10: {
    name: 'Time & Fees',
    open: false,
    options: ['20', '21', '22', '23', '24'],
    selectedOption: null,
    parent: '1',
  }
}

তাত্ত্বিকভাবে, যতক্ষণ না তথ্য সিরিয়ালযোগ্য (তত্ক্ষণাত "রাজ্য" শিরোনামে) থাকে ততক্ষণ তা বিবেচনা করা উচিত নয় ।

সুতরাং আমি আমার অ্যারেটারটি লেখার আগে পর্যন্ত আমি আনন্দের সাথে অ্যারে-অবজেক্টগুলির সাথে চলেছি।

অবজেক্ট-কীড-বাই-আইডি পদ্ধতির সাথে (এবং স্প্রেড সিনট্যাক্সের উদার ব্যবহার), OPEN_FILTERরিডুসারটির অংশটি হয়ে যায়

switch (action.type) {
  case OPEN_FILTER: {
    return { ...state, { ...state[action.id], open: true } }
  }

অ্যারে-অফ-অবজেক্টের পদ্ধতির সাথে, এটি আরও ভার্বোজ (এবং সহায়ক ফাংশন নির্ভর করে)

switch (action.type) {
   case OPEN_FILTER: {
      // relies on getFilterById helper function
      const filter = getFilterById(state, action.id);
      const index = state.indexOf(filter);
      return state
        .slice(0, index)
        .concat([{ ...filter, open: true }])
        .concat(state.slice(index + 1));
    }
    ...

সুতরাং আমার প্রশ্নগুলি তিনগুণ:

1) রিডিউসারটির সরলতা কি অবজেক্ট-কীড-বাই-আইডি পদ্ধতির সাথে যাওয়ার প্রেরণা? রাষ্ট্রীয় আকারের অন্যান্য সুবিধা কি আছে?

এবং

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

এবং

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


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

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

আপনি কীভাবে অবজেক্ট দিয়ে তৈরি কোনও বস্তু বাছাই করতে পারেন? এটা অসম্ভব বলে মনে হচ্ছে।
ডেভিড ভিলহুবার

@ ডেভিডভিয়েলহুবার আপনার অর্থ লডাশের মতো কিছু ব্যবহার করা ছাড়াও sort_by? const sorted = _.sortBy(collection, 'attribute');
নিককক্সডটমে

হ্যাঁ. বর্তমানে আমরা সেই বস্তুগুলিকে একটি
অমিত গণনার

উত্তর:


47

প্রশ্নোত্তর: রিডিউসারটির সরলতা হ'ল সঠিক প্রবেশাধিকার খুঁজে বের করার জন্য অ্যারের মাধ্যমে অনুসন্ধান না করার ফলস্বরূপ। অ্যারের মাধ্যমে অনুসন্ধান না করে সুবিধা হয়। নির্বাচক এবং অন্যান্য ডেটা অ্যাক্সেসরগুলি এবং প্রায়শই এই আইটেমগুলিতে অ্যাক্সেস করতে পারে id। প্রতিটি অ্যাক্সেসের জন্য অ্যারের মাধ্যমে অনুসন্ধান করা একটি পারফরম্যান্স ইস্যুতে পরিণত হয়। যখন আপনার অ্যারেগুলি বড় হয়, তখন পারফরম্যান্সের সমস্যাটি খাড়া হয়ে যায়। এছাড়াও, আপনার অ্যাপ্লিকেশনটি আরও জটিল হয়ে ওঠার সাথে সাথে আরও অনেক জায়গায় ডেটা দেখানো এবং ফিল্টার করা, সমস্যাটি ততই আরও খারাপ হয়। সংমিশ্রণ ক্ষতিকারক হতে পারে। আইটেম দ্বারা অ্যাক্সেস দ্বারা id, অ্যাক্সেস সময় থেকে পরিবর্তিত O(n)হয় O(1), যা বড় n(এখানে অ্যারে আইটেম) জন্য একটি বিশাল পার্থক্য করে।

Q2: আপনি normalizrAPI থেকে স্টোর থেকে রূপান্তর করতে আপনাকে সহায়তা করতে পারেন । নরমালাইজার ভি 3 .১.০ হিসাবে আপনি অন্যভাবে যেতে অস্বীকৃতি ব্যবহার করতে পারেন। এটি বলেছিল যে অ্যাপ্লিকেশনগুলি প্রায়শই ডেটা উত্পাদনকারীদের চেয়ে বেশি ভোক্তা হয় এবং যেমন সংরক্ষণের রূপান্তর সাধারণত আরও ঘন ঘন ঘটে।

Q3: আপনি অ্যারে ব্যবহার করে যে বিষয়গুলি চালাবেন সেগুলি স্টোরেজ কনভেনশন এবং / বা অসম্পূর্ণতাগুলি নয়, তবে আরও কার্য সম্পাদনের সমস্যা performance


নরমালাইজারটি আবার এমন জিনিস যা আমরা ব্যাকএন্ডে ডিএফগুলি পরিবর্তন করে নিলে অবশ্যই ব্যথা তৈরি করতে পারে। সুতরাং এটি প্রতিবারই আপ টু ডেট রাখতে হবে
কুণাল নাভতে

12

অ্যাপ্লিকেশনটির অবস্থাটিকে একটি ডাটাবেস হিসাবে ভাবেন।

এটাই মূল ধারণা।

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

2) API এর সাথে সংযোগটি আপনার স্টোরেজ এবং হ্রাসকারীদের আর্কিটেকচারকে প্রভাবিত করবে না, এ কারণেই উদ্বেগের বিচ্ছিন্নতা বজায় রাখার জন্য আপনার ক্রিয়া রয়েছে। পুনরায় ব্যবহারযোগ্য মডিউলে আপনার রূপান্তর যুক্তিকে এপিআই এর ভিতরে এবং বাইরে রেখে দিন, API ব্যবহার করে এমন ক্রিয়ায় সেই মডিউলটি আমদানি করুন এবং এটি হওয়া উচিত should

3) আমি আইডি সহ স্ট্রাকচারের জন্য অ্যারে ব্যবহার করেছি এবং এগুলি আমি অপ্রত্যাশিত পরিণতি ভোগ করেছি:

  • পুরো কোড জুড়ে অবিচ্ছিন্ন জিনিস পুনরায় তৈরি করা
  • হ্রাসকারীদের এবং ক্রিয়াগুলিতে অপ্রয়োজনীয় তথ্য সরবরাহ করা
  • এর ফলস্বরূপ, খারাপ, পরিষ্কার নয় এবং স্কেলযোগ্য কোড নয়।

আমি আমার ডেটা স্ট্রাকচার পরিবর্তন করে প্রচুর কোড পুনরায় লিখেছি ended আপনাকে সতর্ক করা হয়েছে, দয়া করে নিজেকে সমস্যায় ফেলবেন না।

এছাড়াও:

৪) আইডি সহ বেশিরভাগ সংগ্রহগুলি আইডিটিকে পুরো অবজেক্টের রেফারেন্স হিসাবে ব্যবহার করে বোঝানো হয়, আপনার এটির সুবিধা নেওয়া উচিত। এপিআই কলগুলি আইডি এবং তারপরে বাকী প্যারামিটারগুলি পাবেন, আপনার ক্রিয়াকলাপ এবং হ্রাসকারীরাও তাই ঘটবে।


আমি এমন একটি সমস্যার মুখোমুখি হচ্ছি যেখানে আমাদের কাছে একটি অ্যাপ্লিকেশন রয়েছে অনেকগুলি ডেটা (1000 এর থেকে 10,000 এর) সাথে রেডেক্স স্টোরের কোনও বস্তুতে আইডি দ্বারা সঞ্চিত। দর্শনে, তারা সকলে সময় সিরিজের ডেটা প্রদর্শন করতে বাছাই করা অ্যারে ব্যবহার করে। এর অর্থ প্রতিবার একটি রেন্ডার হয়ে গেলে এটি পুরো অবজেক্টটি নিতে হয়, একটি অ্যারেতে রূপান্তর করতে হয় এবং এটি বাছাই করতে হয়। আমি অ্যাপ্লিকেশন এর পারফরম্যান্স উন্নতি করার দায়িত্ব দেওয়া হয়েছিল। এটি কি এমন ব্যবহারের ক্ষেত্রে যেখানে আপনার ডেটাটিকে বাছাই করা অ্যারেতে সংরক্ষণ করতে এবং কোনও বস্তুর পরিবর্তে মুছে ফেলা এবং আপডেটগুলি করতে বাইনারি অনুসন্ধান ব্যবহার করে আরও বুদ্ধিমান হয়?
উইলিয়াম চৌঃ

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

8

1) রিডিউসারটির সরলতা কি অবজেক্ট-কীড-বাই-আইডি পদ্ধতির সাথে যাওয়ার প্রেরণা? রাষ্ট্রীয় আকারের অন্যান্য সুবিধা কি আছে?

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

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

[{
  id: 1,
  name: 'View',
  open: false,
  options: [
    {
      id: 10, 
      title: 'Option 10',
      created_by: { 
        id: 1, 
        username: 'thierry' 
      }
    },
    {
      id: 11, 
      title: 'Option 11',
      created_by: { 
        id: 2, 
        username: 'dennis'
      }
    },
    ...
  ],
  selectedOption: ['10'],
  parent: null,
},
...
]

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

এর আরও ভাল সমাধান হ'ল প্রতিক্রিয়াটিকে এতে স্বাভাবিক করা:

results: [1],
entities: {
  filterItems: {
    1: {
      id: 1,
      name: 'View',
      open: false,
      options: [10, 11],
      selectedOption: [10],
      parent: null
    }
  },
  options: {
    10: {
      id: 10,
      title: 'Option 10',
      created_by: 1
    },
    11: {
      id: 11,
      title: 'Option 11',
      created_by: 2
    }
  },
  optionCreators: {
    1: {
      id: 1,
      username: 'thierry',
    },
    2: {
      id: 2,
      username: 'dennis'
    }
  }
}

এই কাঠামোর সাহায্যে বিকল্পগুলি তৈরি করা সমস্ত ব্যবহারকারীর তালিকা তৈরি করা অনেক সহজ এবং আরও দক্ষ (

এটি আইডি 1 সহ ফিল্টার আইটেমটির জন্য বিকল্পগুলি তৈরি করেছে এমনদের ব্যবহারকারীর নামগুলি প্রদর্শন করাও বেশ সহজ:

entities
  .filterItems[1].options
  .map(id => entities.options[id])
  .map(option => entities.optionCreators[option.created_by].username)

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

একটি JSON- প্রতিক্রিয়া যেমন নরমালাইজার ব্যবহার করে স্বাভাবিক করা যায়

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

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


4
mapএখানে যেমন অপরিবর্তিত রয়েছে তা ফেরৎ দেয় , যদি উত্সগুলি আলাদাভাবে আনা হয়, তবে উপায়টিকে filterআরও জটিল করে তোলে । একটি সমাধান আছে কি?
সারাভানবালাগী রামচন্দ্রন

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