আমাদের কী পুরো মডিউল ব্যবহার বা কেবল সর্বজনীন পদ্ধতির যুক্তি যাচাই করতে হবে?


9

আমি শুনেছি যে পাবলিক পদ্ধতির যুক্তিগুলির বৈধতা দেওয়ার পরামর্শ দেওয়া হচ্ছে:

প্রেরণা বোধগম্য। যদি কোনও মডিউলটি কোনও ভুল উপায়ে ব্যবহার করা হয়, তবে আমরা কোনও অনাকাঙ্ক্ষিত আচরণের পরিবর্তে অবিলম্বে ব্যতিক্রম নষ্ট করতে চাই।

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

  • আগত কল - অপ্রত্যাশিত যুক্তি
  • ইনকামিং কল - মডিউলটি ভুল অবস্থায় রয়েছে
  • বাহ্যিক কল - অপ্রত্যাশিত ফলাফল ফিরে এসেছে
  • বাহ্যিক কল - অপ্রত্যাশিত পার্শ্ব-প্রতিক্রিয়া (কলিং মডিউলে ডাবল-প্রবেশ, অন্যান্য নির্ভরশীলতাগুলির অবস্থা ভঙ্গ করে)

আমি এই সমস্ত শর্তটি বিবেচনায় নেওয়ার চেষ্টা করেছি এবং একটি পদ্ধতি সহ একটি সাধারণ মডিউল লেখার জন্য দুঃখিত (দুঃখিত, সি-সি নয়):

public sealed class Room
{
    private readonly IDoorFactory _doorFactory;
    private bool _entered;
    private IDoor _door;
    public Room(IDoorFactory doorFactory)
    {
        if (doorFactory == null)
            throw new ArgumentNullException("doorFactory");
        _doorFactory = doorFactory;
    }
    public void Open()
    {
        if (_door != null)
            throw new InvalidOperationException("Room is already opened");
        if (_entered)
            throw new InvalidOperationException("Double entry is not allowed");
        _entered = true;
        _door = _doorFactory.Create();
        if (_door == null)
            throw new IncompatibleDependencyException("doorFactory");
        _door.Open();
        _entered = false;
    }
}

এখন এটি নিরাপদ =)

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

সংক্ষেপে বলা যায়, সঠিক উপায় কী এবং কেন? আপনি যদি নীচের বিকল্পগুলি থেকে চয়ন করতে পারেন তবে অতিরিক্ত প্রশ্নের উত্তর দিন, দয়া করে।

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

কেবল যুক্তি পরীক্ষা করুন Check আমার অভিজ্ঞতা থেকে, যুক্তি যাচাই করা - বিশেষত নাল চেকিং - সবচেয়ে কার্যকর কার্যকর চেক, কারণ যুক্তি ত্রুটি খুব কমই জটিল ভুল এবং ত্রুটির ত্রুটি বাড়িয়ে তোলে। বেশিরভাগ সময় আপনি NullReferenceExceptionপরের লাইনে পাবেন। সুতরাং যুক্তি যাচাই কেন এত বিশেষ?

মডিউল ব্যবহার পরীক্ষা করবেন না। এটি বেশ অপ্রিয় মতামত, আপনি কেন ব্যাখ্যা করতে পারেন?


আক্রমণকারীদের রাখা হয় তা নিশ্চিত করার জন্য মাঠের কার্যভারের সময় চেক করা উচিত।
বেসিলিভ

@ বাসিলিভস আকর্ষণীয় ... এটি কোড কনট্রাক্টসের আদর্শ থেকে বা আরও পুরানো? আপনি কি কিছু পড়ার জন্য সুপারিশ করতে পারেন (আপনার মন্তব্যের সাথে সম্পর্কিত)?
astef

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

@ বাসিলিভস সুতরাং, অন্যান্য মডিউলগুলির আচরণটি একেবারেই পরীক্ষা করবেন না তবে নিজের রাষ্ট্রের আক্রমণকারীদের পরীক্ষা করুন। যুক্তিসঙ্গত মনে হচ্ছে। তবে আমি যুক্তি যাচাই সংক্রান্ত সম্পর্কিত প্রশ্নগুলিতে এই সাধারণ প্রাপ্তিটি কেন দেখছি না?
astef

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

উত্তর:


2

টিএল; ডিআর: রাষ্ট্র পরিবর্তনকে বৈধ করুন, বর্তমান অবস্থার [বৈধতার] উপর নির্ভর করুন।

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

নিম্নলিখিত নীতিগুলি বিবেচনা করুন:

  • সাধারণ বোধ
  • দ্রুত ব্যর্থ
  • শুকনো
  • SRP

সংজ্ঞা

  • উপাদান - একটি ইউনিট সরবরাহকারী API
  • ক্লায়েন্ট - উপাদান এর এপিআই এর ব্যবহারকারী

পরিবর্তনীয় অবস্থা

সমস্যা

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

সমাধান

রাজ্যের প্রতিটি পরিবর্তনকে সাবধানে তৈরি করা উচিত এবং যাচাই করা উচিত। পরিবর্তনীয় রাষ্ট্রের সাথে মোকাবিলা করার একটি উপায় হ'ল এটি সর্বনিম্ন রাখা। এটি দ্বারা অর্জন করা হয়:

  • টাইপ সিস্টেম (কনস্ট্যান্ড এবং চূড়ান্ত সদস্যের ঘোষণা)
  • আক্রমণকারীদের পরিচয় করিয়ে দেওয়া
  • সর্বজনীন API এর মাধ্যমে উপাদানগুলির রাজ্যের প্রতিটি পরিবর্তন যাচাই করা

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

উদাহরণ

// Wrong
class Natural {
    private int number;
    public Natural(int number) {
        this.number = number;
    }
    public int getInt() {
      if (number < 1)
          throw new InvalidOperationException();
      return number;
    }
}

// Right
class Natural {
    private readonly int number;
    /**
     * @param number - positive number
     */
    public Natural(int number) {
      // Going to modify state, verification is required
      if (number < 1)
        throw new ArgumentException("Natural number should be  positive: " + number);
      this.number = number;
    }
    public int getInt() {
      // State is guaranteed by construction and compiler
      return number;
    }
}

পুনরাবৃত্তি এবং দায়িত্ব সংহতি

সমস্যা

পূর্ব শর্তাদি এবং অপারেশনের পোস্ট-শর্তাদি পরীক্ষা করা ক্লায়েন্ট এবং উপাদান উভয়ই যাচাইকরণ কোডটির নকল করে। উপাদান অনুরোধের বৈধতা প্রদান ক্লায়েন্টকে উপাদানগুলির কিছু দায়িত্ব নিতে বাধ্য করে।

সমাধান

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

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

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

উদাহরণ

class Store {
  private readonly List<int> slots = new List<int>();
  public void putToSlot(int slot, int data) {
    if (slot < 0 || slot >= slots.Count) // Unnecessary, validated by List, only needed for custom error message
      throw new ArgumentException("data");
    slots[slot] = data;
  }
}

class Natural {
   int _number;
   public Natural(int number) {
       if (number < 1)
          number = 1;  //Wrong: client can't rely on argument verification, additional state uncertainity is introduced.  Right: throw new ArgumentException(number);
       _number = number;
   }
}

উত্তর

বর্ণিত নীতিগুলি যখন প্রশ্নের উদাহরণে প্রয়োগ করা হয়, তখন আমরা পাই:

public sealed class Room
{
    private bool _entered = false;
    // Do not use lazy instantiation if not absolutely necessary, this introduces additional mutable state
    private readonly IDoor _door;
    public Room(IDoorFactory doorFactory)
    {
        // Rely on system null check
        IDoor door = _doorFactory.Create();
        // Modifying own state, verification is required
        if (door == null)
           throw new ArgumentNullException("Door");
        _door = door;
    }
    public void Enter()
    {
        // Room invariants do not guarantee _entered value. Door state is indirectly a part of our state. Verification is required to prevent second door state change below.
        if (_entered)
           throw new InvalidOperationException("Double entry is not allowed");
        _entered = true;     
        // rely on immutability for _door field to be non-null
        // rely on door implementation to control resulting door state       
        _door.Open();            
    }
}

সারসংক্ষেপ

ক্লায়েন্টের রাজ্যের নিজস্ব ক্ষেত্রের মান এবং উপাদানগুলির রাজ্যের অংশগুলি রয়েছে যা তার নিজস্ব আক্রমণকারীদের দ্বারা আচ্ছাদিত নয়। যাচাইকরণ কেবলমাত্র একজন ক্লায়েন্টের আসল রাষ্ট্র পরিবর্তনের আগেই করা উচিত।


1

একটি শ্রেণি তার নিজের রাষ্ট্রের জন্য দায়বদ্ধ। সুতরাং এটি যে পরিমাণ জিনিসকে গ্রহণযোগ্য অবস্থায় রাখে বা রাখে তার পরিমাণে বৈধতা দিন।

যদি কোনও মডিউলটি কোনও ভুল উপায়ে ব্যবহার করা হয়, তবে আমরা কোনও অনাকাঙ্ক্ষিত আচরণের পরিবর্তে অবিলম্বে ব্যতিক্রম নষ্ট করতে চাই।

না, কোনও ব্যতিক্রম ছুঁড়ে মারবেন না, পরিবর্তে অনুমানযোগ্য আচরণ করুন। রাষ্ট্রের দায়বদ্ধতার সাথে পরিণতি হ'ল শ্রেণি / প্রয়োগকে ব্যবহারিক হিসাবে সহনশীল করে তোলা। উদাহরণস্বরূপ, ক্ষণস্থায়ী nullকরতে aCollection.Add()? শুধু যোগ এবং চলতে না। আপনি nullএকটি অবজেক্ট তৈরি করার জন্য ইনপুট পাবেন ? নাল অবজেক্ট বা ডিফল্ট অবজেক্ট তৈরি করুন। উপরে, doorইতিমধ্যে আছে open? তাহলে কি, চলতে থাকুন। DoorFactoryযুক্তি নাল? একটি নতুন তৈরি করুন। আমি যখন একটি তৈরি করি তখন আমার enumসর্বদা একজন Undefinedসদস্য থাকে। আমি এর উদার ব্যবহার করি Dictionaryএবং enumsবিষয়গুলিকে স্পষ্টভাবে সংজ্ঞায়িত করি; এবং এটি অনুমানযোগ্য আচরণ সরবরাহের দিকে অনেক এগিয়ে যায়।

(হাই, নির্ভরতা ইনজেকশন প্রেমীদের!)

হ্যাঁ যদিও আমি প্যারামিটারগুলির উপত্যকার ছায়া দিয়ে চলেছি তবে আমি কোনও যুক্তিই ভয় করব না। পূর্বেরটিতে আমি ডিফল্ট এবং alচ্ছিক প্যারামিটারগুলি যতটা সম্ভব ব্যবহার করি।

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

সম্পাদন করা

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

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

শেষ সম্পাদনা


1
একটি অবৈধ সংগ্রহ উপাদান যুক্ত না করা একটি খুব অনির্দেশ্য আচরণ।
বেসিলিভ

1
সমস্ত ইন্টারফেস যদি এমন সহনশীল উপায়ে তৈরি করা হয়, তবে একদিন ব্যানাল ত্রুটির কারণে প্রোগ্রামগুলি দুর্ঘটনাবশত জাগ্রত হবে এবং মানবতা ধ্বংস করবে।
Astef

আমরা এখানে মূল ধারণাগুলি / অনুমানগুলি ভুলে যাচ্ছি - encapsulation& single responsibilitynullপ্রথমটি, ক্লায়েন্ট-ইন্টারেক্টিভ স্তরের পরে কার্যত কোনও চেকিং নেই । কোডটি <স্ট্রাইক> সহনশীল </ স্ট্রাইক> মজবুত। ক্লাসগুলি ডিফল্ট রাজ্যগুলির সাথে নকশাকৃত এবং তাই ইন্টারেক্টিভ কোডটি বাগ-চালিত, দুর্বৃত্ত জাঙ্কের মতো লিখিত না হয়ে কাজ করে। যৌগিক পিতামাতাকে বৈধতা মূল্যায়নের জন্য শিশু স্তরগুলি নীচে পৌঁছাতে হবে না (এবং জড়িত হয়ে, nullসমস্ত কুকুর এবং ক্রেইনগুলি পরীক্ষা করে দেখুন)। সন্তানের ডিফল্ট রাষ্ট্রটির অর্থ পিতামাতারা জানেন
রাডারবব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.