অস্থায়ী ভেরিয়েবল বনাম লাইন দৈর্ঘ্যের প্রয়োজনীয়তা


10

আমি মার্টিন ফোলারের রিফ্যাক্টরিং পড়ছি । এটি সাধারণত দুর্দান্ত তবে ফাউলারের একটি প্রস্তাবনা কিছুটা সমস্যা সৃষ্টি করছে বলে মনে হয়।

ফওলার পরামর্শ দেয় আপনি অস্থায়ী ভেরিয়েবলগুলি কোনও ক্যোয়ারির সাথে প্রতিস্থাপন করুন, সুতরাং এর পরিবর্তে:

double getPrice() {
    final int basePrice = _quantity * _itemPrice;
    final double discountFactor;
    if (basePrice > 1000) discountFactor = 0.95;
    else discountFactor = 0.98;
    return basePrice * discountFactor;
}

আপনি একটি সহায়ক পদ্ধতিতে টানুন:

double basePrice() {
    return _quantity * _itemPrice;
}

double getPrice() {
    final double discountFactor;
    if (basePrice() > 1000) discountFactor = 0.95;
    else discountFactor = 0.98;
    return basePrice() * discountFactor;
}

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

$host = 'https://api.twilio.com';
$uri = "$host/2010-04-01/Accounts/$accountSid/Usage/Records/AllTime";
$response = Api::makeRequest($uri);

যদি আমি এটি সন্ধানের চেষ্টা করি, তবে রেখাটি 80 টি অক্ষরের বেশি হবে।

পর্যায়ক্রমে আমি কোডের চেইনগুলি দিয়ে শেষ করি যা এগুলি এত সহজে পড়তে পারা যায় না:

$params = MustacheOptions::build(self::flattenParams($bagcheck->getParams()));

দুটি মিলনের জন্য কিছু কৌশল কী?


10
৮০ টি চরিত্র আমার মনিটরের 1 / তৃতীয় প্রায়। আপনি কি নিশ্চিত যে 80 টি চর লাইনে লেগে থাকা এখনও আপনার পক্ষে সার্থক?
জে কে।


আপনার $hostএবং $uriউদাহরণটি একধরণের সংশ্লেষিত, যদিও - হোস্টটি যদি কোনও সেটিং বা অন্য ইনপুট থেকে না পড়া হত তবে আমি তাদের একই লাইনে থাকতে পছন্দ করতাম, এমনকি এটি মোড়ানো বা প্রান্তটি বন্ধ হয়ে গেলেও।
ইজকাটা

5
এত কৌতুকপূর্ণ হওয়ার দরকার নেই। বইটি এমন কৌশলগুলির একটি তালিকা যা তারা যখন সহায়তা করে তখন ব্যবহার করা যেতে পারে, আপনি সর্বত্র, প্রতিবার প্রয়োগ করতে হবে এমন নিয়মের একটি সেট নয়। মুল বক্তব্যটি হ'ল আপনার কোডটি আরও রক্ষণাবেক্ষণযোগ্য এবং পড়া সহজ। যদি কোনও রিফ্যাক্টর এটি না করে তবে আপনি এটি ব্যবহার করবেন না।
শান ম্যাকসোমিংথ

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

উত্তর:


16

কীভাবে
1. লাইন দৈর্ঘ্যের সীমাবদ্ধতা বিদ্যমান তাই আপনি + আরও কোড বুঝতে পারবেন । তারা এখনও বৈধ।
২. অন্ধ সম্মেলনের বিষয়ে রায়কে জোর দিন ।
৩. পারফরম্যান্সের জন্য অনুকূল না হওয়া পর্যন্ত টেম্প ভেরিয়েবলগুলি এড়িয়ে চলুন ।
৪. বহু-লাইন স্টেটমেন্টগুলিতে প্রান্তিককরণের জন্য গভীর ইন্ডেন্টেশন ব্যবহার করা এড়িয়ে চলুন।
5. ধারণার সীমানা বরাবর একাধিক লাইনে দীর্ঘ বিবৃতি ভাঙ্গা :

// prefer this
var distance = Math.Sqrt(
    Math.Pow(point2.GetX() - point1.GetX(), 2) + // x's
    Math.Pow(point2.GetY() - point1.GetY(), 2)   // y's
);

// over this
var distance = Math.Sqrt(Math.Pow(point2.GetX() -
    point1.GetX(), 2) + Math.Pow(point2.GetY() -
    point1.GetY(), 2)); // not even sure if I typed that correctly.

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

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

আপনি যে উদাহরণগুলি দিয়েছেন (জাভা এবং ... পিএইচপি?) উভয়ই বহু-লাইন স্টেটমেন্টের অনুমতি দেয়। লাইনগুলি দীর্ঘ হয়ে গেলে সেগুলি ভেঙে দিন। Jquery উত্স এটিকে চরমপন্থায় নিয়ে যায়। (প্রথম বিবৃতিটি line৯ লাইনের দিকে চলে!) এটি নয় যে আমি অগত্যা একমত হই, তবে টেম্প ভার্স ব্যবহার না করে আপনার কোডকে পাঠযোগ্য করে তোলার আরও অন্যান্য উপায় রয়েছে।

কয়েকটি উদাহরণ
1. পাইথ 8 পাইথনের জন্য স্টাইল গাইড (সবচেয়ে সুন্দর উদাহরণ নয়)
২. পিয়র স্টাইল গাইডের উপর পল এম জোন্স (রাস্তার যুক্তির মাঝখানে)
৩. ওরাকল লাইনের দৈর্ঘ্য + মোড়ানোর কনভেনশন (80 টি অক্ষরে রাখার জন্য দরকারী স্ট্রেটেজ)
৪. এমডিএন জাভা অনুশীলনগুলি (সম্মেলনের বিষয়ে প্রোগ্রামার রায়কে জোর দেয়)


1
সমস্যার অন্য অংশটি হ'ল একটি অস্থায়ী পরিবর্তনশীল প্রায়শই এর মানকে ছাড়িয়ে যায়। ছোট স্কোপ ব্লকে কোনও সমস্যা নয়, তবে বৃহত্তরগুলির মধ্যে হ্যাঁ, একটি বড় সমস্যা।
রস প্যাটারসন

8
যদি আপনি অস্থায়ীভাবে সংশোধিত হওয়ার বিষয়ে উদ্বিগ্ন হন তবে এটির জন্য একটি চাপ দিন put
থমাস এডিং

3

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

(আমি ভুল হলে আমাকে সংশোধন করুন)


3

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

আপনার পোস্ট করা উদাহরণগুলি আমাকে দেখতে দিন।

$host = 'https://api.twilio.com';
$uri = "$host/2010-04-01/Accounts/$accountSid/Usage/Records/AllTime";
$response = Api::makeRequest($uri);

আমার পর্যবেক্ষণটি হল যে সমস্ত টিভিলিও এপিআই কলগুলি "https://api.twilio.com/2010-04-1/" দিয়ে শুরু হবে এবং এইভাবে একটি খুব সুস্পষ্ট পুনরায় ব্যবহারযোগ্য ফাংশন রয়েছে:

$uri = twilioURL("Accounts/$accountSid/Usage/Records/AllTime")

আসলে, আমি অনুমান করেছি যে ইউআরএল তৈরি করার একমাত্র কারণ হল অনুরোধ করা, তাই আমি করব:

$response = TwilioApi::makeRequest("Accounts/$accountSid/Usage/Records/AllTime")

আসলে, অনেকগুলি ইউআরএল আসলে "অ্যাকাউন্টস / $ অ্যাকাউন্টসিড" দিয়ে শুরু হয়, তাই আমি সম্ভবত এটিও বের করতে পারি:

$response = TwilioApi::makeAccountRequest($accountSid, "Usage/Records/AllTime")

এবং আমরা যদি ট্যালিও এপিআইটিকে এমন একটি অবজেক্ট তৈরি করি যা অ্যাকাউন্ট নম্বর ধারণ করে, তবে আমরা এর মতো কিছু করতে পারি:

$response = $twilio->makeAccountRequest("Usage/Records/AllTime")

একটি $ twilio অবজেক্টটি ব্যবহার করে ইউনিট পরীক্ষা সহজ করার সুবিধা রয়েছে। আমি অবজেক্টটিকে একটি ভিন্ন $ টিউলিও অবজেক্ট দিতে পারি যা আসলে টোলিওতে ফিরে কল করে না, এটি দ্রুত হবে এবং টোলিওতে অদ্ভুত কিছু করবে না।

অন্য একটি তাকান

$params = MustacheOptions::build(self::flattenParams($bagcheck->getParams()));

এখানে আমি উভয় সম্পর্কে চিন্তা করব:

$params = MustacheOptions::buildFromParams($bagcheck->getParams());

অথবা

$params = MustacheOptions::build($bagcheck->getFlatParams());

অথবা

$params = MustacheOptions::build(flatParams($backCheck));

যার উপর নির্ভর করে আরও পুনরায় ব্যবহারযোগ্য আইডিয়াম।


1

আসলে, আমি সাধারণ ক্ষেত্রে এটি নিয়ে বিশিষ্ট মিঃ ফাউলারের সাথে একমত নই।

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

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

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

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

double? _basePrice; //not sure if Java has C#'s "nullable" concept
double basePrice(bool forceCalc)
{
   if(forceCalc || !_basePrice.HasValue)
      return _basePrice = _quantity * _itemPrice;
   return _basePrice.Value;
}

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


1

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

উদাহরণস্বরূপ, আপনার নিজস্ব উদাহরণ উদ্ধৃত:

double getPrice() {
    final double discountFactor;
    if (basePrice() > 1000) discountFactor = 0.95;      <--- first call
    else discountFactor = 0.98;
    return basePrice() * discountFactor;                <--- second call
}

স্পষ্টতই উভয় _quantityএবং _itemPriceবৈশ্বিক চলক (বা কমপক্ষে শ্রেণীর স্তর) এবং সুতরাং তাদের বাইরেও সংশোধন করার সম্ভাবনা রয়েছেgetPrice()

সুতরাং প্রথম কলটি basePrice()দ্বিতীয় কল থেকে আলাদা মান ফেরত পাওয়ার সম্ভাবনা রয়েছে !

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


আপনার এড্রুডাম কমানোর এড়াতে হবে - গণনাটি discountFactorকোনও পদ্ধতিতে বন্ধ করে দেওয়া উচিত ? সুতরাং আপনার উদাহরণটি হয়ে যায়:

double getPrice()
{
    final double basePrice      = calculateBasePrice();
    final double discountFactor = calculateDiscount( basePrice );

    return basePrice * discountFactor;
}

নির্দিষ্ট স্তরের পার্টিশন করা আসলে কোডটি কম পাঠযোগ্য করে তোলে able


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

0

যদি আপনি নামকরণকৃত প্যারামিটারগুলি (অবজেক্টিভ সি, পাইথন, রুবি, ইত্যাদি) কোনও ভাষায় কাজ করতে চান তবে টেম্প ভার্স কম কার্যকর।

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

আপনার মত, যদিও আমি স্পষ্টতা এবং লাইন দৈর্ঘ্যের বিবেচনার জন্য টেম্প ভেরিয়েবলগুলি ব্যবহার করি।

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

$rs = DB::query( $query = "SELECT * FROM table" );
if (DEBUG) echo $query;
// do something with $rs

0

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

নতুন পদ্ধতিটি অন্য পদ্ধতিতে ব্যবহার করা যেতে পারে

    double basePrice = _quantity * _itemPrice;
    if (basePrice > 1000)
        return basePrice * 0.95;
    else
        return basePrice * 0.98;

           http://i.stack.imgur.com/mKbQM.gif

    if (basePrice() > 1000)
        return basePrice() * 0.95;
    else
        return basePrice() * 0.98;
...
double basePrice() {
    return _quantity * _itemPrice;
}

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

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

তারপরে, লাইন দৈর্ঘ্যের ইস্যুটির জন্য, আমি বেশ কয়েকটি বিকল্প দেখতে পাচ্ছি:

  • একটি স্থানীয় ভেরিয়েবল তৈরি করুন uri = archive_request_uri()

যুক্তি: বর্তমান পদ্ধতিতে, আপনি চাইছেন যে ইউআরআই উল্লিখিত হবে। ইউআরআই সংজ্ঞাটি এখনও কার্যকর করা হয়েছে।

  • একটি স্থানীয় পদ্ধতি সংজ্ঞায়িত করুন uri() { return archive_request_uri() }

আপনি যদি প্রায়শই ফোলারের পরামর্শটি ব্যবহার করেন তবে আপনি জানতে পারবেন যে ইউরি () পদ্ধতিটি একই প্যাটার্ন।

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

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