আসুন একটি পদক্ষেপ পিছনে নিতে এবং এখানে বড় ছবি তাকান।
কি IDatabase
'র দায়ভার?
এটির কয়েকটি আলাদা অপারেশন রয়েছে:
- সংযোগের স্ট্রিং পার্স করুন
- একটি ডাটাবেসের সাথে একটি সংযোগ খুলুন (একটি বাহ্যিক সিস্টেম)
- ডাটাবেসে বার্তা প্রেরণ করুন; বার্তাগুলি ডাটাবেসকে তার অবস্থার পরিবর্তন করতে আদেশ দেয় command
- ডাটাবেস থেকে প্রতিক্রিয়াগুলি গ্রহণ করুন এবং কলার ব্যবহার করতে পারেন এমন ফর্ম্যাটে রূপান্তর করুন
- সংযোগটি বন্ধ করুন
এই তালিকাটি দেখে আপনি ভাবছেন, "এটি কি এসআরপি লঙ্ঘন করে না?" তবে আমি তা করি না বলে মনে হয়। সমস্ত ক্রিয়াকলাপ একটি একক, সম্মিলিত ধারণার অংশ: ডাটাবেসের সাথে একটি রাষ্ট্রীয় সংযোগ পরিচালনা করে (একটি বাহ্যিক সিস্টেম) । এটি সংযোগ স্থাপন করে, এটি সংযোগের বর্তমান অবস্থার উপর নজর রাখে (বিশেষত অন্যান্য সংযোগগুলির উপর পরিচালিত ক্রিয়াকলাপগুলির ক্ষেত্রে), সংযোগের বর্তমান অবস্থা কখন সংঘটিত করতে হবে তা ইঙ্গিত দেয়, এই অর্থে, এটি একটি এপিআই হিসাবে কাজ করে এটি বেশিরভাগ কলারদের যত্ন নেবে না এমন প্রচুর বাস্তবায়ন বিবরণ গোপন করে। উদাহরণস্বরূপ, এটি কি এইচটিটিপি, সকেট, পাইপ, কাস্টম টিসিপি, এইচটিটিপিএস ব্যবহার করে? কলিং কোড পাত্তা দেয় না; এটি কেবল বার্তা প্রেরণ করতে এবং প্রতিক্রিয়া পেতে চায়। এটি encapsulation একটি ভাল উদাহরণ।
আমরা কি নিশ্চিত? আমরা কি এই অপারেশনগুলির কিছু ভাগ করতে পারি না? হতে পারে, তবে কোনও লাভ নেই। আপনি যদি এগুলিকে আলাদা করার চেষ্টা করেন তবে আপনার এখনও একটি কেন্দ্রীয় অবজেক্ট দরকার যা সংযোগটি উন্মুক্ত রাখে এবং / অথবা বর্তমান অবস্থাটি পরিচালনা করে। অন্যান্য সমস্ত ক্রিয়াকলাপ দৃ strongly ়ভাবে একই অবস্থায় মিলিত হয়েছে, এবং আপনি যদি তাদের আলাদা করার চেষ্টা করেন তবে তারা কেবল সংযোগের অবজেক্টে যাই হোক না কেন ফেরত প্রেরণ করতে চলেছে। এই অপারেশনগুলি প্রাকৃতিক এবং যৌক্তিকভাবে রাষ্ট্রের সাথে মিলিত হয় এবং এগুলি আলাদা করার কোনও উপায় নেই। যখন আমরা এটি করতে পারি তখন ডিকোপলিং দুর্দান্ত, তবে এই ক্ষেত্রে আমরা আসলে পারি না। কমপক্ষে একটি পৃথক, ডিবিতে কথা বলার জন্য রাষ্ট্রবিহীন প্রোটোকল ছাড়া না, এবং এটি আসলে এসিআইডি কমপ্লায়েন্সের মতো খুব গুরুত্বপূর্ণ সমস্যা তৈরি করবে। এছাড়াও, সংযোগ থেকে এই ক্রিয়াকলাপগুলি ডিক্লোল করার চেষ্টা করার সময়, আপনি কলকারীরা যে প্রোটোকলের যত্ন নেন না সে সম্পর্কে বিবরণ প্রকাশ করতে বাধ্য হবেন, যেহেতু আপনার কোনও ধরণের "স্বেচ্ছাচারিত" বার্তা প্রেরণের জন্য একটি উপায় প্রয়োজন ডাটাবেসে।
নোট করুন যে আমরা একটি রাষ্ট্রীয় প্রোটোকল নিয়ে কাজ করছি তা আপনার দৃ alternative়তার সাথে সর্বশেষ বিকল্পটিকে ছাড়িয়ে যায় (সংযোগের স্ট্রিংটিকে প্যারামিটার হিসাবে পাস করে)।
আমাদের কি সত্যিই সেট করার জন্য সংযোগের স্ট্রিং দরকার?
হ্যাঁ. আপনার সংযোগের স্ট্রিং না হওয়া পর্যন্ত আপনি সংযোগটি খুলতে পারবেন না এবং সংযোগটি না খোলার আগ পর্যন্ত আপনি প্রোটোকল দিয়ে কিছু করতে পারবেন না। সুতরাং এটি ছাড়া কোনও সংযোগের বিষয়টি থাকা অর্থহীন ।
সংযোগের স্ট্রিংয়ের প্রয়োজনীয়তার সমস্যাটি আমরা কীভাবে সমাধান করব?
আমরা যে সমস্যাটি সমাধান করার চেষ্টা করছি তা হ'ল আমরা চাই যে বস্তুটি সর্বদা ব্যবহারযোগ্য স্থানে থাকে। ওও ভাষায় রাষ্ট্র পরিচালনার জন্য কোন ধরণের সত্তা ব্যবহৃত হয়? অবজেক্টস , ইন্টারফেস নয়। ইন্টারফেসের পরিচালনার রাষ্ট্র নেই। যে সমস্যাটি আপনি সমাধান করার চেষ্টা করছেন তা হ'ল একটি রাষ্ট্র পরিচালনার সমস্যা, একটি ইন্টারফেস এখানে সত্যই উপযুক্ত নয়। একটি বিমূর্ত শ্রেণি অনেক বেশি প্রাকৃতিক। সুতরাং একটি কনস্ট্রাক্টর সহ একটি বিমূর্ত ক্লাস ব্যবহার করুন।
কনস্ট্রাক্টরের সময় আপনি সংযোগটি খোলার বিষয়টিও বিবেচনা করতে পারেন , কারণ সংযোগটি খোলার আগে এটিও অকেজো। এর জন্য একটি বিমূর্ত protected Open
পদ্ধতি প্রয়োজন কারণ সংযোগ খোলার প্রক্রিয়া ডাটাবেস নির্দিষ্ট হতে পারে। ConnectionString
এই ক্ষেত্রে সম্পত্তিটি কেবল পঠন করা ভাল ধারণা হবে কারণ সংযোগটি খোলা থাকার পরে সংযোগের স্ট্রিং পরিবর্তন করা অর্থহীন হবে। (সত্যি বলতে, আমি এটি যেভাবেই পড়তে পারি। আপনি যদি অন্য স্ট্রিংয়ের সাথে সংযোগ চান তবে অন্য কোনও বস্তু তৈরি করুন))
আমাদের কি কোনও ইন্টারফেসের দরকার আছে?
একটি ইন্টারফেস যা উপলব্ধ সংযোগগুলি আপনাকে সংযোগের মাধ্যমে প্রেরণ করতে পারে এবং যে ধরণের প্রতিক্রিয়া আপনি ফিরে পেতে পারেন তা নির্দিষ্ট করে। এটি আমাদের কোড লিখতে দেয় যা এই ক্রিয়াকলাপগুলি কার্যকর করে তবে সংযোগ খোলার যুক্তিতে মিলিত হয় না। তবে এটি হ'ল সংযোগটি পরিচালনা করা এই ইন্টারফেসের অংশ নয়, "আমি কী বার্তা পাঠাতে পারি এবং আমি কী বার্তাগুলি ডাটাবেসে / থেকে ফিরে পেতে পারি?", সুতরাং সংযোগের স্ট্রিংটিও এর একটি অংশ হওয়া উচিত নয় ইন্টারফেস.
আমরা যদি এই রুটে চলে যাই তবে আমাদের কোডটি এর মতো দেখতে পারে:
interface IDatabase {
void ExecuteNoQuery(string sql);
void ExecuteNoQuery(string[] sql);
//Various other methods all requiring ConnectionString to be set
}
abstract class ConnectionStringDatabase : IDatabase {
public string ConnectionString { get; }
public Database(string connectionString) {
this.ConnectionString = connectionString;
this.Open();
}
protected abstract void Open();
public abstract void ExecuteNoQuery(string sql);
public abstract void ExecuteNoQuery(string[] sql);
//Various other methods all requiring ConnectionString to be set
}