এটি কি একটি ভাল প্যাটার্ন: লম্বা লম্বা সিরিজের সাথে দীর্ঘ ফাংশনটির পরিবর্তে?


14

আমি সম্প্রতি নিম্নলিখিত পরিস্থিতিতে চালিত।

class A{
public:
    void calculate(T inputs);
}

প্রথমত, Aদৈহিক জগতের একটি বস্তুর প্রতিনিধিত্ব করে, যা শ্রেণি বিভক্ত না করার পক্ষে একটি শক্ত যুক্তি। এখন, calculate()বেশ দীর্ঘ এবং জটিল ফাংশন হিসাবে দেখা যাচ্ছে। আমি এটির জন্য তিনটি সম্ভাব্য কাঠামো বুঝতে পারি:

  • এটি পাঠ্যের প্রাচীর হিসাবে লিখুন - সুবিধা - সমস্ত তথ্য এক জায়গায়
  • privateক্লাসে ইউটিলিটি ফাংশন লিখুন এবং তাদের calculateশরীরের - অসুবিধাগুলিতে ব্যবহার করুন - ক্লাসের বাকিরা এই পদ্ধতিগুলি সম্পর্কে জানে / যত্ন / বুঝতে পারে না
  • calculateনিম্নলিখিত পদ্ধতিতে লিখুন :

    void A::calculate(T inputs){    
        auto lambda1 = () [] {};    
        auto lambda2 = () [] {};    
        auto lambda3 = () [] {};
    
        lambda1(inputs.first_logical_chunk);
        lambda2(inputs.second_logical_chunk);
        lambda3(inputs.third_logical_chunk);
    }

এটি একটি ভাল বা খারাপ অনুশীলন হিসাবে বিবেচনা করা যেতে পারে? এই পদ্ধতির কোনও সমস্যা প্রকাশ করে? সব মিলিয়ে, যখন আমি আবার একই পরিস্থিতির মুখোমুখি হই তখন কি আমি এটিকে একটি ভাল পদ্ধতির হিসাবে বিবেচনা করব?


সম্পাদনা করুন:

class A{
    ...
public:
    // Reconfiguration of the algorithm.
    void set_colour(double colour);
    void set_density(double density);
    void set_predelay(unsigned long microseconds);
    void set_reverb_time(double reverb_time, double room_size);
    void set_drywet(double left, double right);
    void set_room_size(double value);;

private:
    // Sub-model objects.
    ...
}

এই সমস্ত পদ্ধতি:

  • একটি মান পেতে
  • রাষ্ট্র ব্যবহার না করে কিছু অন্যান্য মান গণনা করুন
  • কিছু "সাব-মডেল অবজেক্টস" তাদের অবস্থা পরিবর্তন করতে কল করুন।

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

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


2
আপনি কী ভাবেন যে ল্যাম্বডাস ব্যবহার করলে এমন ফাংশন কল আসবে না?
blrfl

1
Firstly, A represents an object in the physical world, which is a strong argument for not splitting the class up.অবশ্যই কোনও বস্তু সম্পর্কে তথ্যA উপস্থাপন করে যা দৈহিক বিশ্বে বিদ্যমান থাকতে পারে । আপনি এর একটি দৃষ্টান্ত হতে পারে Aবাস্তব বস্তু এবং একটি দৃষ্টান্ত ছাড়া একটি বাস্তব বস্তু ছাড়া A, তাই তাদের তারা করছি এক চিকিত্সা এবং একই অর্থহীন নয়।
ডোভাল

@ ব্লারফ্লিল, এনক্যাপসুলেশন - calculate()এই উপ-কার্যাবলী সম্পর্কে কেউ জানতে পারবেন না।
ভোরাক

যদি এই সমস্ত গণনা কেবল প্রাসঙ্গিক হয় A, তবে এটি একেবারে চূড়ান্ত দিকে নিয়ে যাচ্ছে।
blrfl

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

উত্তর:


13

না, এটি সাধারণত ভাল প্যাটার্ন নয়

আপনি যা করছেন তা ল্যাম্বডা ব্যবহার করে ছোট ফাংশনগুলিতে ফাংশন ভাঙ্গা। তবে, ফাংশনগুলি ভাঙ্গার জন্য আরও অনেক ভাল সরঞ্জাম রয়েছে: ফাংশনগুলি।

ল্যাম্বডাস কাজ করেন যেমনটি আপনি দেখেছেন, তবে তারা কেবল স্থানীয় বিটগুলিতে ফাংশন ভাঙার চেয়ে অনেক বেশি অনেক কিছু বোঝায় । লাম্বদাস কর:

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

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

এটি আপনার বাগান করতে ব্যাক হোল ব্যবহার করার মতো। আপনি জানেন যে আপনি এটি কেবল এই বছরের ফুলের জন্য ছোট গর্ত খননের জন্য ব্যবহার করছেন তবে প্রতিবেশীরা ঘাবড়ে যাবেন।

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

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

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

void A::set_room_size(double value)
{
    {
        // Part 1: {description of part 1}
        ...
    }
    // ------------------------
    {
        // Part 2: {description of part 2}
        ...
    }
    // ------------------------
    {
        // Part 3: {description of part 3}
        ...
    }
}

সুতরাং এটি উদ্দেশ্যমূলক সংখ্যা নয়, তবে আমি বিষয়গতভাবে দাবি করব যে ল্যাম্বডা ফাংশনগুলির নিছক উপস্থিতি আমাকে কোডের প্রতিটি লাইনটিতে প্রায় 10 গুণ বেশি মনোযোগ দিতে বাধ্য করেছে, কারণ তাদের পক্ষে বিপজ্জনকভাবে জটিল, দ্রুত হওয়ার এবং এতটা করার সম্ভাবনা রয়েছে have কোডের একটি নির্দোষ চেহারা লাইন (পছন্দ count++)
কর্ট আম্মন

দুর্দান্ত পয়েন্ট। আমি ল্যাম্বডাস - (1) কোডটি স্থানীয়ভাবে সংলগ্ন এবং স্থানীয় স্কোপ সহ (এই ফাইল-স্তরের ফাংশনগুলির দ্বারা হারিয়ে যাবে) (2) সংকলকটি নিশ্চিত করে যে কোনও স্থানীয় ভেরিয়েবল কোড বিভাগগুলির মধ্যে ভাগ করা নেই few সুতরাং সেই সুবিধাগুলি ব্লকগুলিতে পৃথক calculate()করে {}এবং calculate()স্কোপে ভাগ করা ডেটা ঘোষণা করে সংরক্ষণ করা যায় । আমি ভেবেছিলাম যে ল্যাম্বডাস ক্যাপচার না করে দেখে কোনও পাঠক ল্যাম্বডাসের শক্তিতে আবদ্ধ হবে না।
ভোরাক

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

ল্যাম্বডাটির অর্থের বিষয়ে আমার মতামতটি আমি যে C + 11 তে নয়, C ++ 03 এ বড় হয়েছি তা থেকেই বোঝা যায়। ফাংশনটির lambdaমতো অভাবের কারণে সি ++ এর যে নির্দিষ্ট জায়গাগুলি আঘাত পেয়েছিল সেগুলির জন্য একটি প্রশংসা বিকাশ করার জন্য আমি কয়েক বছর সময় কাটিয়েছি for_each। তদনুসারে, যখন আমি lambdaএমন কোনও স্পষ্ট দেখতে পাই যা স্পট থেকে স্পট সমস্যাগুলির মধ্যে একটির সাথে খাপ খায় না , তখন আমি প্রথম অনুমান করি যে এটি সম্ভবত কার্যকরী প্রোগ্রামিংয়ের জন্য ব্যবহৃত হবে, কারণ এটি অন্যথায় প্রয়োজন হয়নি। অনেক বিকাশকারীদের জন্য, ক্রিয়ামূলক প্রোগ্রামিং প্রক্রিয়াগত বা ওও প্রোগ্রামিং থেকে সম্পূর্ণ ভিন্ন মানসিকতা।
আম্মোনে

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

20

আমি মনে করি আপনি একটি খারাপ ধারণা তৈরি করেছেন:

প্রথমত, এ শারীরিক জগতে একটি বস্তুর প্রতিনিধিত্ব করে, যা শ্রেণি বিভক্ত না করার পক্ষে দৃ argument় যুক্তি।

আমি এর সাথে একমত নই। উদাহরণস্বরূপ, যদি আমার কাছে এমন একটি শ্রেণি থাকে যা একটি গাড়ি প্রতিনিধিত্ব করে, আমি অবশ্যই অবশ্যই এটি বিভক্ত করতে চাই, কারণ আমি অবশ্যই একটি ছোট শ্রেণি টায়ারের প্রতিনিধিত্ব করতে চাই।

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

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

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

সংক্ষেপে বলতে গেলে, আমি মনে করি না যে এটি একটি ভাল প্যাটার্ন।

হালনাগাদ

আপনি যদি অর্থবোধক শ্রেণিতে এই কার্যকারিতাটি সজ্জিত করার কোনও উপায় না দেখেন তবে আপনি ফাইল স্কোপড সহায়ক ফাংশন তৈরি করতে পারেন, এটি আপনার শ্রেণীর সদস্য নয় । এটি সর্বোপরি সি ++, ওও ডিজাইনটি আবশ্যক নয়।


যুক্তিযুক্ত মনে হচ্ছে, তবে বাস্তবায়নের কল্পনা করা আমার পক্ষে কঠিন। স্থির পদ্ধতি সহ ফাইল-স্কোপ ক্লাস? শ্রেণি, ভিতরে সংজ্ঞায়িত A(এমনকি অন্য সমস্ত পদ্ধতির ব্যক্তিগত সাথে ব্যক্তিগতও থাকতে পারে)? শ্রেণীর ভিতরে ঘোষিত এবং সংজ্ঞায়িত calculate()(এটি দেখতে অনেকটা আমার ল্যাম্বদা উদাহরণের মতো লাগে)। একটি স্পষ্টকরণ হিসাবে, calculate()এমন একটি পদ্ধতির পরিবারগুলির মধ্যে একটি ( calculate_1(), calculate_2()ইত্যাদি) যার মধ্যে সমস্তগুলি সহজ, কেবল এইটি হল 2 টি পর্দার সূত্র।
ভোরাক

@ ভোরাক: calculate()অন্যান্য পদ্ধতির তুলনায় এত দীর্ঘ কেন ?
কেভিন

@ ভোরাক আপনার কোড না দেখে সাহায্য করা সত্যই কঠিন। আপনি কি এটি পোস্ট করতে পারেন?
গ্যাবার অ্যাঙ্গিয়াল

কেভিন, সমস্ত কিছুর জন্য সূত্রগুলি প্রয়োজনীয়তাতে দেওয়া আছে। কোড পোস্ট করা হয়েছে।
ভোরাক

4
আমি যদি এটি করতে পারি তবে আমি এটি 100 বার উপস্থাপন করব। "রিয়েল ওয়ার্ল্ডে মডেলিং অবজেক্টস" হ'ল অবজেক্ট ডিজাইনের ডেথ সর্পিল। এটি কোনও কোডে একটি দৈত্য লাল পতাকা।
ফ্রেড ম্যাজিক ওয়ান্ডার ডগ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.