স্ট্রিং হিসাবে নির্দিষ্ট মান সংরক্ষণ করা কি খারাপ অভ্যাস?


19

এটি একটি খুব অস্পষ্ট শিরোনাম তবে আমি এটি শব্দটির আরও ভাল উপায়ের কথা ভাবতে পারি নি। তবে, যেমন একটি উদাহরণ হিসাবে, গেমের কোনও চরিত্র যে দিকে এগিয়ে চলেছে সে সম্পর্কে চিন্তা করুন a স্ট্রিংটি ব্যবহার করা এবং তার মতো জিনিসগুলি করা কোনও ধরনের ভুল অনুভব করে if(character.direction == "left")। আমার কাছে মনে হয় এটি নিরীহ ত্রুটির জন্য খুব বেশি জায়গা ছেড়ে যায়, যেমন দুর্ঘটনাক্রমে ব্যবহার করা Leftবা lতার পরিবর্তে যা কিছু left। আমার সন্দেহ কি সঠিক? যদি তা হয় তবে এরকম কিছু অর্জনের পছন্দের উপায়টি কী?


10
আপনার মানে, enums ছাড়াও যদি আপনার ভাষা সেগুলি সমর্থন করে?
হফমলে



কিছু ভাষা স্ট্রিং, উদাহরণস্বরূপ, ছাড়া অন্য মান সংরক্ষণ করতে সক্ষম হয় না bash
mouviciel

কেন জানি না তবে আমি
সিতে

উত্তর:


28

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

public enum Direction {
    LEFT,
    RIGHT,
    UP,
    DOWN
}

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

12

কোডে আক্ষরিক স্ট্রিং (বা ম্যাজিক নম্বর) ব্যবহার করা ভয়ানক অনুশীলন।

এনামগুলি ভাল, বা খুব কম ব্যবহারের ধ্রুবক (অবশ্যই এক বা একাধিক সম্পর্কিত ধ্রুবকগুলির জন্য এনামগুলি কেবল একটি মোড়কের ধরণ)।

const string LEFT = "left"
if (someThing == LEFT) { doStuff(); }

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

এখানে একটি দ্রুত রেফ, আমি নিশ্চিত যে আরও কয়েক আরও রয়েছে: /programming/47882/ কি-is-a-magic-number-and-w--is-it- bad


1
এই পদ্ধতির সাথে আমার যে সমস্যাটি হচ্ছে তা হ'ল আপনি --const স্ট্রিং লেফট = "লেফ" এর মতো টাইপো-বাগ পান - তবে আপনি যদি এনামগুলি নিয়ে কাজ করেন যা সংকলনের সময় ধরা পড়ে।
পিটার বি

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

3
উইকএন্ডের দিনগুলি "s" দিয়ে শুরু হওয়া দিনগুলিকে নির্ধারিত করে এমন একটি অ্যাপ্লিকেশন নিয়ে কাজ করে আমার খুব আনন্দ হয়েছে। তারা "সত্য" সম্পর্কে খুব অবাক হয়েছিল যে তারা যখন অ্যাপ্লিকেশনটিকে আন্তর্জাতিককরণ করেছিল যে ফ্রান্সের একদিনের সপ্তাহান্ত ছিল কেবল।
পিটার বি

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

4

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

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

left = "left";

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

if (player.direction == Left)

একটি সংকলন-সময় ত্রুটি (সেরা কেস, জাভা এবং এ জাতীয়) হিসাবে সনাক্ত করা হবে বা কোনও আইডিই দ্বারা এর বিটকে ভুল হিসাবে চিহ্নিত করা হবে (সবচেয়ে খারাপ কেস, বেসিক এবং এ জাতীয়)।

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

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

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


2

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

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

যেমনটি প্রস্তাবিত হয়েছে, আপনার ভাষা যদি অনুমতি দেয় তবে গণনাগুলি ব্যবহার করুন। আপনার নির্দিষ্ট উদাহরণে এটি পরিষ্কারভাবে আরও ভাল পছন্দ।


গতি এবং স্মৃতিশক্তি গুরুত্বহীন। এটি বলেছিল, এনাম বা ধ্রুবক পছন্দ করুন prefer স্ট্রিংগুলি আরও বোধগম্য হয় যদি ডেটা কোনও টেক্সট ফর্ম্যাট থেকে আসে, যেমন এক্সএমএল, তবে তারপরে সমস্ত ক্যাপ বা সমস্ত ক্যাপের সাথে সামঞ্জস্য থাকে। বা, সর্বদা রূপান্তর , ই জি। if (uppercase(foo) == "LEFT")
user949300

2
@ ব্যবহারকারী949300 স্ট্রিংগুলি সমস্ত বড় হাতের বা সমস্ত ছোট হাতের কাছে রূপান্তর করা নির্ভরযোগ্য নয়। সম্ভাবনা আছে যে কেউ তুরস্কের মতো অন্য কোনও স্থানীয় (বা সেখানে ব্যবসায় প্রসারিত) দেখার এবং নির্লজ্জ উপরের কেসিং (বা লোয়ার কেসিং) স্ট্রিংয়ের তুলনা ভাঙার সিদ্ধান্ত নিতে পারে ।
বিট্রি

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

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

1

আপনার পরিস্থিতি অনুধাবন করে এমন ডেটা টাইপ ব্যবহার করুন।

stringঅন্তর্নিহিত আন্ত / আন্ত-অ্যাপ্লিকেশন যোগাযোগ হিসাবে প্রকারের ব্যবহার অভ্যন্তরীণ কোনও সমস্যা নয়। আসলে, কখনও কখনও স্ট্রিংগুলি ব্যবহার করা ভাল : এটি আপনার এপিআই ব্যবহার করে শিখতে এবং ডিবাগ করা সহজ করে তোলে।

আপনার কোডের সাথে আসল সমস্যাটি মানটির পুনরাবৃত্তি করতে পারে।

এটি করবেন না:

if (direction == 'left') {
  goLeft();
}

আপনি যদি এই শর্তসাপেক্ষে বা অন্য কোথাও "বাম" ব্যবহারের ক্ষেত্রে টাইপ তৈরি করেন তবে আপনি কার্যকরভাবে কোনও কোডবেস-এর জন্য অনুসন্ধান করতে পারবেন না, কারণ আপনি এটি ভুল লিখেছেন!

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

এর মানে হল যে LEFTবরাদ্দ-টু দিতে হবে একবার এবং শুধুমাত্র একবার আপনার অ্যাপ্লিকেশনের মধ্যে। এবং, আপনার কোডের বাকী অংশগুলি সেই এনাম বা ধ্রুবককে উপার্জন করবে:

const string LEFT = "left";

if (direction == LEFT) {
  goLeft();
}

এটি যদি আপনি পছন্দ করেন তবে পরে আপনার দিকনির্দেশগুলির জন্য আপনি যে ডেটা টাইপটি ব্যবহার করেন তা আরও সহজেই পরিবর্তন করতে দেয়।


1

এটা কি খারাপ অভ্যাস?

সম্ভবত হ্যাঁ, তবে এটি আপনি যা করছেন ঠিক তার উপর এবং আপনি যে প্রোগ্রামিং ভাষা ব্যবহার করছেন তার উপরও নির্ভর করে।

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

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

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

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


আপনি যদি জাভাতে প্রয়োগ করছেন, character.direction == "left"অন্য কারণে খারাপ অভ্যাস। ==স্ট্রিংগুলির তুলনা করার জন্য আপনার ব্যবহার করা উচিত নয় , কারণ এটি স্ট্রিং সাম্যের চেয়ে বস্তুর পরিচয় পরীক্ষা করে। (আপনি যদি গ্যারান্টি দিতে পারতেন যে "left"স্ট্রিংয়ের সমস্ত উদাহরণ অভ্যন্তরীণ করা হয়েছে তবে এটি কার্যকর হবে তবে এতে অ্যাপ্লিকেশন বিশ্লেষণের সম্পূর্ণ প্রয়োজন))


1
যা সর্বদা স্থির বলে মনে হয় তা প্রায়শই স্থির হয় না so চার দিক উদাহরণস্বরূপ আট হয়ে যেতে পারে।
জিমি টি।

@JimmyT। - এটি প্রসঙ্গে নির্ভর করে। উদাহরণস্বরূপ, একটি গেমের ক্ষেত্রে, কোনও চরিত্র 4 থেকে 8-এ যেতে পারে এমন দিকনির্দেশের সংখ্যা পরিবর্তন করা গেমস বিধিগুলির একটি সম্পূর্ণ পর্যালোচনা এবং নিয়মকে কার্যকর করার কোডকে আবশ্যক। Stringদিকনির্দেশনা উপস্থাপনে ব্যবহার করা পরিবর্তনগুলি জড়িত কাজের পরিমাণের সাথে শূন্যের পার্থক্য তৈরি করবে। আরও বুদ্ধিমান পদ্ধতিটি হ'ল অনুমান করা যায় যে দিকের সংখ্যা পরিবর্তন হবে না এবং স্বীকৃতি জানাতে হবে যে গেমের নিয়মগুলি যদি মৌলিকভাবে পরিবর্তিত হয় তবে যে কোনও উপায়ে আপনার অনেক কাজ করতে হবে ।
স্টিফেন সি

@ জিমিটি - সম্পূর্ণরূপে সম্মত হয়েছি আমি এটি অনেকবার ঘটতে দেখেছি, আপনি বিকাশকারীদেরও স্ট্রিংটিকে নতুন করে সংজ্ঞায়িত করার শর্ট কাট নিতে পারেন উদাহরণস্বরূপ, পণ্য = "বিকল্প" পণ্য = "অপশন_অর_ফিউচার" হয়ে কোডটির অর্থকে পুরোপুরি অস্বীকার করে।
ক্রিস মিলবার্ন

-3

প্রস্তাবিত হিসাবে, আপনার Enums ব্যবহার করা উচিত। তবে, কেবল স্ট্রাইনের প্রতিস্থাপন হিসাবে এনাম ব্যবহার করা যথেষ্ট আইএমএইচও নয়। আপনার বিশেষ উদাহরণে, প্লেয়ারের বেগটি প্রকৃতপক্ষে পদার্থবিদ্যার মাধ্যমে একটি ভেক্টর হওয়া উচিত:

class Vector {
  final double x;
  final double y;
}

এই ভেক্টরটি তখন প্রতিটি টিক প্লেয়ারের অবস্থান আপডেট করার জন্য ব্যবহার করা উচিত।

তারপরে আপনি এটিকে উচ্চতর পঠনযোগ্যতার জন্য এনামের সাথে একত্রিত করতে পারেন:

enum Direction {
  UP(new Vector(0, 1)),
  RIGHT(new Vector(1, 0)),
  DOWN(new Vector(0, -1)),
  LEFT(new Vector(-1, 0));

  private Vector direction;

  Direction(Vector v) {
    this.direction = v;
  }

  public Vector getVector() { return this.direction; }
}

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