ফাংশন মানচিত্র বনাম সুইচ বিবৃতি


21

আমি একটি প্রকল্পে কাজ করছি যা অনুরোধগুলি প্রক্রিয়া করে, এবং অনুরোধের দুটি উপাদান রয়েছে: কমান্ড এবং পরামিতি। প্রতিটি কমান্ডের হ্যান্ডলারটি খুব সহজ (<10 টি লাইন, প্রায়শই <5)। কমপক্ষে 20 টি কমান্ড রয়েছে এবং সম্ভবত 50 এরও বেশি থাকবে।

আমি বেশ কয়েকটি সমাধান নিয়ে এসেছি:

  • একটি বড় স্যুইচ / যদি-অন্য কমান্ডগুলিতে
  • কমান্ড মানচিত্র
  • অবিচলিত ক্লাস / সিঙ্গলটনে আদেশের মানচিত্র

প্রতিটি কমান্ডটি কিছুটা ত্রুটি পরীক্ষা করে এবং একমাত্র বিট যা বিমূর্ত করা যেতে পারে তা প্রতিটি কমান্ডের জন্য সংজ্ঞায়িত পরামিতিগুলির সংখ্যা পরীক্ষা করে।

এই সমস্যার সর্বোত্তম সমাধান কী হবে এবং কেন? আমি যে কোনও ডিজাইনের ধরণগুলি মিস করেছি তা সম্পর্কেও আমি উন্মুক্ত।

আমি প্রত্যেকের জন্য নিম্নলিখিত প্রো / কনস তালিকাটি নিয়ে এসেছি:

সুইচ

  • অনুকূল
    • সমস্ত আদেশ একটি ফাংশনে রাখে; যেহেতু তারা সহজ, এটি এটি একটি ভিজ্যুয়াল টেবিল তৈরি করে
    • টোন ছোট ফাংশন / ক্লাস যা কেবলমাত্র এক জায়গায় ব্যবহার করা হবে তা নিয়ে উত্সাহিত করার দরকার নেই
  • কনস
    • খুব দীর্ঘ
    • প্রোগ্রামক্রমে কমান্ড যুক্ত করা শক্ত (ডিফল্ট কেস ব্যবহার করে চেইন করা দরকার)

মানচিত্র কমান্ড -> ফাংশন

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

মানচিত্র কমান্ড -> স্ট্যাটিক ক্লাস / সিঙ্গলটন

  • অনুকূল
    • সাধারণ ত্রুটি পরীক্ষা করা পরিচালনা করতে পলিমারফিজম ব্যবহার করতে পারে (কেবল 3 টি লাইনের মতো তবে এখনও)
    • মানচিত্র -> ফাংশন সমাধানের অনুরূপ সুবিধাগুলি
  • কনস
    • প্রচুর খুব ছোট ক্লাস প্রকল্পের বিশৃঙ্খলা করবে
    • বাস্তবায়ন সব একই জায়গায় নয়, তাই বাস্তবায়নগুলি স্ক্যান করা তত সহজ নয়

অতিরিক্ত নোট:

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

কমান্ডটি একটি স্ট্রিং, তবে সুবিধাজনক হলে আমি সহজেই এটি একটি সংখ্যায় ম্যাপ করতে পারি। ফাংশনের স্বাক্ষর এমন কিছু:

Reply Command(List<String> params)

গো শীর্ষ স্তরের ফাংশন রয়েছে এবং অন্যান্য প্ল্যাটফর্মগুলির মধ্যে আমি শীর্ষ স্তরের ফাংশনগুলিও বিবেচনা করছি, সুতরাং দ্বিতীয় এবং তৃতীয় বিকল্পগুলির মধ্যে পার্থক্য রয়েছে।


8
মানচিত্র ফাংশনগুলিতে আদেশ দেয় এবং কনফিগারেশন থেকে রানটাইম এগুলি লোড করে। কমান্ড প্যাটার্ন ব্যবহার করুন।
স্টিভেন এভার্স 17

3
প্রচুর ছোট ফাংশন তৈরি করতে খুব ভয় পাবেন না। সাধারণত, বেশ কয়েকটি ছোট ফাংশনের একটি সংগ্রহ এক বিশাল ফাংশনের চেয়ে বেশি রক্ষণাবেক্ষণযোগ্য।
বার্ট ভ্যান ইনজেন শেহেনো

8
এই টপসি-টারভি বিশ্বে কী আছে, যেখানে লোকেরা মন্তব্যে প্রশ্নের উত্তর দেয় এবং উত্তরগুলিতে আরও তথ্যের জন্য জিজ্ঞাসা করে?
পিডিআর

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

1
@ পিডিআর - ঠিক আছে। আমার প্রবণতা ফাংশনগুলির আদেশগুলির মানচিত্র ছিল, তবে আমি সিএস ডিজাইনের কোর্সে তুলনামূলকভাবে জুনিয়র প্রোগ্রামার। আমার অধ্যাপক প্রচুর ক্লাস পছন্দ করেন, তাই কমপক্ষে 2 টি বৈধ সমাধান রয়েছে। আমি সম্প্রদায়ের প্রিয় জানতে চাই।
বেটগ্যামিট

উত্তর:


14

এটি একটি মানচিত্রের (2 য় বা 3 য় প্রস্তাবিত সমাধান) জন্য দুর্দান্ত ফিট। আমি এটি কয়েক ডজন ব্যবহার করেছি এবং এটি সহজ এবং কার্যকর। আমি এই সমাধানগুলির মধ্যে সত্যই পার্থক্য করি না; গুরুত্বপূর্ণ বিষয় হ'ল কী হিসাবে ফাংশন নাম সহ একটি মানচিত্র রয়েছে।

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

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

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


4

আপনার সমস্যা কমান্ড ডিজাইনের প্যাটার্নকে খুব সুন্দরভাবে ধার দেয় । সুতরাং মূলত আপনার একটি বেস Commandইন্টারফেস থাকবে এবং তারপরে এমন একাধিক CommandImplক্লাস থাকবে যা সেই ইন্টারফেসটি প্রয়োগ করবে। ইন্টারফেসটির মূলত কেবলমাত্র একা পদ্ধতি থাকা দরকার doCommand(Args args)। আপনি Argsক্লাসের উদাহরণের মাধ্যমে যুক্তিগুলি পাস করতে পারেন । এইভাবে আপনি যদি / অন্য বিবৃতিগুলি বিব্রত না করে পলিমারফিজমের শক্তিটি লাভ করেন। এছাড়াও এই নকশা সহজেই বর্ধনযোগ্য।


3

যখনই আমি নিজেকে জিজ্ঞাসা করতে পারি যে আমার কোনও সুইচ স্টেটমেন্ট বা OO- স্টাইলের পলিমারফিজম ব্যবহার করা উচিত আমি অভিব্যক্তি সমস্যাটি উল্লেখ করি । মূলত, আপনার যদি আপনার ডেটার জন্য আলাদা "কেস" থাকে এবং বিভিন্ন "ক্রিয়া" সমর্থন করার জন্য ছড়িয়ে পড়ে (যেখানে প্রতিটি ক্রিয়া প্রতিটি মামলার জন্য কিছু আলাদা করে) তবে স্বাভাবিকভাবেই এমন একটি সিস্টেম তৈরি করা আপনার পক্ষে স্বাভাবিক যে আপনাকে নতুন কেস এবং নতুন ক্রিয়া উভয়ই যুক্ত করতে দেয় ভবিষ্যতে

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

বিপরীতভাবে, আপনি যদি ওও-স্টাইলের পলিমারফিজম ব্যবহার করেন তবে এটি নতুন কেস যুক্ত করা সহজ (কেবলমাত্র একটি নতুন শ্রেণি তৈরি করুন) তবে ইন্টারফেসে পদ্ধতি যুক্ত করা শক্ত (কারণ আপনার আবার ফিরে এসে ক্লাসগুলির একগুচ্ছ সম্পাদনা করতে হবে)

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


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

উদাহরণস্বরূপ, আপনি উত্তরাধিকারের উপর নির্ভর করার পরিবর্তে ত্রুটি পরীক্ষা করার অংশটি করতে সাধারণত প্রতিনিধিদের ব্যবহার করতে পারেন (আমার উদাহরণ জাভাস্ক্রিপ্টে রয়েছে কারণ ও ওয়ান গো সিনট্যাক্স জানেন না, আমি আশা করি আপনার আপত্তি নেই)

function make_command(real_command){
    return function(x){
        if(check_arguments(x)){
            return real_command(x);
        }else{
            //handle error here
        }
    }
 }

 command1 = make_command(function(x){ 
     //do something
 })

 command2 = make_command(function(x){
     //do something else
 })

 command1(17);
 commnad2(42);

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

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


1

আমি কখনই গো ব্যবহার করি নি, এসি # প্রোগ্রামার হিসাবে আমি সম্ভবত নিম্নলিখিত পংক্তিতে যেতে চাই, আশা করি এই আর্কিটেকচারটি আপনি যা করছেন তা ফিট হবে।

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

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

সুতরাং এটি পরীক্ষার জন্য আরও মডিউলার করে তোলে এবং কোডটি সুন্দর এবং ছোট করা উচিত, যা পরে রক্ষণাবেক্ষণ করা সহজ।


0

আপনি কীভাবে আপনার আদেশ / কার্যগুলি নির্বাচন করবেন?

সঠিক ফাংশনটি নির্বাচনের যদি কিছু "চালাক" উপায় থাকে তবে সেটাই যাওয়ার উপায় - এর অর্থ হ'ল মূল যুক্তিটি পরিবর্তন না করে আপনি নতুন সমর্থন যোগ করতে পারেন (সম্ভবত কোনও বাহ্যিক গ্রন্থাগারে)।

এছাড়াও, পৃথক ফাংশনগুলি পরীক্ষা করা এক বিরাট আকারে স্যুইচ স্টেটমেন্টের চেয়ে সহজ।

অবশেষে, কেবলমাত্র এক জায়গায় ব্যবহার করা হচ্ছে - আপনি দেখতে পাবেন যে একবার আপনি 50 এ চলে গেলে বিভিন্ন ফাংশনের বিভিন্ন বিট পুনরায় ব্যবহার করা যেতে পারে?


কমান্ডগুলি অনন্য স্ট্রিং। আমি প্রয়োজন হলে এটি পূর্ণসংখ্যার মানচিত্র করতে পারেন।
বেটগ্যামিট 16

0

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

বিদ্যমান চেইনের লিঙ্কগুলির (বা শেষে) একটি নতুন লিঙ্ক যুক্ত করে বিভিন্ন ব্যবহারের কেসগুলি সহজেই যুক্ত এবং সরানো যেতে পারে।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.