তথ্যবহুল ব্যতিক্রম এবং পরিষ্কার কোডের ভারসাম্য রক্ষার ভাল উপায়গুলি কী কী?


11

আমাদের সার্বজনীন এসডিকে দিয়ে, আমরা কেন ব্যতিক্রম ঘটে তা সম্পর্কে খুব তথ্যমূলক বার্তা দিতে চাই tend উদাহরণ স্বরূপ:

if (interfaceInstance == null)
{
     string errMsg = string.Format(
          "Construction of Action Argument: {0}, via the empty constructor worked, but type: {1} could not be cast to type {2}.",
          ParameterInfo.Name,
          ParameterInfo.ParameterType,
          typeof(IParameter)
    );

    throw new InvalidOperationException(errMsg);
}

যাইহোক, এটি কোডটির প্রবাহকে বিশৃঙ্খলা করতে পারে, কারণ কোডটি কী করছে তার চেয়ে ত্রুটি বার্তাগুলিতে অনেক ফোকাস রাখে।

একজন সহকর্মী ব্যতিক্রম কিছু এরকম কিছু ছুঁড়ে ফেলে পুনরায় সঞ্চার শুরু করলেন:

if (interfaceInstance == null)
    throw EmptyConstructor();

...

private Exception EmptyConstructor()
{
    string errMsg = string.Format(
          "Construction of Action Argument: {0}, via the empty constructor worked, but type: {1} could not be cast to type {2}.",
          ParameterInfo.Name,
          ParameterInfo.ParameterType,
          typeof(IParameter)
    );

    return new InvalidOperationException(errMsg);
}

যা কোড লজিককে বোঝা সহজ করে তোলে, তবে ত্রুটি পরিচালনা করার জন্য অতিরিক্ত প্রচুর পদ্ধতি যুক্ত করে।

"দীর্ঘ-ব্যতিক্রম-বার্তা বিশৃঙ্খলা যুক্তি" সমস্যা এড়ানোর অন্যান্য উপায়গুলি কী কী? আমি প্রাথমিকভাবে আইডেম্যাটিক সি # /। নেট সম্পর্কে জিজ্ঞাসা করছি, তবে অন্যান্য ভাষা কীভাবে এটি পরিচালনা করে তাও সহায়ক।

[সম্পাদনা]

প্রতিটি পদ্ধতির পাশাপাশি ভাল মতামত পাওয়া ভাল লাগবে।


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

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

1
চিন্তাধারা: কি বার্তা না সব ব্যতিক্রম বিস্তারিত ক্যারিয়ার। সম্পত্তিটি ব্যবহারের সংমিশ্রণ , "পিক" ব্যতিক্রমী ক্যাপচারিং, কলিং কোড ক্যাপচারিং এবং তার নিজস্ব প্রসঙ্গ যুক্ত করার সাথে সাথে ক্যাপচারিত কল স্ট্যাকের সাথে এমন সমস্ত তথ্য অবদান রাখে যা খুব কম ভার্বোস বার্তাগুলিকে অনুমতি দেয়। অবশেষে আপনার "ব্যতিক্রম নির্মাণ" পদ্ধতিতে বিশদ সরবরাহ করার জন্য প্রতিশ্রুতিবদ্ধ দেখায়। Exception.DataSystem.Reflection.MethodBase
রাডারবব

@radarbob আপনি কি পরামর্শ দিচ্ছেন যে সম্ভবত ব্যতিক্রমগুলি খুব ভার্জোজ? সম্ভবত আমরা এটি অনেক বেশি লগিংয়ের মতো করে দিচ্ছি।
ফ্রেন্ডলিগুই

1
@ ম্যাকলেচান, আমি পড়েছি যে এখানে দৃষ্টান্তটি একটি বার্তায় তথ্য প্রেরণ করা হয়েছে যা 'যথাযথভাবে কী ঘটেছে তা বলার চেষ্টা করেছে, এটি ব্যাকরণগতভাবে সঠিক, এবং এআই-র একটি ভান: ".. খালি নির্মাণকারীর মাধ্যমে কাজ করেছে, কিন্তু .." " সত্যি? আমার অভ্যন্তরীণ ফরেনসিক কোডার এটিকে স্ট্যাক-ট্রেস-হারানো পুনরায় নিক্ষেপ এবং অসচেতনতার সাধারণ ত্রুটির বিবর্তনীয় পরিণতি হিসাবে দেখছে Exception.Data। জোর দেওয়া উচিত টেলিমেট্রি ক্যাপচার করা উচিত। এখানে রিফ্যাক্টরিং ঠিক আছে তবে সমস্যাটি এটি মিস করে।
রডারবব

উত্তর:


10

বিশেষায়িত ব্যতিক্রম ক্লাস কেন নেই?

if (interfaceInstance == null)
{
    throw new ThisParticularEmptyConstructorException(<maybe a couple parameters>);
}

এটি ব্যতিক্রম নিজেই ফর্ম্যাটিং এবং বিশদটি ধাক্কা দেয় এবং মূল শ্রেণিকে নিরবিচ্ছিন্ন করে ফেলে।


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

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

যা আসলেই দুর্গন্ধযুক্ত (ক্লাসগুলির সাথে শক্তভাবে মিলিত ব্যতিক্রম)। আমি অনুমান করি যে ব্যতিক্রমগুলির তুলনায় স্বনির্ধারিত ব্যতিক্রম বার্তাগুলির ভারসাম্য বজায় রাখা শক্ত হবে।
ফ্রেন্ডলিগুই

7

মাইক্রোসফ্ট মনে হয় (। নেট উত্সটি দেখার মাধ্যমে) কখনও কখনও সংস্থান / পরিবেশের স্ট্রিং ব্যবহার করে। উদাহরণস্বরূপ ParseDecimal:

throw new OverflowException(Environment.GetResourceString("Overflow_Decimal"));

পেশাদাররা:

  • পুনরায় ব্যবহারের অনুমতি দিয়ে ব্যতিক্রম বার্তাগুলিকে কেন্দ্রিয়করণ
  • পদ্ধতিগুলির যুক্তি থেকে ব্যতিক্রম বার্তা (তর্কসাপেক্ষে যা কোডের কোনও বিষয় নয়) রাখছেন
  • ফেলে দেওয়া ব্যতিক্রমের ধরণটি পরিষ্কার
  • বার্তাগুলি স্থানীয় করা যায়

কনস:

  • যদি একটি ব্যতিক্রম বার্তা পরিবর্তিত হয় তবে সেগুলি সমস্ত পরিবর্তন হয়
  • ব্যতিক্রম নিক্ষেপকারী কোডটিতে ব্যতিক্রম বার্তাটি সহজেই পাওয়া যায় না।
  • বার্তা স্থিতিশীল এবং কোন মানগুলি ভুল তা সম্পর্কে কোনও তথ্য নেই। আপনি যদি এটি ফর্ম্যাট করতে চান তবে কোডে এটি আরও বিশৃঙ্খলা।

2
আপনি একটি বিশাল সুবিধা রেখে গেছেন: ব্যতিক্রম পাঠ্যের স্থানীয়করণ
26

@ 17of26 - ভাল পয়েন্ট, এটি যুক্ত।
ফ্রেন্ডলিগুই

আমি আপনার উত্তরটিকে উঁচু করে তুলেছি, তবে এইভাবে তৈরি করা ত্রুটি বার্তাগুলি "স্থির"; ওপি যেমন তার কোড করছে সেভাবে আপনি তাদের সাথে কোনও সংশোধক যোগ করতে পারবেন না। সুতরাং আপনি কার্যকরভাবে তার কার্যকারিতা কিছু বাদ দিয়েছেন।
রবার্ট হার্ভে

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

6
@ 17of26 বিকাশকারী হিসাবে, আমি আবেগের সাথে স্থানীয় ব্যতিক্রমগুলি ঘৃণা করি। উদাহরণস্বরূপ বলার আগে আমাকে প্রতিবারই সেগুলি বন্ধ করতে হবে। সমাধানের জন্য গুগল।
কনরাড মোরাউস্কি

2

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

একটি অতিরিক্ত সুবিধা হ'ল যদি আপনার গ্রাহকরা সি # ব্যবহার করছেন তবে তারা কোড চালানোর আগেই তাদের সম্ভাব্য সমস্যাগুলি সনাক্ত করার জন্য আপনার কোড চুক্তি রেফারেন্স অ্যাসেম্বলিকে সুবিধা দিতে পারে।

কোড চুক্তিগুলির জন্য সম্পূর্ণ ডকুমেন্টেশন এখানে


2

আমি যে কৌশলটি ব্যবহার করি তা হ'ল একত্রিত করা, এবং বৈধতাটিকে আউটসোর্স করা এবং কোনও ইউটিলিটি ফাংশনে পুরোপুরি নিক্ষেপ করা।

একক অতি গুরুত্বপূর্ণ সুবিধা হ'ল এটি ব্যবসায়ের যুক্তিতে এক-লাইনারে নামিয়ে আনা হয়েছে

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

অবশ্যই এটি করার উপায় রয়েছে - দৃ typ়ভাবে টাইপ করা ভাষা, "কোনও অবৈধ অবজেক্টগুলিকে আর অনুমতি দেওয়া হয়নি" ডিজাইন, চুক্তি অনুসারে নকশা ইত্যাদি,

উদাহরণ:

internal static class ValidationUtil
{
    internal static void ThrowIfRectNullOrInvalid(int imageWidth, int imageHeight, Rect rect)
    {
        if (rect == null)
        {
            throw new ArgumentNullException("rect");
        }
        if (rect.Right > imageWidth || rect.Bottom > imageHeight || MoonPhase.Now == MoonPhase.Invisible)
        {
            throw new ArgumentException(
                message: "This is uselessly informative",
                paramName: "rect");
        }
    }
}

public class Thing
{
    public void DoSomething(Rect rect)
    {
        ValidationUtil.ThrowIfRectNullOrInvalid(_imageWidth, _imageHeight, rect);
        // rest of your code
    }
}

1

[দ্রষ্টব্য] আমি মন্তব্য থেকে প্রশ্নটি উত্তর থেকে অনুলিপি করেছি।

বিন্যাসের প্রয়োজন হয় এমন কোনও যুক্তি গ্রহণ করে প্রতিটি ব্যতিক্রম শ্রেণীর কোনও পদ্ধতিতে সরান।

private Exception EmptyConstructor()
{
    string errMsg = string.Format(
          "Construction of Action Argument: {0}, via the empty constructor worked, but type: {1} could not be cast to type {2}.",
          ParameterInfo.Name,
          ParameterInfo.ParameterType,
          typeof(IParameter)
    );

    return new InvalidOperationException(errMsg);
}

সমস্ত ব্যতিক্রম পদ্ধতিগুলি অঞ্চলে সংযুক্ত করুন এবং এটিকে শ্রেণীর শেষে রাখুন।

পেশাদাররা:

  • পদ্ধতির মূল যুক্তিটির বাইরে বার্তাটি রাখে
  • প্রতিটি বার্তায় যুক্তি সম্পর্কিত তথ্য যুক্ত করার অনুমতি দেয় (আপনি পদ্ধতিতে তর্ক করতে পারেন)

কনস:

  • পদ্ধতি বিশৃঙ্খলা। সম্ভবত আপনার প্রচুর পদ্ধতি থাকতে পারে যা কেবল ব্যতিক্রমগুলি ফিরিয়ে দেয় এবং ব্যবসায়ের যুক্তির সাথে সত্যই সম্পর্কিত নয়।
  • অন্যান্য ক্লাসে বার্তাগুলি পুনরায় ব্যবহার করতে পারবেন না

আমি মনে করি আপনি যে বিয়োগগুলি উল্লেখ করেছেন সেগুলি সুবিধার চেয়ে অনেক বেশি।
নিওন্টাপির

@ এনটাপির সর্বদাই সহজেই সম্বোধন করা হবে। সহায়ক পদ্ধতিগুলিকে ইনটেনশনরিভেলিংনাম দেওয়া উচিত এবং কিছুতে গ্রুপ করা উচিত #region #endregion(যার ফলে তাদের ডিফল্টরূপে আইডিই থেকে গোপন করা যায়), এবং যদি তারা বিভিন্ন শ্রেণি জুড়ে প্রযোজ্য হয় তবে সেগুলি একটি internal static ValidationUtilityশ্রেণিতে রাখুন। বিটিডব্লিউ, কোনও সি # প্রোগ্রামারের সামনে দীর্ঘ শনাক্তকারী নামগুলির বিষয়ে কখনও অভিযোগ করবেন না।
রোবং

যদিও অঞ্চলগুলির সম্পর্কে আমি অভিযোগ করব। আমার মনে হয়, আপনি যদি নিজেকে অঞ্চলগুলিতে অবলম্বন করতে চান তবে ক্লাসটির সম্ভবত অনেক বেশি দায়িত্ব ছিল।
নিউন্টাপির

0

আপনি যদি আরও কিছু সাধারণ ত্রুটিগুলি থেকে দূরে সরে যেতে পারেন তবে আপনি আপনার জন্য একটি সর্বজনীন স্ট্যাটিক জেনেরিক কাস্ট ফাংশন লিখতে পারেন যা উত্সের ধরণের অনুমান করে:

public static I CastOrThrow<I,T>(T t, string source)
{
    if (t is I)
        return (I)t;

    string errMsg = string.Format(
          "Failed to complete {0}, because type: {1} could not be cast to type {2}.",
          source,
          typeof(T),
          typeof(I)
        );

    throw new InvalidOperationException(errMsg);
}


/// and then:

var interfaceInstance = SdkHelper.CastTo<IParameter>(passedObject, "Action constructor");

বিভিন্ন সম্ভাবনা রয়েছে (মনে করুন SdkHelper.RequireNotNull()), যা কেবল ইনপুটগুলির প্রয়োজনীয়তাগুলি পরীক্ষা করে এবং যদি তারা ব্যর্থ হয় তবে নিক্ষেপ করে, তবে এই উদাহরণে ফলাফল তৈরির সাথে কাস্টের সংমিশ্রণ হ'ল স্ব-দস্তাবেজ এবং কমপ্যাক্ট।

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


এটি কাস্টিংয়ের এই নির্দিষ্ট উদাহরণ সম্পর্কে নয়, সাধারণভাবে ব্যতিক্রম ছোঁড়া ব্যতিক্রম সম্পর্কে (এবং কোনও কোড ব্যতীত কতটা ব্যতিক্রমী তথ্য পরিচালনা করে তা সম্পর্কে) more
ফ্রেন্ডলিগুই

0

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

/// <summary>
/// This enum is used to identify each business rule uniquely.
/// </summary>
public enum BusinessRuleId {

    /// <summary>
    /// Indicates that a valid body weight value of a patient is missing for dose calculation.
    /// </summary>
    [Display(Name = @"DoseCalculation_PatientBodyWeightMissing")]
    PatientBodyWeightMissingForDoseCalculation = 1,

    /// <summary>
    /// Indicates that a valid body height value of a patient is missing for dose calculation.
    /// </summary>
    [Display(Name = @"DoseCalculation_PatientBodyHeightMissing")]
    PatientBodyHeightMissingForDoseCalculation = 2,

    // ...
}

[Display(Name = "...")]বৈশিষ্ট্যাবলী রিসোর্স কী ত্রুটি বার্তা অনুবাদ করতে ব্যবহার করা ফাইল নির্ধারণ করুন।

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

ব্যবসায়িক বিধিগুলি পরীক্ষা করা বিশেষায়িত ভ্যালিডেটর শ্রেণিতে নিযুক্ত করা যেতে পারে যা লঙ্ঘিত ব্যবসায়িক বিধিগুলির তালিকা সরবরাহ করে।

এরপরে লঙ্ঘিত নিয়মগুলি পরিবহনের জন্য আমরা একটি কাস্টম ব্যতিক্রমের প্রকারটি ব্যবহার করি:

[Serializable]
public class BusinessLogicException : Exception {

    /// <summary>
    /// The Business Rule that was violated.
    /// </summary>
    public BusinessRuleId ViolatedBusinessRule { get; set; }

    /// <summary>
    /// Optional: additional parameters to be used to during generation of the error message.
    /// </summary>
    public string[] MessageParameters { get; set; }

    /// <summary>
    /// This exception indicates that a Business Rule has been violated. 
    /// </summary>
    public BusinessLogicException(BusinessRuleId violatedBusinessRule, params string[] messageParameters) {
        ViolatedBusinessRule = violatedBusinessRule;
        MessageParameters = messageParameters;
    }
}

ব্যাকএন্ড পরিষেবা কলগুলি জেনেরিক ত্রুটি হ্যান্ডলিং কোডে মোড়ানো থাকে যা লঙ্ঘিত বুসিনস বিধিটিকে ব্যবহারকারীর পাঠযোগ্য ত্রুটি বার্তায় অনুবাদ করে:

public object TryExecuteServiceAction(Action a) {
    try {
        return a();
    }
    catch (BusinessLogicException bex) {
        _logger.Error(GenerateErrorMessage(bex));
    }
}

public string GenerateErrorMessage(BusinessLogicException bex) {
    var translatedError = bex.ViolatedBusinessRule.ToTranslatedString();
    if (bex.MessageParameters != null) {
        translatedError = string.Format(translatedError, bex.MessageParameters);
    }
    return translatedError;
}

এখানে এটির ToTranslatedString()জন্য একটি এক্সটেনশন পদ্ধতিটি বৈশিষ্ট্যগুলি enumথেকে রিসোর্স কীগুলি পড়তে [Display]এবং ResourceManagerএই কীগুলি অনুবাদ করতে ব্যবহার করতে পারেন। নিজ নিজ সম্পদ কী-এর জন্য মান জন্য প্লেসহোল্ডার ধারণ করতে পারে string.Format, যা এটি মেলে MessageParameters। রেজেক্স ফাইলটিতে প্রবেশের উদাহরণ:

<data name="DoseCalculation_PatientBodyWeightMissing" xml:space="preserve">
    <value>The dose can not be calculated because the body weight observation for patient {0} is missing or not up to date.</value>
    <comment>{0} ... Patient name</comment>
</data>

ব্যবহারের উদাহরণ:

throw new BusinessLogicException(BusinessRuleId.PatientBodyWeightMissingForDoseCalculation, patient.Name);

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


0

আমি এই উদাহরণ হিসাবে গার্ড ক্লজগুলি ব্যবহার করব যাতে প্যারামিটার চেকগুলি পুনরায় ব্যবহার করা যায়।

এছাড়াও, আপনি বিল্ডার প্যাটার্নটি ব্যবহার করতে পারেন যাতে একাধিক বৈধতা বেঁধে রাখা যায়। এটি কিছুটা সাবলীল দৃ .়তার মতো দেখায় ।

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