উদাহরণস্বরূপ বা স্থিতিশীল হিসাবে সহায়ক পদ্ধতিগুলি - কোনটি আরও ভাল অনুশীলন?


48

এই প্রশ্নটি সাবজেক্টিভ তবে আমি বেশ কৌতূহল ছিলাম যে সর্বাধিক প্রোগ্রামাররা এটির কাছে যান। নীচের নমুনাটি সিউডো-সি # তে রয়েছে তবে এটি জাভা, সি ++ এবং অন্যান্য ওওপি ভাষার ক্ষেত্রেও প্রযোজ্য।

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

class Foo
{
  Bar _bar;

  public void DoSomethingWithBar()
  {
    // Method Call #1.
    DoSomethingWithBarImpl();

    // Method Call #2.
    DoSomethingWithBarImpl(_bar);
  }

  private void DoSomethingWithBarImpl()
  {
    _bar.DoSomething();
  }

  private static void DoSomethingWithBarImpl(Bar bar)
  {
    bar.DoSomething();
  }
}

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

আপনি নিজের কোডে কোনটি করতে পছন্দ করেন এবং এটি করার কারণগুলি কী কী?


3
আমি এই প্রশ্ন থেকে সি ++ সরিয়ে ফেলব: সি ++ এ স্পষ্টতই আপনি এটিকে একটি নিখরচায় পদ্ধতিতে পরিণত করবেন, কারণ এটিকে নির্বিচারে কোনও বস্তুতে আটকানো হওয়ার কোনও কারণ নেই: এটি এডিএল অক্ষম করে।
ম্যাথিউ এম।

1
@ ম্যাথিউইউম: বিনামূল্যে পদ্ধতি বা না, এটি কোনও ব্যাপার নয়। আমার প্রশ্নের উদ্দেশ্যটি হ'ল জিজ্ঞাসা করার জন্য হেল্পার পদ্ধতিগুলি উদাহরণ হিসাবে ঘোষণা করার কোনও সুবিধা আছে কিনা। সুতরাং সি ++ এ পছন্দ উদাহরণ পদ্ধতি বনাম ফ্রি পদ্ধতি / ফাংশন হতে পারে। আপনি ADL সম্পর্কে একটি ভাল পয়েন্ট পেয়েছি। সুতরাং আপনি কি বলছেন যে আপনি বিনামূল্যে পদ্ধতি ব্যবহার করতে পছন্দ করেন? ধন্যবাদ!
ইলিয়ান

2
সি ++ এর জন্য, বিনামূল্যে পদ্ধতিগুলি সুপারিশ করা হয়। তারা এনক্যাপসুলেশন বৃদ্ধি করে (অপ্রত্যক্ষভাবে কেবলমাত্র পাবলিক ইন্টারফেস অ্যাক্সেস করতে সক্ষম হিসাবে) এবং এখনও এডিএল (বিশেষত টেমপ্লেটগুলিতে) কারণে দুর্দান্ত খেলায়। তবে যদি এই জাভা / সি # প্রযোজ্য জানি না, সি ++ পৃথক ব্যাপকভাবে থেকে জাভা / সি # তাই আমি উত্তর ভিন্ন আশা (এবং এইভাবে আমি 3 ভাষার জন্য জিজ্ঞাসা একসঙ্গে জানার জন্য মনে করি না)।
ম্যাথিউ এম।


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

উত্তর:


23

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

যদি তারা জটিল হয় তবে সলাইড প্রয়োগ হয়, বিশেষত এস , আই এবং ডি

উদাহরণ:

class CookieJar {
      function takeCookies(count:Int):Array<Cookie> { ... }
      function countCookies():Int { ... }
      function ressuplyCookies(cookies:Array<Cookie>
      ... // lot of stuff we don't care about now
}

class CookieFan {
      function getHunger():Float;
      function eatCookies(cookies:Array<Cookie>):Smile { ... }
}

class OurHouse {
      var jake:CookieFan;
      var jane:CookieFan;
      var cookies:CookieJar;
      function makeEveryBodyAsHappyAsPossible():Void {
           //perform a lot of operations on jake, jane and the cookies
      }
      public function cookieTime():Void {
           makeEveryBodyAsHappyAsPossible();
      }
}

এটি আপনার সমস্যা সম্পর্কে হবে। আপনি করতে পারেন করা makeEveryBodyAsHappyAsPossibleএকটি স্ট্যাটিক পদ্ধতি, প্রয়োজনীয় পরামিতি গ্রহণ করা হবে। আরেকটি বিকল্প হ'ল:

interface CookieDistributor {
    function distributeCookies(to:Array<CookieFan>):Array<Smile>;
}
class HappynessMaximizingDistributor implements CookieDistributor {
    var jar:CookieJar;
    function distributeCookies(to:Array<CookieFan>):Array<Smile> {
         //put the logic of makeEveryBodyAsHappyAsPossible here
    }
}
//and make a change here
class OurHouse {
      var jake:CookieFan;
      var jane:CookieFan;
      var cookies:CookieDistributor;

      public function cookieTime():Void {
           cookies.distributeCookies([jake, jane]);
      }
}

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

তবে, খেয়াল রাখবেন যে আপনি এটি অতিরিক্ত পরিমাণে না ঘটাচ্ছেন। উদাহরণস্বরূপ ৩০ টি শ্রেণির একটি জটিল ব্যবস্থা থাকা বাস্তবায়ন হিসাবে কাজ করে CookieDistributor, যেখানে প্রতিটি শ্রেণি কেবল একটি ছোট্ট কাজ সম্পাদন করে, সত্যিকার অর্থে তা বোঝায় না। এসআরপি সম্পর্কে আমার ব্যাখ্যাটি হ'ল এটি কেবলমাত্র নির্দেশ দেয় না যে প্রতিটি শ্রেণীর কেবল একটি দায়িত্ব থাকতে পারে, তবে এটিও যে একটি একক দায়িত্ব একক শ্রেণীর দ্বারা পরিচালিত হওয়া উচিত।

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

সুতরাং আপনার সমস্যার উপর নির্ভর করে এটির বিভিন্ন উপায় রয়েছে।


18

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

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

হালনাগাদ

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

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


আপনি কি স্থিতিশীল সহায়তা পদ্ধতির উপর নির্ভরতাটি পাস করতে পারবেন না?
ইলিয়ান

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

1
স্ট্যাটিকস সহজেই 'বিদ্রূপ' করা হয় - মাইক্রোসফ্ট মোলস বা জাল (নির্ভর করে ভিএস2010 বা ভিএস ২০১২ +) আপনাকে পরীক্ষায় নিজের প্রয়োগের সাথে একটি স্ট্যাটিক পদ্ধতি প্রতিস্থাপন করতে দেয়। পুরানো উপহাস ফ্রেমওয়ার্কগুলি অচল করে তোলে। (এটি প্রচলিত উপহাসগুলিও করে এবং কংক্রিটের ক্লাসগুলিও উপহাস করতে পারে)। এটি এমএস থেকে বিনামূল্যে এক্সটেনশন ম্যানেজারের মাধ্যমে।
gbjbaanb

4

আপনি নিজের কোডে কোনটি করতে পছন্দ করেন?

আমি # 1 ( this->DoSomethingWithBarImpl();) পছন্দ করি , যদি না অবশ্যই সহায়তাকারীর পদ্ধতির উদাহরণের ডেটা / প্রয়োগের অ্যাক্সেসের প্রয়োজন হবে না static t_image OpenDefaultImage()

এবং এটি করার জন্য আপনার কারণগুলি কী?

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

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

static void ValidateImage(const t_image& image);
void validateImages() const {
    ValidateImage(this->innerImage());
    ValidateImage(this->outerImage());
}

যদি # 2 একটি কোডবেজে একটি ভাল সাধারণ সমাধান (যেমন ডিফল্ট) হয় তবে আমি ডিজাইনের কাঠামো সম্পর্কে উদ্বিগ্ন হব: ক্লাসগুলি কি খুব বেশি করছে? পর্যাপ্ত এনক্যাপসুলেশন নেই বা পর্যাপ্ত পুনঃব্যবহার নয়? বিমূর্ততা স্তর কি যথেষ্ট উচ্চ?

শেষ পর্যন্ত, # 2 টি অপ্রয়োজনীয় বলে মনে হয় যদি আপনি ওও ভাষা ব্যবহার করেন যেখানে মিউটেশন সমর্থিত (যেমন একটি constপদ্ধতি)।

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