কেবলমাত্র একটি ভেরিয়েবলের সুযোগ কমিয়ে আনার জন্য কী ব্লক তৈরি করা কি বোধগম্য?


38

আমি জাভাতে একটি প্রোগ্রাম লিখছি যেখানে এক পর্যায়ে আমার কীস্টোরের জন্য আমার একটি পাসওয়ার্ড লোড করা দরকার। কেবল মজাদার জন্য, আমি জাভায় নিজের পাসওয়ার্ডটি যতটা সম্ভব সংক্ষিপ্ত করে রাখার চেষ্টা করেছি:

//Some code
....

KeyManagerFactory keyManager = KeyManagerFactory.getInstance("SunX509");
Keystore keyStore = KeyStore.getInstance("JKS");

{
    char[] password = getPassword();
    keyStore.load(new FileInputStream(keyStoreLocation), password);
    keyManager.init(keyStore, password);
}

...
//Some more code

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

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

এমন কোনও ঘটনা রয়েছে যেখানে কেবল পরিবর্তনশীল সুযোগ কমিয়ে আনার জন্য ব্লক ব্যবহার করা কী বোঝাপড়া করে ?


13
@ জাগান .... কি? এমনকি আমি জানি না যে আমার প্রশ্নটি কীভাবে সেই দ্বিগুণ টার্গেটের সাথে কম মিল হতে পারে edit এর কোন অংশ আপনাকে এই প্রশ্নগুলি একই বলে বিশ্বাস করতে পরিচালিত করেছিল?
লর্ড ফারকোয়াড

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

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


4
@ প্রশ্ন এই প্রশ্নটি কেন খোলা? এটা তোলে বিস্তৃত জিনিষ আমি করেছি এক কি কখনো দেখিনি। এটি কি কোনও প্রামাণিক প্রশ্নের চেষ্টা?
jpmc26

উত্তর:


34

প্রথমে অন্তর্নিহিত যান্ত্রিকদের সাথে কথা বলছি:

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

সি / সি ++ সংকলক স্থানীয়দের জন্য স্ট্যাক স্টোরেজ স্পেসটি পুনরায় ব্যবহার করতে পারে যা ব্যবহারের আজীবন দ্বন্দ্ব না করে (এটি সাধারণত সুযোগের চেয়ে খাঁটি, খ / সি এর চেয়ে সঠিক যা এটি নির্ধারণ করতে প্রকৃত কোডের বিশ্লেষণ ব্যবহার করে!)।

আমি সি / সি ++ বি / সি জাভার সিনট্যাক্স, অর্থাত্ কোঁকড়া ধনুর্বন্ধনী এবং স্কোপিংয়ের উল্লেখ করি, কমপক্ষে সেই পরিবার থেকে প্রাপ্ত অংশ is এবং কারণ C ++ প্রশ্ন মন্তব্যে এসেছিল।

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

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

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

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

প্রোগ্রামার সুবিধার সাথে কথা বললে, আমি অন্যের সাথে একমত হতে চাই যে একটি (ব্যক্তিগত) পদ্ধতি কেবল একবার ব্যবহার করা হলেও একটি ভাল নির্মাণ is

তবুও, নামগুলি ডিকনফ্লিক্ট করতে এটি ব্যবহার করে সত্যই কোনও ভুল নেই।

আমি বিরল পরিস্থিতিতে এটি করেছি যখন পৃথক পদ্ধতিগুলি তৈরি করা বোঝা। উদাহরণস্বরূপ, switchলুপের মধ্যে একটি বৃহত্তর স্টেটমেন্ট ব্যবহার করে দোভাষী লিখতে গিয়ে আমি caseপ্রতিটি ক্ষেত্রে আলাদা পদ্ধতি তৈরির পরিবর্তে পৃথক কেসগুলিকে একে অপরের থেকে আরও পৃথক রাখতে প্রতিটিটির জন্য একটি পৃথক ব্লক প্রবর্তন করতে পারি might যা কেবল একবারই আহবান করা হয়েছে)।

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


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

1
@ এরিকইডট আমি "সি / সি ++" বলার সমস্যাটির দিকে দৃষ্টি আকর্ষণ করার চেষ্টা করছিলাম যদিও এটি আসলে "জিনিস" ছিল তবে এটি নয়: "সি / সি ++ এর জন্য রানটাইমটিতে সাধারণত সংকলক একটি স্ট্যাক ফ্রেম বরাদ্দ করবে পদ্ধতির জন্য যা প্রয়োজন যতটা বড় " তবে সি এর কোনও পদ্ধতি নেই। এটির কার্যকারিতা রয়েছে। এগুলি আলাদা, বিশেষত সি ++ এ।
tchrist

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

1
সর্বোপরি সংকলক স্থানীয় ভেরিয়েবল স্লটগুলি পুনরায় ব্যবহার করতে পারে, তবে (সি / সি ++ এর বিপরীতে) কেবল যদি তাদের ধরণ একই হয়। ”কেবল ভুল। বাইটকোড স্তরে, স্থানীয় ভেরিয়েবলগুলি আপনি যা চান তার সাথে নিয়োগ ও পুনর্নির্দিষ্ট করতে পারেন, কেবলমাত্র সীমাবদ্ধতা হ'ল পরবর্তী ব্যবহারটি সর্বশেষতম নির্ধারিত আইটেমের ধরণের সাথে সামঞ্জস্যপূর্ণ। স্থানীয় পরিবর্তনশীল স্লট পুনঃব্যবহার আদর্শ, সঙ্গে যেমন হয় { int x = 42; String s="blah"; } { long y = 0; }, longভেরিয়েবলের স্লট পুনরায় ব্যবহার করতে হবে উভয় , ভেরিয়েবল xএবং sসব সাধারণভাবে ব্যবহৃত কম্পাইলার (সঙ্গে javacএবং ecj)।
হোলার

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

27

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


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

16
@ রাবারডাক সত্য, তবে সেই ক্ষেত্রে আমাদের বাকিদের কখনই এটি দেখা উচিত নয়, তাই আমরা যা ভাবি তা বিবেচনা করে না। একজন প্রাপ্তবয়স্ক কোডার এবং একটি সম্মতিসূচক সংকলক তাদের নিজস্ব ঘনক্ষেত্রের গোপনীয়তায় কীভাবে উঠে যায় তা অন্য কারোরই উদ্বেগ নয়।
candied_orange

@ প্রচারিত_আরঞ্জ আমি আশঙ্কা করি আমি এটি না পেয়ে যাব :( বিস্তৃত করার যত্ন
নিচ্ছেন

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

@ ক্যান্ডিড_আরঞ্জ ওহ, আপনি ভাবছিলেন যে আপনি তর্ক করছেন এবং রাবারডাকের যুক্তিটি প্রসারিত করবেন না।
ডাবলআর্ট

17

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

একটি ক্ষেত্রে আছে যেখানে আমি এটি দরকারী মনে করি - একটি switchবিবৃতিতে! কখনও কখনও আপনি একটিতে চলক ঘোষণা করতে চান case:

switch (op) {
    case ADD:
        int result = a + b;
        System.out.printf("%s + %s = %s\n", a, b, result);
        break;
    case SUB:
        int result = a - b;
        System.out.printf("%s - %s = %s\n", a, b, result);
        break;
}

এটি তবে ব্যর্থ হবে:

error: variable result is already defined in method main(String[])
            int result = a - b;

switch বিবৃতিগুলি অদ্ভুত - এগুলি নিয়ন্ত্রণের বিবৃতি, তবে তাদের পতনের কারণে তারা স্কোপগুলি প্রবর্তন করে না।

সুতরাং - আপনি নিজে স্কোপগুলি তৈরি করতে কেবল ব্লকগুলি ব্যবহার করতে পারেন:

switch (op) {
    case ADD: {
        int result = a + b;
        System.out.printf("%s + %s = %s\n", a, b, result);
    } break;
    case SUB: {
        int result = a - b;
        System.out.printf("%s - %s = %s\n", a, b, result);
    } break;
}

6
  • সাধারণ ক্ষেত্রে:

এমন কোনও ঘটনা রয়েছে যেখানে কেবল পরিবর্তনশীল সুযোগ কমিয়ে আনার জন্য ব্লক ব্যবহার করা কী বোঝাপড়া করে?

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

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

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

এটি বোধগম্য হতে পারে তবে এটি খুব বিরল।

  • আপনার ব্যবহারের কেস:

আপনার কোডটি এখানে:

KeyManagerFactory keyManager = KeyManagerFactory.getInstance("SunX509");
Keystore keyStore = KeyStore.getInstance("JKS");

{
    char[] password = getPassword();
    keyStore.load(new FileInputStream(keyStoreLocation), password);
    keyManager.init(keyStore, password);
}

আপনি একটি তৈরি করছেন FileInputStreamতবে আপনি কখনই এটি বন্ধ করছেন না।

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

KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
Keystore keyStore = KeyStore.getInstance("JKS");

try (InputStream fis = new FileInputStream(keyStoreLocation)) {
    char[] password = getPassword();
    keyStore.load(fis, password);
    keyManager.init(keyStore, password);
}

(এটি প্রায়শই এর getDefaultAlgorithm()পরিবর্তে ব্যবহারের মাধ্যমে প্রায়শই ভাল SunX509)

তদ্ব্যতীত, কোডগুলির অংশগুলি পৃথক পদ্ধতিতে পৃথক করার পরামর্শটি সাধারণত কার্যকর। এটি মাত্র ৩ টি লাইনের জন্য খুব কমই মূল্যবান (যদি এমন কিছু হয় তবে এটি একটি পৃথক পদ্ধতি তৈরি করে পাঠযোগ্যতায় বাধা সৃষ্টি করে)।


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

2

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

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

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

অতিমাত্রায় ব্যবহারের পদ্ধতিগুলির জন্য কোনও পরামর্শ নয়

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

আরও ন্যূনতম স্কোপগুলি আরও কমাতে চেষ্টা করা

যদি স্থানীয় ভেরিয়েবল স্কোপগুলি পরম সর্বনিম্নে হ্রাস করা সার্থক হয় তবে এই জাতীয় কোডের বৃহত্তর গ্রহণযোগ্যতা থাকতে হবে:

ImageIO.write(new Robot("borg").createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())), "png", new File(Db.getUserId(User.handle()).toString()));

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

আর কিছুই না হলে, পুরো জায়গাজুড়ে বেনামে ব্লক ব্যবহার করা বহিরাগত, মূর্খবাদী নয় এবং বহিরাগত কোডগুলি কয়েক বছর পরে নিজে না হলে অন্যরা ঘৃণা করার ঝুঁকি বহন করে।

ব্যাপ্তি হ্রাস করার ব্যবহারিক কার্যকারিতা

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


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

2

এমন কোনও ঘটনা রয়েছে যেখানে কেবল পরিবর্তনশীল সুযোগ কমিয়ে আনার জন্য ব্লক ব্যবহার করা কী বোঝাপড়া করে?

আমি মনে করি যে অনুপ্রেরণা একটি ব্লক প্রবর্তনের যথেষ্ট কারণ, হ্যাঁ।

ক্যাসি যেমন উল্লেখ করেছেন, ব্লকটি একটি "কোড গন্ধ" যা আপনাকে বোঝায় যে কোনও ফাংশনে ব্লকটি বের করা আপনার পক্ষে আরও ভাল। তবে আপনি নাও পারেন।

জন কারমার্ক ইনলাইনড কোডে 2007 সালে একটি মেমো লিখেছিলেন His

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

সুতরাং ভাবুন , উদ্দেশ্য নিয়ে একটি পছন্দ করুন, এবং (alচ্ছিক) আপনি যে পছন্দ করেছেন তার প্রেরণার বর্ণনা দিয়ে প্রমাণ রেখে যান।


1

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

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

{
    char[] password = getPassword();
    try{
        keyStore.load(new FileInputStream(keyStoreLocation), password);
        keyManager.init(keyStore, password);
    }finally{
        Arrays.fill(password, '\0');
    }
}

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

এর কারণ হ'ল ভেরিয়েবলটি আর বৈধ নয়। আপনি এটি তৈরি করেছেন, ব্যবহার করেছেন এবং কোনও অর্থবহ তথ্য না থাকার জন্য তার অবস্থাটিকে অকার্যকর করেছেন। এই ব্লকের পরে পরিবর্তনশীলটি ব্যবহার করার কোনও অর্থ নেই, সুতরাং এটির সুযোগটি যুক্তিযুক্ত reasonable

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

{
    MethodBuilder m_ToString = tb.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, typeofString, Type.EmptyTypes);
    var il = m_ToString.GetILGenerator();
    il.Emit(OpCodes.Ldstr, templateType.ToString()+":"+staticType.ToString());
    il.Emit(OpCodes.Ret);
    tb.DefineMethodOverride(m_ToString, m_Object_ToString);
}
{
    PropertyBuilder p_Class = tb.DefineProperty("Class", PropertyAttributes.None, typeofType, Type.EmptyTypes);
    MethodBuilder m_get_Class = tb.DefineMethod("get_Class", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, typeofType, Type.EmptyTypes);
    var il = m_get_Class.GetILGenerator();
    il.Emit(OpCodes.Ldtoken, staticType);
    il.Emit(OpCodes.Call, m_Type_GetTypeFromHandle);
    il.Emit(OpCodes.Ret);
    p_Class.SetGetMethod(m_get_Class);
    tb.DefineMethodOverride(m_get_Class, m_IPattern_get_Class);
}

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

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

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