তৃতীয় পক্ষের লাইব্রেরি মোড়ানোর মাধ্যমে আপনি এর উপরে বিমূর্তির একটি অতিরিক্ত স্তর যুক্ত করুন। এর কয়েকটি সুবিধা রয়েছে:
আপনার কোড বেস পরিবর্তনগুলি আরও নমনীয় হয়ে ওঠে
আপনার যদি কখনও লাইব্রেরিকে অন্য একটিতে প্রতিস্থাপনের প্রয়োজন হয় তবে আপনাকে কেবল নিজের র্যাপারে - একই জায়গায় আপনার প্রয়োগ পরিবর্তন করতে হবে । আপনি মোড়কের বাস্তবায়ন পরিবর্তন করতে পারেন এবং অন্য কোনও বিষয়ে কোনও জিনিস বদলাতে হবে না, অন্য কথায় আপনার কাছে শিথিলিত যুগল সিস্টেম রয়েছে। অন্যথায় আপনাকে আপনার পুরো কোডবেস দিয়ে সর্বত্র পরিবর্তন করতে হবে - যা আপনি চান তা সম্ভবত নয়।
আপনি লাইব্রেরির এপিআই-র স্বাধীনভাবে মোড়কের এপিআই সংজ্ঞা দিতে পারেন
বিভিন্ন লাইব্রেরিতে বিস্তৃত পৃথক এপিআই থাকতে পারে এবং একই সাথে এগুলির কোনওটিই আপনার প্রয়োজন মতো হ'ল না। যদি কোনও লাইব্রেরির প্রতিটি কলের সাথে পাশ করার জন্য একটি টোকেনের প্রয়োজন হয় তবে কী হবে? আপনি যেখানেই লাইব্রেরিটি ব্যবহার করতে পারেন সেখানে আপনার অ্যাপ্লিকেশনটিতে টোকনটি পাস করতে পারেন বা আপনি এটি আরও কেন্দ্রীয়ভাবে নিরাপদ করতে পারেন তবে যে কোনও ক্ষেত্রে আপনার প্রয়োজনই টোকেন। আপনার মোড়কের ক্লাসটি এই পুরো জিনিসটিকে আবার সহজ করে তোলে - কারণ আপনি কেবল নিজের মোড়কের ক্লাসের ভিতরে টোকন রাখতে পারেন, এটি আপনার অ্যাপের অভ্যন্তরের কোনও উপাদানকে কখনই প্রকাশ করা যায় না এবং এর প্রয়োজনটিকে সম্পূর্ণ বিমূর্ত করে তোলে। আপনি যদি কখনও এমন একটি লাইব্রেরি ব্যবহার করেন যা ভাল API নকশাকে জোর দেয় না তবে একটি বিশাল সুবিধা।
ইউনিট টেস্টিং সহজ উপায়
ইউনিট পরীক্ষা শুধুমাত্র একটি জিনিস পরীক্ষা করা উচিত। আপনি যদি কোনও শ্রেণির পরীক্ষা করতে চান তবে আপনাকে তার নির্ভরতাগুলি উপহাস করতে হবে। এটি আরও গুরুত্বপূর্ণ হয়ে ওঠে যদি সেই শ্রেণিটি যদি আপনার সফ্টওয়্যারের বাইরে নেটওয়ার্ক কল করে বা অন্য কোনও সংস্থান অ্যাক্সেস করে। তৃতীয় পক্ষের লাইব্রেরি মোড়ানোর মাধ্যমে those কলগুলি উপহাস করা এবং পরীক্ষার ডেটা ফিরানো বা ইউনিট পরীক্ষার জন্য যা প্রয়োজন তা ফিরিয়ে দেওয়া সহজ। আপনার যদি বিমূর্ততার এমন স্তর না থাকে তবে এটি করা আরও বেশি কঠিন হয়ে পড়ে - এবং বেশিরভাগ সময় এর ফলে প্রচুর কুৎসিত কোড আসে।
আপনি একটি শিথিলিত যুগল সিস্টেম তৈরি করুন
আপনার মোড়কের পরিবর্তনগুলি আপনার সফ্টওয়্যারটির অন্যান্য অংশগুলিতে কোনও প্রভাব ফেলবে না - যতক্ষণ না আপনি নিজের মোড়কের আচরণ পরিবর্তন করেন না। এই মোড়কের মতো বিমূর্ততার একটি স্তর প্রবর্তন করে আপনি লাইব্রেরিতে কলগুলি সহজ করতে পারেন এবং সেই লাইব্রেরিতে আপনার অ্যাপের নির্ভরতা প্রায় সম্পূর্ণ সরিয়ে ফেলতে পারেন। আপনার সফ্টওয়্যারটি কেবল মোড়ক ব্যবহার করবে এবং এটি কীভাবে কার্যকরভাবে কার্যকর হয় বা এটি কী করে তা কীভাবে কার্যকর হয় তা কোনও পার্থক্য করে না।
ব্যবহারিক উদাহরণ
আসুন সত্যবাদী হই। লোকেরা এই জাতীয় কোনও কিছুর সুবিধা এবং অসুবিধাগুলি সম্পর্কে কয়েক ঘন্টা ধরে তর্ক করতে পারে - এজন্য আমি আপনাকে বরং একটি উদাহরণ দেখাই।
ধরা যাক আপনার কাছে কোনও ধরণের অ্যান্ড্রয়েড অ্যাপ রয়েছে এবং আপনার ছবিগুলি ডাউনলোড করতে হবে। সেখানে আউট লাইব্রেরি যা লোড হচ্ছে এবং ক্যাশে ইমেজ উদাহরণস্বরূপ একটি হাওয়া করতে একটি গুচ্ছ আছে পিকাসো বা ইউনিভার্সাল ভাবমূর্তি লোডার ।
আমরা এখন একটি ইন্টারফেস সংজ্ঞায়িত করতে পারি যা আমরা যে লাইব্রেরিটি ব্যবহার করে শেষ করব তা মোড়ানোর জন্য ব্যবহার করতে যাচ্ছি:
public interface ImageService {
Bitmap load(String url);
}
যখনই কোনও চিত্র লোড করা দরকার তখন আমরা এখন অ্যাপ্লিকেশন জুড়ে ব্যবহার করতে পারি এটিই ইন্টারফেস। আমরা এই ইন্টারফেসটির একটি বাস্তবায়ন তৈরি করতে পারি এবং যেখানেই আমরা ব্যবহার করি না কেন সেই প্রয়োগের একটি উদাহরণ ইনজেকশন করতে নির্ভরতা ইনজেকশন ব্যবহার করতে পারি ImageService
।
ধরা যাক আমরা প্রাথমিকভাবে পিকাসো ব্যবহারের সিদ্ধান্ত নিয়েছি। আমরা এখন একটি বাস্তবায়ন লিখতে পারি ImageService
যার জন্য পিকাসো অভ্যন্তরীণভাবে ব্যবহার করে:
public class PicassoImageService implements ImageService {
private final Context mContext;
public PicassoImageService(Context context) {
mContext = context;
}
@Override
public Bitmap load(String url) {
return Picasso.with(mContext).load(url).get();
}
}
আপনি আমাকে জিজ্ঞাসা যদি খুব সোজা এগিয়ে। লাইব্রেরিগুলির চারপাশে মোড়কগুলি কার্যকর হওয়ার জন্য জটিল হতে হবে না। ইন্টারফেস এবং বাস্তবায়নের কোডের 25 টিরও কম সংযুক্ত লাইনের রয়েছে তাই এটি তৈরি করার জন্য এটি সবেমাত্র কোনও প্রচেষ্টা ছিল, তবে ইতিমধ্যে আমরা এটি করে কিছু অর্জন করেছি। Context
বাস্তবায়নে ক্ষেত্রটি দেখুন ? আপনার পছন্দসই নির্ভরতা ইনজেকশন কাঠামোটি ইতিমধ্যে আমাদের নির্ভর করার আগে সেই নির্ভরতা ইনজেকশন দেওয়ার যত্ন নেবে ImageService
, আপনার অ্যাপ্লিকেশনটিকে এখন কীভাবে চিত্রগুলি ডাউনলোড করা হয় এবং লাইব্রেরিতে যে পরিমাণ নির্ভরতা থাকতে পারে সেদিকে নজর দেওয়া উচিত নয়। আপনার সমস্ত অ্যাপ্লিকেশনটি যা দেখেছে তা হ'ল ImageService
এবং যখন কোনও চিত্রের প্রয়োজন হয় তখন এটি load()
একটি ইউআরএল - সহজ এবং সহজবোধ্য সহ কল করে।
তবে আসল উপকারটি তখনই আসে যখন আমরা জিনিসগুলি পরিবর্তন করতে শুরু করি। ভাবুন আমাদের এখন পিকাসোকে ইউনিভার্সাল ইমেজ লোডার দিয়ে প্রতিস্থাপন করতে হবে কারণ পিকাসো আমাদের এখনই একেবারে প্রয়োজন এমন কিছু বৈশিষ্ট্য সমর্থন করে না। আমাদের এখন কি আমাদের কোডবেস দিয়ে চিরুনি দিয়ে এবং ক্লান্তি দিয়ে পিকাসোতে সমস্ত কলগুলি প্রতিস্থাপন করতে হবে এবং তারপরে কয়েক পিকাসোর কল ভুলে যাওয়ার কারণে কয়েক ডজন সংকলন ত্রুটিগুলি মোকাবেলা করতে হবে? না All আমাদের এখনই একটি নতুন বাস্তবায়ন তৈরি করা ImageService
এবং আমাদের নির্ভরতা ইনজেকশন কাঠামোটি এখন থেকে এই বাস্তবায়নটি ব্যবহার করতে বলুন:
public class UniversalImageLoaderImageService implements ImageService {
private final ImageLoader mImageLoader;
public UniversalImageLoaderImageService(Context context) {
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.defaultDisplayImageOptions(defaultOptions)
.build();
mImageLoader = ImageLoader.getInstance();
mImageLoader.init(config);
}
@Override
public Bitmap load(String url) {
return mImageLoader.loadImageSync(url);
}
}
আপনি দেখতে পাচ্ছেন বাস্তবায়নটি খুব আলাদা হতে পারে তবে এটি কোনও বিষয় নয়। আমাদের অ্যাপে অন্য কোথাও কোডের একক লাইন পরিবর্তন করতে হবে না। আমরা একটি সম্পূর্ণ আলাদা লাইব্রেরি ব্যবহার করি যা সম্পূর্ণ আলাদা বৈশিষ্ট্যযুক্ত থাকতে পারে বা খুব আলাদাভাবে ব্যবহার করা যেতে পারে তবে আমাদের অ্যাপ্লিকেশনটির কোনও যত্ন নেই। আমাদের অ্যাপ্লিকেশনের বাকী আগের মতোই কেবল ImageService
তার load()
পদ্ধতির সাথে ইন্টারফেস দেখেছে এবং তবে এই পদ্ধতিটি প্রয়োগ করা হয় তাতে আর কোনও গুরুত্ব আসে না।
কমপক্ষে আমার কাছে এটি ইতিমধ্যে বেশ সুন্দর লাগছে তবে অপেক্ষা করুন! এখনও আরও কিছু আছে। আপনি যে শ্রেণীর উপর কাজ করছেন সেটির জন্য আপনি ইউনিট পরীক্ষা লিখছেন এবং এই বর্গটি ব্যবহার করে দেখুন ImageService
। অবশ্যই আপনি আপনার ইউনিট পরীক্ষাগুলি অন্য কোনও সার্ভারে অবস্থিত কিছু সংস্থানগুলিতে নেটওয়ার্ক কল করতে দিতে পারবেন না তবে আপনি এখন যেহেতু ব্যবহার করছেন ImageService
আপনি load()
একটি বিদ্রূপক Bitmap
বাস্তবায়নের মাধ্যমে ইউনিট পরীক্ষার জন্য ব্যবহৃত একটি স্ট্যাটিক সহজেই ফেরত দিতে পারবেন ImageService
:
public class MockImageService implements ImageService {
private final Bitmap mMockBitmap;
public MockImageService(Bitmap mockBitmap) {
mMockBitmap = mockBitmap;
}
@Override
public Bitmap load(String url) {
return mMockBitmap;
}
}
তৃতীয় পক্ষের লাইব্রেরিগুলিকে মোড়ক দিয়ে সংক্ষেপে বলতে গেলে আপনার কোড বেস পরিবর্তনের জন্য আরও নমনীয় হয়ে ওঠে, সামগ্রিক সরল, পরীক্ষা করা সহজ এবং আপনি আপনার সফ্টওয়্যারটিতে বিভিন্ন উপাদানগুলির সংমিশ্রণ হ্রাস করেন - এমন সমস্ত বিষয় যা আপনাকে আরও বেশি গুরুত্বপূর্ণ সফ্টওয়্যার বজায় রাখে।