কোডে ডেটা সংরক্ষণ করা


17

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

public class Country
{
    public string Code { get; set; }
    public string EnglishName {get;set;}
}

public static class CountryHelper
{
    public static List<Country> Countries = new List<Country>
        {
            new Country {Code = "AU", EnglishName = "Australia"},
            ...
            new Country {Code = "SE", EnglishName = "Sweden"},
            ...
        };

    public static Country GetByCode(string code)
    {
        return Countries.Single(c => c.Code == code);
    }
}

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

ডেটা নিজেই খুব কমই পরিবর্তিত হয় এবং এটি পরিবর্তিত হয় যখন এটি সত্যিই এমনকি গুরুত্বপূর্ণ হয় না। সুতরাং এটি পরবর্তী প্রকাশিত সংস্করণে ঘূর্ণায়মান পুরোপুরি ঠিক আছে।

আমি আমার ডেটা উত্সকে এমন কিছুতে রূপান্তর করতে টি 4 বা ইআরবি বা অন্য কোনও টেম্প্লেটিং সমাধান ব্যবহার করার পরিকল্পনা করছি যা সমাবেশে স্থিতিশীলভাবে সঞ্চিত থাকে।

আমার বিকল্পগুলি মনে হয়

  1. এক্সএমএলে ডেটা সংরক্ষণ করুন। এক্সেমিলি রিসোর্স হিসাবে এক্সএমএল ফাইলটি সংকলন করুন। প্রয়োজনীয় হিসাবে ডেটা লোড করুন, পুনরায় ব্যবহারের পারফরম্যান্সের জন্য লোড হওয়া ডেটাটিকে একটি অভিধানে সঞ্চয় করুন।
  2. প্রারম্ভকালীন সময়ে শুরু হওয়া কিছু স্ট্যাটিক অবজেক্ট বা অবজেক্ট তৈরি করুন।

আমি নিশ্চিত যে আমি বিকল্প 1 এর পারফরম্যান্সের প্রভাবগুলি বুঝতে পেরেছি least কমপক্ষে, আমার কুঁচক এটির দুর্দান্ত অভিনয় নেই।

বিকল্প 2 হিসাবে, আমি কী করব জানি না। .NET কাঠামোর অভ্যন্তরগুলি সম্পর্কে এই তথ্যটি আসলে # # কোডে প্রকৃতপক্ষে সংরক্ষণ করার সর্বোত্তম উপায় এবং এটি শুরু করার সর্বোত্তম উপায়গুলি সম্পর্কে আমি যথেষ্ট জানি না। আমি কীভাবে System.Globalization.CultureInfo.GetCulture(name)কাজ করে তা দেখতে নেট ডাব্লু রিফ্লেক্টরটি ব্যবহার করে ঘুরে দেখলাম , যেহেতু এটি আসলে যা আমি চাই তার সাথে খুব মিল রয়েছে work দুর্ভাগ্যক্রমে এই ট্রেইলটি শেষ হয়েছে extern, সুতরাং কোনও ইঙ্গিত নেই। আমার উদাহরণ হিসাবে, যাওয়ার মতো সমস্ত ডেটা দিয়ে স্থিতিশীল সম্পত্তি শুরু করা কি? অথবা চাহিদার ভিত্তিতে অবজেক্টগুলি তৈরি করা এবং তারপরে এগুলি ক্যাশে করা ভাল?

    private static readonly Dictionary<string, Country> Cache = new Dictionary<string,Country>(); 

    public static Country GetByCode(string code)
    {
        if (!Cache.ContainsKey(code))
            return Cache[code];

        return (Cache[code] = CreateCountry(code));
    }

    internal static Country CreateCountry(string code)
    {
        if (code == "AU")
            return new Country {Code = "AU", EnglishName = "Australia"};
        ...
        if (code == "SE")
            return new Country {Code = "SE", EnglishName = "Sweden"};
        ...
        throw new CountryNotFoundException();
    }

স্থিতিশীল সদস্যে একবারে এগুলি তৈরি করার সুবিধাটি হ'ল আপনি লিনকিউ বা অন্য যে কোনও কিছু ব্যবহার করতে পারেন সমস্ত বস্তুর দিকে নজর রাখতে এবং যদি আপনি চান তবে সেগুলি অনুসন্ধান করতে পারেন। যদিও আমি সন্দেহ করি এটি করার ক্ষেত্রে একটি স্টার্টআপ পারফরম্যান্স পেনাল্টি রয়েছে। আমি আশা করছি কারও সাথে এটির অভিজ্ঞতা আছে এবং তাদের মতামত ভাগ করে নিতে পারেন!


5
200 অবজেক্ট? আমি মনে করি না পারফরম্যান্স নিয়ে আপনাকে চিন্তিত হতে হবে, বিশেষত যদি এটি এক সময়ের ব্যয় হয়।
এসভিক

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

@ এসভিক: সত্য। আমি সম্ভবত অভিনয় সম্পর্কে অতিরিক্ত সতর্ক হই being
mroach

@ অ্যামাইব্ল্যাঙ্কনশিপ আমি সর্বদা সহায়ক পদ্ধতি ব্যবহার করতাম, তবে ডিআই একটি ভাল ধারণা। আমি এটা ভাবিনি। আমি এটি দিয়ে যাব এবং দেখব আমি প্যাটার্নটি পছন্দ করি কিনা। ধন্যবাদ!
mroach

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

উত্তর:


11

আমি এক বিকল্প সঙ্গে যেতে হবে। এটি সহজ এবং পড়া সহজ। আপনার কোডটির দিকে তাকিয়ে অন্য কেউ সরাসরি তা বুঝতে পারবেন। প্রয়োজনে আপনার এক্সএমএল ডেটা আপডেট করা আরও সহজ হবে। (আরও ভাল আপনি যদি সামনে একটি ভাল প্রান্ত থাকে এবং ফাইলগুলি পৃথকভাবে সঞ্চয় করে থাকেন তবে ব্যবহারকারীকে সেগুলি আপডেট করতে দিতে পারে)

আপনার প্রয়োজন হলে কেবল এটিই অনুকূলিত করুন - অকাল অনুকূলকরণটি খারাপ) :)


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

7

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

private static class CountryHelper
{
    private static ResourceManager rm;

    static CountryHelper()
    {
        rm = new ResourceManager("Countries",  typeof(CountryHelper).Assembly);
    }

    public static Country GetByCode(string code)
    {
        string countryName = rm.GetString(code + ".EnglishName");
        return new Country { Code = code, EnglishName = countryName };
    }
}

এটিকে কিছুটা দক্ষ করার জন্য আপনি এগুলি একবারে লোড করতে পারেন:

private static class CountryHelper
{
    private static Dictionary<string, Country> countries;

    static CountryHelper()
    {
        ResourceManager rm = new ResourceManager("Countries",  typeof(CountryHelper).Assembly);
        string[] codes = rm.GetString("AllCodes").Split("|"); // AU|SE|... 
        countries = countryCodes.ToDictionary(c => c, c => CreateCountry(rm, c));
    }

    public static Country GetByCode(string code)
    {
        return countries[code];
    }

    private static Country CreateCountry(ResourceManager rm, string code)
    {
        string countryName = rm.GetString(code + ".EnglishName");
        return new Country { Code = "SE", EnglishName = countryName };
    }
}

আপনার অ্যাপ্লিকেশনটিকে একাধিক ভাষায় সমর্থন করার প্রয়োজন হলে এটি আপনাকে অনেক সাহায্য করবে ।

যদি এটি ডাব্লুপিএফ অ্যাপ্লিকেশন হিসাবে ঘটে থাকে তবে একটি উত্স অভিধান একটি আরও সুস্পষ্ট সমাধান।


2

সিদ্ধান্তটি সত্যই: আপনি কি কেবল বিকাশকারী (বা বিল্ড সিস্টেমে অ্যাক্সেস সহ যে কেউ চান) ডেটা সংশোধন করার প্রয়োজন হয় বা শেষ ব্যবহারকারী বা সংস্থার কোনও ব্যবহারকারী সম্ভবত সংশোধন করতে সক্ষম হন তথ্য?

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

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


1

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

যদিও এটি সমর্থন করার জন্য কোনও দুর্দান্ত ডকুমেন্টেশন নেই, এমএসবাইল্ডকে অবশ্যই একটি এক্সএএমএল ফাইল নিতে, এটি বিএএমএলে রূপান্তর করতে এবং আপনার জন্য এটি এম্বেড করতে সক্ষম হতে হবে (এটি এটি ফর্মগুলির জন্য সঠিকভাবে তৈরি করে?)।

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

কয়েকটি লিঙ্ক যা দরকারী রেফারেন্স উপাদান:

  • AL.exe (সমাবেশগুলিতে সংস্থান সংস্থানগুলির জন্য)
  • Resgen.exe (.resx ফাইলগুলিকে সংস্থানগুলিতে রূপান্তর করার জন্য)
  • XamlServices ক্লাস

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


1

আমার ধারণা, সিস্টেম.গ্লোবালাইজেশন.ক্ল্যাচারআইনফো.গেটকালচার (নাম) একটি সিস্টেম ফাইল থেকে ডেটা পেতে উইন্ডোজ এপিআইগুলিকে কল করবে।

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

যদি আপনার ডেটা কখনই পরিবর্তন হয় না, আমার অভিজ্ঞতা কেবল তালিকা / অভিধান ব্যবহার করে:

private static readonly Dictionary<string, Country> _countries = new Dictionary<string,Country>();

তবে সমস্যাটি হ'ল আপনার অভিধানটি আরম্ভ করার জন্য আপনাকে একটি উপায় খুঁজে বের করতে হবে। আমার ধারণা এটি ব্যথার বিষয় point

সুতরাং সমস্যাটি "কীভাবে আপনার ডেটা তৈরি করবেন?" তে পরিবর্তিত হয়েছে। তবে এটি আপনার যা প্রয়োজন তা সম্পর্কিত।

আপনি যদি দেশগুলির জন্য ডেটা তৈরি করতে চান তবে আপনি এটি ব্যবহার করতে পারেন

System.Globalization.CultureInfo.GetCultures()

CultrueInfo অ্যারে পান এবং আপনি আপনার প্রয়োজনের সাথে অভিধানটি আরম্ভ করতে পারেন।

এবং অবশ্যই আপনি কোডটি একটি স্ট্যাটিক ক্লাসে রাখতে পারেন এবং অভিধানটিকে স্ট্যাটিক কনস্ট্রাক্টরের মতো শুরু করতে পারেন:

public static class CountryHelper
{
    private static readonly Dictionary<string, Country> _countries;
    static CountryHelper()
    {
        _countries = new Dictionary<string,Country>();
        // initialization code for your dictionary
        System.Globalization.CultureInfo[] cts = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures);
        for(int i=0; i < cts.Length; i++)
        {
            _countries.Add(cts[i].Name, new Country(cts[i]));
        }
    }

    public static Country GetCountry(string code)
    {
        Country ct = null;
        if(this._countries.TryGet(code, out ct))
        {
            return ct;
        } else
        {
            Log.WriteDebug("Cannot find country with code '{0}' in the list.", code);
            return null;
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.