অ্যাপ্লিকেশন সেটিংস লোড করার সেরা উপায়


24

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

// Java example
Properties config = new Properties();
config.load(...);
String valueStr = config.getProperty("listening-port");
// ...

// C# example
NameValueCollection setting = ConfigurationManager.AppSettings;
string valueStr = setting["listening-port"];
// ...

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

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

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

এই সমস্যাটি সমাধান করার জন্য, আমি নীচে টেমপ্লেট পদ্ধতি পদ্ধতি ব্যবহার করার কথা ভেবেছিলাম ।

public abstract class Setting
{
    protected abstract bool TryParseValues();

    protected abstract bool CheckValues();

    public abstract void SetDefaultValues();

    /// <summary>
    /// Template Method
    /// </summary>
    public bool TrySetValuesOrDefault()
    {
        if (!TryParseValues() || !CheckValues())
        {
            // parsing error or domain error
            SetDefaultValues();
            return false;
        }
        return true;
    }
}

public class RangeSetting : Setting
{
    private string minStr, maxStr;
    private byte min, max;

    public RangeSetting(string minStr, maxStr)
    {
        this.minStr = minStr;
        this.maxStr = maxStr;
    }

    protected override bool TryParseValues()
    {
        return (byte.TryParse(minStr, out min)
            && byte.TryParse(maxStr, out max));
    }

    protected override bool CheckValues()
    {
        return (0 < min && min < max);
    }

    public override void SetDefaultValues()
    {
        min = 5;
        max = 10;
    }
}

সমস্যাটি হ'ল এইভাবে আমাদের প্রতিটি সেটিংয়ের জন্য এমনকি একটি একক মানের জন্য একটি নতুন শ্রেণি তৈরি করা দরকার। এই ধরণের সমস্যার কী অন্যান্য সমাধান আছে?

সংক্ষেপে:

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

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

উত্তর:


8

মূলত বাহ্যিক কনফিগারেশন ফাইলটি YAML নথি হিসাবে এনকোড করা আছে। এর পরে অ্যাপ্লিকেশন শুরু করার সময় পার্স করা হয় এবং একটি কনফিগারেশন অবজেক্টে ম্যাপ করা হয়।

চূড়ান্ত ফলাফলটি মজবুত এবং সর্বোপরি পরিচালনা করা সহজ।


7

আসুন এটি দুটি দৃষ্টিকোণ থেকে বিবেচনা করুন: কনফিগারেশন মানগুলি পেতে, এবং স্টোরেজ ফর্ম্যাটটি the এগুলি প্রায়শই সম্পর্কিত হয় তবে এগুলি আলাদাভাবে বিবেচনা করা সহায়ক।

কনফিগারেশন এপিআই

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

int getInt(name, default, min, max)
float getFloat(name, default, min, max)
boolean getBoolean(name, default)
String getString(name, default)
<T extends Enum<T>> T getEnum(name, Class<T> enumClass, T default)

(আমি মনে করি যে জেনেরিকগুলি আমি শেষের এক দিকে পেয়েছি))

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

এমন কিছু জিনিস রয়েছে যা হ্যান্ডেল করে না, যেমন একাধিক মান, মান যা আন্তঃসম্পর্কিত, গতিশীল টেবিল লুকআপ ইত্যাদি You আপনি এগুলির জন্য বিশেষ পার্সিং এবং বৈধকরণের রুটিন লিখতে পারেন, তবে এটি যদি খুব জটিল হয়ে যায় তবে আমি প্রশ্ন করতে শুরু করব I'd আপনি কোনও কনফিগার ফাইল দিয়ে খুব বেশি চেষ্টা করার চেষ্টা করছেন কিনা।

স্টোরেজ ফর্ম্যাট

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

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

আমি যদি সম্ভব হয় তবে বৈশিষ্ট্যগুলির সাথে লেগে থাকতে বলব।


2
আরে স্টুয়ার্ট, আপনাকে এখানে দেখতে ভাল লাগল :-)। আমি স্টুয়ার্টস এর উত্তরে যুক্ত করব যে আমি মনে করি আপনি জেনারিকসকে দৃ .়ভাবে টাইপ করার জন্য জাভা ব্যবহার করলে আপনার টেম্পল্ট ধারণাটি জাভাতে কাজ করবে, যাতে আপনার বিকল্প হিসাবে সেটিং <টি> থাকতে পারে।
মার্টিজ ভার্বার্গ

@StuartMarks: ওয়েল, আমার প্রথম ধারণা একটি লিখতে শুধু ছিল Configবর্গ পদ্ধতির আপনি দ্বারা প্রস্তাবিত এবং ব্যবহার করুন: getInt(), getByte(), getBoolean(), ইত্যাদি .. অব্যাহত এই ধারণা সঙ্গে, আমি প্রথম সব মান পড়া এবং আমি একটি পতাকা প্রতিটি মান শরীক পারে (এই পতাকাটি মিথ্যা যদি ডেসারিয়ালাইজেশনের সময় সমস্যা দেখা দেয়, উদাহরণস্বরূপ ত্রুটি বিশ্লেষণকারী)। এর পরে, আমি সমস্ত লোড হওয়া মানগুলির জন্য একটি বৈধতা পর্ব শুরু করতে এবং কোনও ডিফল্ট মান সেট করতে পারি।
enzom83

2
সমস্ত বিবরণ সহজ করার জন্য আমি এক ধরণের জ্যাক্সবি বা ওয়াইএএমএল পদ্ধতির পক্ষে চাই favor
গ্যারি রোয়ে

4

আমি এটি কীভাবে করেছি:

সমস্ত কিছু ডিফল্ট মানগুলিতে আরম্ভ করুন।

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


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

2

এই ধরণের সমস্যার কী অন্যান্য সমাধান আছে?

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


1
পার্সিং বা রূপান্তর নিয়ে কোনও বিড়বিড় করছে না, কনফিগার স্ট্রিংগুলির সাথে কোনও স্ক্রুিং নেই, noালাইয়ের আবর্জনা নেই। আপনি কি বোঝাতে চেয়েছেন?
enzom83

1
এর অর্থ হ'ল: ১. আপনার অ্যাপকনফাইগ ফলাফল (একটি স্ট্রিং) নেওয়ার দরকার নেই এবং যা চান তা পার্স করার দরকার নেই। ২. আপনার কোন কনফিগার প্যারামিটারটি চয়ন করতে আপনার কোনও ধরণের স্ট্রিং নির্দিষ্ট করার দরকার নেই; এটি সেই জিনিসগুলির মধ্যে একটি যা মানুষের ত্রুটিযুক্ত এবং চুল্লী প্রতিরোধের শক্ত এবং 3.. আপনার প্রোগ্রামের সাথে মান নির্ধারণ করতে গিয়ে অন্য ধরণের রূপান্তর করার দরকার নেই।
টেলাস্টিন

2

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

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


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

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