কোডের অভ্যন্তরে পরিবর্তনশীল ব্যবহারকে সাধারণীকরণ করুন


11

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

 Strings querycre,queryins,queryup,querydel; 
    querycre = 'Create table XYZ ...';
    execute querycre ;
    queryins = 'Insert into XYZ ...';
    execute queryins ;
    queryup  = 'Update  XYZ set ...';
    execute queryup;
    querydel = 'Delete from XYZ ...';
    execute querydel ;

এবং

 Strings query; 
    query= 'Create table XYZ ... ';
    execute query ;
    query= 'Insert into XYZ ...';
    execute query ;
    query= 'Update  XYZ set ...';
    execute query ;
    query= 'Delete from XYZ ...';
    execute query ;

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

এছাড়াও অনেকগুলি ভেরিয়েবল থাকা কি আমার অভিনয়কে বাধা দেয়?

পিএস: দয়া করে কোডটি জবাব দেবেন না উদাহরণস্বরূপ এটি কেবলমাত্র আমি যা বলতে চাইছি তা বোঝানো হয়েছিল।


অবশ্যই আপনি একই পরিবর্তনশীলটিকে পুনরায় ব্যবহার করুন ... কারণ আপনি এটি কোনও ফাংশনে সংজ্ঞায়িত করেছেন। এটিই ফাংশনগুলির জন্য।
zzzzBov

উত্তর:


26

নিজেকে এই প্রশ্নটি জিজ্ঞাসা করা একটি বেশ শক্ত গন্ধ যা আপনি ডিআরওয়াই অনুসরণ করছেন না (নিজেকে পুনরাবৃত্তি করবেন না)। মনে করুন আপনার কাছে এটি একটি অনুমানকৃত কোঁকড়ানো-ব্রেস ভাষায় রয়েছে:

function doFoo() {
    query = "SELECT a, b, c FROM foobar WHERE baz = 23";
    result = runQuery(query);
    print(result);

    query = "SELECT foo, bar FROM quux WHERE x IS NULL";
    result = runQuery(query);
    print(result);

    query = "SELECT a.foo, b.bar FROM quux a INNER JOIN quuux b ON b.quux_id = a.id ORDER BY date_added LIMIT 10";
    result = runQuery(query);
    print(result);
}

রিফ্যাক্টর যে এর মধ্যে:

function runAndPrint(query) {
    result = runQuery(query);
    print(result);
}

function doFoo() {
    runAndPrint("SELECT a, b, c FROM foobar WHERE baz = 23");
    runAndPrint("SELECT foo, bar FROM quux WHERE x IS NULL");
    runAndPrint("SELECT a.foo, b.bar FROM quux a INNER JOIN quuux b ON b.quux_id = a.id ORDER BY date_added LIMIT 10");
}

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


2
আমি কেবল DRY নীতি :)
আর্টজম

1
@tdammers একটি ফাংশনের ভিতরে মাত্র 2 লাইন কোড থাকা ভাল? আমার যদি এই ফাংশনটি ডুফু () {মুদ্রণ (রানওয়াইকিয়ারি ("এক্সওয়াইজেড থেকে সেল্টেন্ট এ, বি, সি")) থাকে
কিনা তা বিবেচনা করুন

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

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

1
@ জেমসএন্ডারসন: এটি কিছুটা স্বীকৃত উদাহরণ, তবে এটি একটি বিষয় ব্যাখ্যা করার জন্য কাজ করে। আপনার কাছে কোডের কত লাইন রয়েছে তা নয়। আপনি একই ঘটনাটি কতবার বর্ণনা করেছেন। এটিই ডিআরওয়াই, একই সাথে সত্যের
নীতিটির

14

সাধারণত, এটি একটি খারাপ অভ্যাস।

একটি ভেরিয়েবলের পুনরায় ব্যবহার হ'ল এই উপায়টি এমন কোড তৈরি করতে পারে যা বুঝতে বুঝতে বিভ্রান্ত হয়।

কোডটি পড়ছেন তারা কোনও ভেরিয়েবলকে এভাবে পুনরায় ব্যবহার করার আশা করবেন না এবং জানেন না কেন শুরুতে একটি মান সেট ফাংশনের শেষে আলাদা মান রয়েছে।

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

আপনি যে উদাহরণগুলি দিয়েছেন সেগুলি তাদেরকে ফাংশনগুলিতে আবদ্ধ করার জন্য ndণ দেয়, যেখানে আপনি কোয়েরিতে পাস করে তা সম্পাদন করবেন।


এটির দ্বারা সিস্টেমের কার্য সম্পাদন সম্পর্কে কী প্রভাব ফেলবে?
শিরিশ

@ শিরিশ ১১ - এটি হতে পারে। সংকলক, ভাষা, পরিবেশ এবং অন্যান্য ভেরিয়েবলগুলির উপর নির্ভর করে।
ওদে

সাধারণত, সংকলক এটি অপ্টিমাইজ করা ভাল। তবে এটি সর্বদা সংকলক / প্লেটফর্ম / নির্দিষ্ট কেস / কনফিগারেশনের উপর নির্ভর করে।
ডেডালনিক্স

7

স্ব-ডকুমেন্টেড কোডটি পড়া এবং রক্ষণাবেক্ষণ করা সহজ

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

সঠিকভাবে কাঠামোগত কোডটি (পুনরায়) ব্যবহার করা সহজতর (এভাবে সস্তা)

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

এইভাবে, আপনি কার্যকরভাবে:

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

উদাহরণ:

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

আপনার উদাহরণ 1:

Strings querycre,queryins,queryup,querydel; 
    querycre = 'Create table XYZ ...';
    execute querycre ;
    queryins = 'Insert into XYZ ...';
    execute queryins ;
    queryup  = 'Update  XYZ set ...';
    execute queryup;
    querydel = 'Delete from XYZ ...';
    execute querydel ;

আপনার উদাহরণ 2:

 Strings query; 
    query= 'Create table XYZ ...';
    execute query ;
    query= 'Insert into XYZ ...';
    execute query ;
    query= 'Update  XYZ set ...';
    execute query ;
    query= 'Delete from XYZ ...';
    execute query ;

উদাহরণ 3 (রিফ্যাক্টর সিউডো কোড):

def executeQuery(query, parameters...)
    statement = prepareStatement(query, parameters);
    execute statement;
end

// call point:
executeQuery('Create table XYZ ... ');
executeQuery('Insert into XYZ ...');
executeQuery('Update  XYZ set ...');
executeQuery('Delete from XYZ ...');

নিয়মিত পুনঃব্যবহারের সাথে সুবিধাটি দেখায়।

ব্যক্তিগত উপাখ্যান

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

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

আমার জন্যে ইহাতে কি আছে?

আপনি যদি আপনার সমস্ত ফাংশনের ইনপুটগুলি পরিবর্তনযোগ্য হতে এবং কোনও নতুন ফলাফল (সত্য গাণিতিক ফাংশন হিসাবে) ফেরত দেওয়ার অভ্যাস গ্রহণ করেন তবে আপনি স্টোরগুলি অনুলিপি না করার অভ্যাসে চলে যান।

এক্সটেনশন দ্বারা, এটি বাড়ে:

  • আপনি ছোট ফাংশন লিখছেন,
  • সুনির্দিষ্ট উদ্দেশ্য সহ,
  • যে বুঝতে সহজ হয়,
  • পুনরায় ব্যবহার করার জন্য,
  • প্রসারিত (OO উত্তরাধিকার দ্বারা বা কার্যকরী শৃঙ্খলা দ্বারা),
  • এবং নথি (ইতিমধ্যে স্ব-ডকুমেন্টিং হিসাবে)।

আমি বলছি না যে এখানে পরিবর্তনীয় রাষ্ট্রের কোনও লাভ নেই, আমি কেবল এটিই নির্দেশ করছি যে কীভাবে অভ্যাসটি আপনার উপর বাড়তে পারে এবং কীভাবে এটি কোডের পাঠ্যতাকে প্রভাবিত করে।


2

কোড ডিজাইনের শর্তাবলী

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

for currentQuery in queries:
    execute query;

স্বাভাবিকভাবেই একটি লুপ রয়েছে তাই আপনাকে একটি পরিবর্তনশীল পুনরায় ব্যবহার করতে হবে , তবে লুপ না থাকলেও এটি ঠিক ছিল। মানটির অর্থ যদি একই জিনিস না হয় তবে পৃথক ভেরিয়েবল ব্যবহার করুন।

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

পারফরম্যান্সের শর্তাবলী

এটি ব্যবহৃত ভাষা, সংকলক (গুলি) এবং রানটাইম সিস্টেম (গুলি) এর উপর নির্ভর করে, তবে সাধারণভাবে কোনও পার্থক্য হওয়া উচিত নয় - স্ট্যাক-ভিত্তিক রেজিস্টার মেশিনগুলির জন্য বিশেষ সংকলকগুলিতে (জনপ্রিয় x86 / x86-64 এর মতো) যাইহোক কেবল ঠিক থাকবে যে কোনও ফ্রি স্ট্যাক মেমরি ব্যবহার করুন বা অ্যাসাইনমেন্ট টার্গেট হিসাবে তারা পারেন নিবন্ধন করুন, আপনি একই পরিবর্তনশীল চান কিনা তা সম্পূর্ণ উপেক্ষা করে ignoring

উদাহরণস্বরূপ, gcc -O2ঠিক একই বাইনারি তৈরি করে, এবং আমি জানি কেবলমাত্র পারফরম্যান্সের পার্থক্যটি সংকলনের সময় প্রতীক টেবিলের আকার - আপনি 60 এর দশকে সময় না পেলে সম্পূর্ণরূপে তুচ্ছ।

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


0

আমি ভেরিয়েবল পুনরায় ব্যবহার করা বেশিরভাগ সময় ঠিক আছে বলে মনে করি।

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


-1

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


আমি কেবল একটি সহজ উদাহরণ দিয়েছি যাতে পাঠকদের পক্ষে আমি কী চাই তা বোঝা সহজ। আমার কোডটি এর চেয়ে অনেক বেশি জটিল।
শিরীশ

-2

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

{
    String query = 'Create table XYZ ...';
    execute query;
}
{
    String query = 'Insert table XYZ ...';
    execute query;
}
And so on...

(এই মুহুর্তে, আমি টিডামারদের সমাধান বিবেচনা করতে পারি ))

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

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


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

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

@ হাইলেম: আপনি এবং টিডামার উভয়ই সঠিক সমাধান দেবেন। আমি শুধু মনে করি এটি কিছু ক্ষেত্রে ওভারকিল হতে পারে।
রাল্ফচাপিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.