কোন অপরিবর্তনীয় বস্তুতে যুক্তি বৈধতা এবং ক্ষেত্রের সূচনা পরীক্ষা করার কোনও সহজ উপায় আছে?


20

আমার ডোমেনটিতে এই জাতীয় প্রচুর অনিবার্য ক্লাস রয়েছে:

public class Person
{
    public string FullName { get; }
    public string NameAtBirth { get; }
    public string TaxId { get; }
    public PhoneNumber PhoneNumber { get; }
    public Address Address { get; }

    public Person(
        string fullName,
        string nameAtBirth,
        string taxId,
        PhoneNumber phoneNumber,
        Address address)
    {
        if (fullName == null)
            throw new ArgumentNullException(nameof(fullName));
        if (nameAtBirth == null)
            throw new ArgumentNullException(nameof(nameAtBirth));
        if (taxId == null)
            throw new ArgumentNullException(nameof(taxId));
        if (phoneNumber == null)
            throw new ArgumentNullException(nameof(phoneNumber));
        if (address == null)
            throw new ArgumentNullException(nameof(address));

        FullName = fullName;
        NameAtBirth = nameAtBirth;
        TaxId = taxId;
        PhoneNumber = phoneNumber;
        Address = address;
    }
}

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

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


আমি এখন উত্তর উপর ভিত্তি করে কি আছে।

আমি দেখতে দেখতে নাল চেক এবং সম্পত্তি সূচনাটি সহজ করতে পারি:

FullName = fullName.ThrowIfNull(nameof(fullName));
NameAtBirth = nameAtBirth.ThrowIfNull(nameof(nameAtBirth));
TaxId = taxId.ThrowIfNull(nameof(taxId));
PhoneNumber = phoneNumber.ThrowIfNull(nameof(phoneNumber));
Address = address.ThrowIfNull(nameof(address));

রবার্ট হার্ভে নিম্নলিখিত প্রয়োগগুলি ব্যবহার করে :

public static class ArgumentValidationExtensions
{
    public static T ThrowIfNull<T>(this T o, string paramName) where T : class
    {
        if (o == null)
            throw new ArgumentNullException(paramName);

        return o;
    }
}

নাল চেক পরীক্ষা ব্যবহার করে সহজ GuardClauseAssertionথেকে AutoFixture.Idioms(প্রস্তাবনা, জন্য ধন্যবাদ Esben Skov Pedersen ):

var fixture = new Fixture().Customize(new AutoMoqCustomization());
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(typeof(Address).GetConstructors());

এটি আরও সংকোচিত হতে পারে:

typeof(Address).ShouldNotAcceptNullConstructorArguments();

এই এক্সটেনশন পদ্ধতিটি ব্যবহার করে:

public static void ShouldNotAcceptNullConstructorArguments(this Type type)
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var assertion = new GuardClauseAssertion(fixture);

    assertion.Verify(type.GetConstructors());
}

3
শিরোনাম / ট্যাগটি অবজেক্টটির নির্মাণ-পরবর্তী ইউনিট পরীক্ষার ক্ষেত্রের মানগুলির পরীক্ষার (ইউনিট) সম্পর্কে আলোচনা করে তবে কোড স্নিপেট ইনপুট আর্গুমেন্ট / প্যারামিটারের বৈধতা দেখায়; এগুলি একই ধারণা নয়।
এরিক tদ

2
এফওয়াইআই, আপনি একটি টি 4 টেমপ্লেট লিখতে পারেন যা এই ধরণের বয়লারপ্লেটকে সহজ করে তোলে। (আপনি স্ট্রিংটিও বিবেচনা করতে পারেন sসেম্পটি () == নাল ছাড়িয়ে))
এরিক

1
আপনি কি অটোফাইচার আইডিয়ামগুলিতে একবার দেখেছেন? nuget.org/packages/ অটোফাইচার.আইডিয়ামস
স্কোভ পেডারসেন


1
আপনি ফডি / নুলগার্ডও ব্যবহার করতে পারেন , যদিও দেখে মনে হচ্ছে এটির ডিফল্ট-অনুমতি মোড নেই।
বব

উত্তর:


5

আমি ঠিক এই ধরণের মামলার জন্য একটি টি 4 টেম্পলেট তৈরি করেছি। অপরিষ্কার ক্লাসগুলির জন্য প্রচুর বয়লারপ্লেট এড়াতে।

https://github.com/xaviergonz/T4Immutable T4Immutable C # .NET অ্যাপ্লিকেশনগুলির জন্য একটি টি 4 টেম্পলেট যা অপরিবর্তনীয় শ্রেণির জন্য কোড উত্পন্ন করে।

বিশেষত নাল পরীক্ষা সম্পর্কে কথা বলার পরে যদি আপনি এটি ব্যবহার করেন:

[PreNotNullCheck, PostNotNullCheck]
public string FirstName { get; }

কনস্ট্রাক্টরটি হ'ল:

public Person(string firstName) {
  // pre not null check
  if (firstName == null) throw new ArgumentNullException(nameof(firstName));

  // assignations + PostConstructor() if needed

  // post not null check
  if (this.FirstName == null) throw new NullReferenceException(nameof(this.FirstName));
}

এটি বলার পরে, আপনি যদি নাল পরীক্ষার জন্য জেটব্রেইন টীকাগুলি ব্যবহার করেন তবে আপনি এটিও করতে পারেন:

[JetBrains.Annotations.NotNull, ConstructorParamNotNull]
public string FirstName { get; }

এবং কনস্ট্রাক্টরটি হ'ল:

public Person([JetBrains.Annotations.NotNull] string firstName) {
  // pre not null check is implied by ConstructorParamNotNull
  if (firstName == null) throw new ArgumentNullException(nameof(firstName));

  FirstName = firstName;
  // + PostConstructor() if needed

  // post not null check implied by JetBrains.Annotations.NotNull on the property
  if (this.FirstName == null) throw new NullReferenceException(nameof(this.FirstName));
}

এছাড়াও এটির চেয়ে আরও কয়েকটি বৈশিষ্ট্য রয়েছে।


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

16

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

internal static T ThrowIfNull<T>(this T o, string paramName) where T : class
{
    if (o == null)
        throw new ArgumentNullException(paramName);

    return o;
}

তারপরে আপনি লিখতে পারেন:

public class Person
{
    public string FullName { get; }
    public string NameAtBirth { get; }
    public string TaxId { get; }
    public PhoneNumber PhoneNumber { get; }
    public Address Address { get; }

    public Person(
        string fullName,
        string nameAtBirth,
        string taxId,
        PhoneNumber phoneNumber,
        Address address)
    {
        FullName = fullName.ThrowIfNull(nameof(fullName));
        NameAtBirth = nameAtBirth.ThrowIfNull(nameof(nameAtBirth));
        TaxId = taxId.ThrowIfNull(nameof(taxId));
        PhoneNumber = phoneNumber.ThrowIfNull(nameof(fullName));
        Address = address.ThrowIfNull(nameof(address));
    }
}

এক্সটেনশন পদ্ধতিতে মূল প্যারামিটারটি ফিরে আসা একটি সাশ্রয়ী ইন্টারফেস তৈরি করে, তাই আপনি যদি চান তবে অন্যান্য এক্সটেনশন পদ্ধতির সাথে এই ধারণাটি প্রসারিত করতে পারেন এবং আপনার কার্যভারে সমস্ত একসাথে চেইন করতে পারেন।

অন্যান্য প্রযুক্তি যেমন একটি সঙ্গে পরামিতি শোভাকর যেমন, ধারণা আরও মার্জিত, কিন্তু সম্পাদনের ক্রমবর্ধমানভাবেই জটিল [NotNull]বৈশিষ্ট্য এবং অন্য কোনো প্রতিফলন ব্যবহার এই

এটি বলেছে, আপনার ক্লাসটি জন-মুখোমুখি এপিআইয়ের অংশ না হলে আপনার এই সমস্ত পরীক্ষার প্রয়োজন হবে না।


3
অদ্ভুত যে এটি ডাউনভোটেড ছিল। এটি সর্বাধিক উত্সাহিত উত্তরের সরবরাহিত পদ্ধতির সাথে অত্যন্ত মিল, কেবলমাত্র এটি রোজলিনের উপর নির্ভর করে না।
রবার্ট হার্ভে

আমি এটি সম্পর্কে যা পছন্দ করি না তা হ'ল এটি কনস্ট্রাক্টরের সংশোধনগুলির পক্ষে ঝুঁকিপূর্ণ।
jpmc26

@ jpmc26: এর অর্থ কী?
রবার্ট হার্ভে

1
আমি আপনার উত্তরটি পড়ার সাথে সাথে এটি পরামর্শ দিচ্ছে যে আপনি কন্সট্রাক্টরের পরীক্ষা করবেন না , তবে পরিবর্তে আপনি প্রতিটি প্যারামিটারে কল করা কিছু সাধারণ পদ্ধতি তৈরি করেন এবং এটি পরীক্ষা করে। আপনি যদি কোনও নতুন সম্পত্তি / যুক্তি জুড়েন এবং নির্মাতার পক্ষে nullযুক্তিটি পরীক্ষা করতে ভুলে যান তবে আপনি একটি ব্যর্থ পরীক্ষা পাবেন না।
jpmc26

@ jpmc26: স্বাভাবিকভাবেই। তবে এটি সত্যও যদি আপনি ওপিতে বর্ণিত প্রচলিত পদ্ধতিতে লিখে থাকেন। সমস্ত সাধারণ পদ্ধতিটি throwকনস্ট্রাক্টরের বাইরে চলে যাওয়া ; আপনি সত্যিই অন্য কোথাও কনস্ট্রাক্টরের মধ্যে নিয়ন্ত্রণ স্থানান্তর করছেন না। এটি কেবল একটি ইউটিলিটি পদ্ধতি এবং যদি আপনি এটি চয়ন করেন তবে সাবলীলভাবে কাজ করার একটি উপায় ।
রবার্ট হার্ভে

7

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

public class Person
{
    public string FullName { get; }
    public string NameAtBirth { get; }
    public string TaxId { get; }
    public PhoneNumber PhoneNumber { get; }
    public Address Address { get; }

    public Person(
        string fullName,
        string nameAtBirth,
        string taxId,
        PhoneNumber phoneNumber,
        Address address)
    {
        FullName = fullName ?? throw new ArgumentNullException(nameof(fullName));
        NameAtBirth = nameAtBirth ?? throw new ArgumentNullException(nameof(nameAtBirth));
        TaxId = taxId ?? throw new ArgumentNullException(nameof(taxId)); ;
        PhoneNumber = phoneNumber ?? throw new ArgumentNullException(nameof(phoneNumber)); ;
        Address = address ?? throw new ArgumentNullException(nameof(address)); ;
    }
}

আপনি ট্রাই রোজলিন ওয়েব অ্যাপের মাধ্যমে নিক্ষেপ অভিব্যক্তি নিয়ে পরীক্ষা করতে পারেন ।


আরও অনেক কমপ্যাক্ট, আপনাকে ধন্যবাদ। অর্ধেক লাইন। সি # 7 এর অপেক্ষায়!
বোটন্ড বালিজ

@ বটন্ডবালিজ আপনি যদি চান তবে এখনই এটি ভিএস 15 প্রাকদর্শনটিতে চেষ্টা করে দেখতে পারেন
ব্যবহারকারী1306322

7

আমি অবাক হয়েছি এখনও কেউ নুলগার্ড.ফডির কথা উল্লেখ করেনি। এটি নুগেটের মাধ্যমে উপলব্ধ এবং সংকলনের সময় স্বয়ংক্রিয়ভাবে সেই সমস্ত নাল চেকগুলি আইএল মধ্যে বুনবে

সুতরাং আপনার কনস্ট্রাক্টর কোডটি সহজভাবে হবে

public Person(
    string fullName,
    string nameAtBirth,
    string taxId,
    PhoneNumber phoneNumber,
    Address address)
{
    FullName = fullName;
    NameAtBirth = nameAtBirth;
    TaxId = taxId;
    PhoneNumber = phoneNumber;
    Address = address;
}

এবং নুলগার্ড আপনার নকল চেকগুলিকে আপনার লিখিতভাবে ঠিক রূপান্তর করার জন্য এটি যুক্ত করবে।

তবে নোটগার্ডটি অপ্ট-আউট হয়েছে কিনা তা লক্ষ করুন , এটি প্রতিটি পদ্ধতি এবং নির্মাণকারী যুক্তি, সম্পত্তি প্রাপ্তি এবং সেটটারের সাথে সেই নাল চেকগুলি যুক্ত করবে এবং এমনকি বৈশিষ্ট্যের সাথে কোনও নাল মানকে স্পষ্টভাবে মঞ্জুরি না দিলে এমনকি পদ্ধতি ফেরতের মানগুলিও পরীক্ষা করবে [AllowNull]


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

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

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

5
হ্যাঁ, এটি যুক্তিসঙ্গত তবে এটি সর্বনিম্ন বিস্ময়ের নীতি লঙ্ঘন করে । যদি কোনও নতুন প্রোগ্রামার যদি না জানে যে প্রকল্পটি নুলগার্ড ব্যবহার করে তবে তারা বড় অবাক হবেন! যাইহোক, আমি ডাউনটাও বুঝতে পারি না, এটি একটি খুব দরকারী উত্তর answer
বোটন্ড বালিজ

1
@ বটন্ডবালিজ / রোমান, নুলগার্ডের কাছে একটি নতুন স্পষ্ট মোড রয়েছে যা ডিফল্টরূপে এটির কাজ করে এমন পরিবর্তন করে
কাইল ডাব্লু

5

এই সমস্ত পরীক্ষা লিখতে মূল্যবান?

না, সম্ভবত না। আপনি যে স্ক্রু করতে যাচ্ছেন সম্ভাবনা কি? কিছু শব্দার্থবিজ্ঞান আপনার অধীনে থেকে পরিবর্তিত হবে এমন সম্ভাবনা কী? কেউ যদি এটিকে ঘায়েল করে তবে এর প্রভাব কী?

যদি আপনি এমন কিছু পরীক্ষার জন্য প্রচুর সময় ব্যয় করেন যা খুব কমই ভেঙে যায়, এবং যদি এটি ঘটে তবে এটি একটি তুচ্ছ সমস্যা ... সম্ভবত এটি মূল্যবান নয় not

এই জাতীয় ক্লাসগুলির প্রত্যেকের জন্য পরীক্ষার লিখন পরীক্ষা এড়ানোর জন্য কোড জেনারেটর লেখার পক্ষে কি ভাল ধারণা হবে?

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


ধন্যবাদ. সম্ভবত আমি আমার প্রশ্নে যথেষ্ট পরিষ্কার ছিল না তবে আমি বোঝাতে চাইছিলাম এমন একটি জেনারেটর লিখুন যা অপরিবর্তনীয় শ্রেণি তৈরি করে, তাদের জন্য পরীক্ষা দেয় না
বোটন্ড বালিজ

2
আমিও একটি পরিবর্তে বেশ কয়েকবার দেখা করেছি if...throwতারা থাকবে ThrowHelper.ArgumentNull(myArg, "myArg"), উপায় যে যুক্তিবিজ্ঞান এখনও আছে এবং আপনি কোড কভারেজ dinged পেতে না। যেখানে ArgumentNullপদ্ধতিটি করবে if...throw
ম্যাথু

2

এই সমস্ত পরীক্ষা লিখতে মূল্যবান?

না।
কারণ আমি নিশ্চিত যে আপনি যুক্তিগুলির অন্যান্য কয়েকটি পরীক্ষার মাধ্যমে properties শ্রেণিগুলি ব্যবহার করা হয়েছে সেখানে আপনি সেই বৈশিষ্ট্যগুলি পরীক্ষা করেছেন।

উদাহরণস্বরূপ, আপনি কারখানার শ্রেণীর জন্য পরীক্ষা করতে পারেন যা সেই বৈশিষ্ট্যগুলির উপর ভিত্তি করে দৃ .়তা জানিয়েছে (সঠিকভাবে বরাদ্দ করা ইনস্ট্যান্স) Name উদাহরণস্বরূপ সম্পত্তি )।

যদি এই শ্রেণিগুলি জনসাধারণের API- এ প্রকাশিত হয় যা কিছু তৃতীয় অংশ / শেষ ব্যবহারকারী (@ জ্যোশুয়া দেখার জন্য ধন্যবাদ) দ্বারা ব্যবহৃত হয়, তবে প্রত্যাশিত পরীক্ষার জন্য ArgumentNullException হতে পারে।

সি # 7 এর জন্য অপেক্ষা করার সময় আপনি এক্সটেনশন পদ্ধতিটি ব্যবহার করতে পারেন

public MyClass(string name)
{
    name.ThrowArgumentNullExceptionIfNull(nameof(name));
}

public static void ThrowArgumentNullExceptionIfNull(this object value, string paramName)
{
    if(value == null)
        throw new ArgumentNullException(paramName);
}

পরীক্ষার জন্য আপনি একটি প্যারামিটারাইজড পরীক্ষা পদ্ধতি ব্যবহার করতে পারেন যা nullপ্রতিটি প্যারামিটারের রেফারেন্স তৈরি করতে প্রতিবিম্ব ব্যবহার করে এবং প্রত্যাশিত ব্যতিক্রমের প্রতি দৃ as়তা দেয়।


1
সম্পত্তি প্রারম্ভিককরণ পরীক্ষা না করার জন্য এটি একটি বিশ্বাসযোগ্য যুক্তি।
বোটন্ড বালিজ

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

2

আপনি সর্বদা নীচের মত একটি পদ্ধতি লিখতে পারেন:

// Just to illustrate how to call this
private static void SomeMethod(string a, string b, string c, string d)
    {
        ValidateArguments(a, b, c, d);
        // ...
    }

    // This is the one to use as a utility function
    private static void ValidateArguments(params object[] args)
    {
        for (int i = 0; i < args.Length; i++)
        {
            if (args[i] == null)
            {
                StackTrace trace = new StackTrace();
                // Get the method that called us
                MethodBase info = trace.GetFrame(1).GetMethod();

                // Get information on the parameter that is null so we can add its name to the exception
                ParameterInfo param = info.GetParameters()[i];

                // Raise the exception on behalf of the caller
                throw new ArgumentNullException(param.Name);
            }
        }
    }

সর্বনিম্ন, যদি আপনার কাছে এমন কয়েকটি বৈধতা রয়েছে যা এই ধরণের বৈধতার প্রয়োজন হয় তবে এটি আপনাকে কিছু টাইপিং সংরক্ষণ করবে। অবশ্যই, এই সমাধানটি অনুমান করে যে আপনার পদ্ধতির কোনও পরামিতি হতে পারে নাnull , কিন্তু আপনার এই যে পরিবর্তন যদি আপনি তা কামনা সংশোধন করতে পারেন।

আপনি অন্যান্য প্রকার-নির্দিষ্ট বৈধতা সম্পাদন করতে এটি প্রসারিত করতে পারেন। উদাহরণস্বরূপ, আপনার যদি নিয়ম থাকে যে স্ট্রিংগুলি বিশুদ্ধরূপে বা খালি হওয়া যায় না, আপনি নিম্নলিখিত শর্তটি যুক্ত করতে পারেন:

// Note that we already know based on the previous condition that args[i] is not null
else if (args[i].GetType() == typeof(string))
            {
                string argCast = arg as string;

                if (!argCast.Trim().Any())
                {
                    ParameterInfo param = GetParameterInfo(i);

                    throw new ArgumentException(param.Name + " is empty or consists only of whitespace");
                }
            }

GetParameterInfo পদ্ধতিটি আমি উল্লেখ করি মূলত প্রতিচ্ছবিটি ঘটে (যাতে আমাকে একই জিনিস বার বার লিখতে হবে না, যা DRY নীতি লঙ্ঘন হবে ):

private static ParameterInfo GetParameterInfo(int index)
    {
        StackTrace trace = new StackTrace();

        // Note that we have to go 2 methods back to get the ValidateArguments method's caller
        MethodBase info = trace.GetFrame(2).GetMethod();

        // Get information on the parameter that is null so we can add its name to the exception
        ParameterInfo param = info.GetParameters()[index];

        return param;
    }

1
কেন এটিকে নিম্নমানের করা হচ্ছে? এটি খুব খারাপ নয়
গ্যাসপা79

0

আমি কনস্ট্রাক্টর থেকে ব্যতিক্রম নিক্ষেপ করার পরামর্শ দিই না। সমস্যাটি হ'ল এটি পরীক্ষা করার জন্য আপনার একটি শক্ত সময় হবে কারণ আপনাকে বৈধ প্যারামিটারগুলি পাস করতে হবে এমনকি তারা আপনার পরীক্ষার জন্য অপ্রাসঙ্গিক।

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

আমি জাভা বৈধতা এপিআই ব্যবহার এবং বৈধকরণ প্রক্রিয়া বহিরাগত করার পরামর্শ দিই। আমি চারটি দায়িত্ব (ক্লাস) জড়িত থাকার পরামর্শ দিচ্ছি:

  1. জাভা বৈধতা সহ একটি প্রস্তাবিত অবজেক্ট একটি বৈধতা পদ্ধতি যা প্রতিবন্ধীকরণের সেটকে ফেরত দেয় তার সাথে পরামিতিগুলি উল্লেখ করে। একটি সুবিধা হ'ল আপনি বৈধ হওয়ার জন্য দৃ objects়তা ছাড়াই এই বস্তুর চারপাশে যেতে পারেন। ডোমেন অবজেক্টটি ইনস্ট্যান্ট করার চেষ্টা না করে আপনি প্রয়োজনীয়তা অবধি বৈধকরণ বিলম্ব করতে পারেন। বৈধতা অবজেক্টটি বিভিন্ন স্তরগুলিতে ব্যবহার করা যেতে পারে কারণ এটি কোনও POJO হওয়ায় কোনও স্তর নির্দিষ্ট জ্ঞান নেই। এটি আপনার সর্বজনীন API এর অংশ হতে পারে।

  2. বৈধ অবজেক্ট তৈরি করার জন্য দায়বদ্ধ ডোমেন অবজেক্টের জন্য একটি কারখানা। আপনি প্রস্তাবিত অবজেক্টে পাস করুন এবং কারখানাটি বৈধকরণটিকে কল করবে এবং সবকিছু ঠিক থাকলে ডোমেন অবজেক্ট তৈরি করবে।

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

  4. কংক্রিট ডোমেন অবজেক্টটি আড়াল করতে এবং অপব্যবহারকে শক্ত করে তোলার জন্য একটি পাবলিক ডোমেন ইন্টারফেস।

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

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


1
আমি শ্রদ্ধার সাথে আপনার শেষ বক্তব্য সাথে একমত। 100 তম সময় জন্য একই boilerplate, টাইপ করা হচ্ছে না নেই সাহায্যের ভুল তৈরীর সুযোগ কমে যায়। ভাবুন এটি সি জাভা না হয়ে জাভা হত। আমাকে প্রতিটি সম্পত্তির জন্য একটি ব্যাকিং ফিল্ড এবং একটি গেটর পদ্ধতি নির্ধারণ করতে হবে। কোডটি পুরোপুরি অপঠনযোগ্য হয়ে উঠবে এবং যা গুরুত্বপূর্ণ তা হবে clunky অবকাঠামো দ্বারা অস্পষ্ট।
বোটন্ড বালিজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.