এই পৃষ্ঠায় আর্কিটেকচারের বেশ কিছু সেরা অনুশীলন এবং সুপারিশ তুলে ধরা হয়েছে। আপনার অ্যাপের গুণমান, দৃঢ়তা এবং প্রসারণযোগ্যতা উন্নত করতে এগুলো গ্রহণ করুন। এগুলো আপনার অ্যাপের রক্ষণাবেক্ষণ এবং পরীক্ষাও সহজ করে তোলে।
নীচের সেরা অনুশীলনগুলি বিষয় অনুসারে শ্রেণীবদ্ধ করা হয়েছে। প্রতিটির একটি অগ্রাধিকার রয়েছে যা সুপারিশটির গুরুত্ব নির্দেশ করে। অগ্রাধিকারের তালিকাটি নিম্নরূপ:
- দৃঢ়ভাবে সুপারিশ করা হচ্ছে: এই অনুশীলনটি বাস্তবায়ন করুন, যদি না এটি আপনার পদ্ধতির সাথে মৌলিকভাবে সাংঘর্ষিক হয়।
- সুপারিশকৃত: এই অনুশীলনটি আপনার অ্যাপের মান উন্নত করতে পারে।
- ঐচ্ছিক: নির্দিষ্ট পরিস্থিতিতে এই অনুশীলনটি আপনার অ্যাপের উন্নতি করতে পারে।
স্তরযুক্ত স্থাপত্য
আমাদের প্রস্তাবিত লেয়ার্ড আর্কিটেকচার কাজের পৃথকীকরণকে প্রাধান্য দেয়। এটি ডেটা মডেল থেকে UI পরিচালনা করে, ‘একক সত্যের উৎস’ নীতি মেনে চলে এবং একমুখী ডেটা প্রবাহের নীতি অনুসরণ করে। লেয়ার্ড আর্কিটেকচারের জন্য কিছু সেরা অনুশীলন নিচে দেওয়া হলো:
| সুপারিশ | বর্ণনা |
|---|---|
| একটি সুস্পষ্টভাবে সংজ্ঞায়িত ডেটা লেয়ার ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | ডেটা লেয়ার অ্যাপ্লিকেশনের ডেটা অ্যাপের বাকি অংশের কাছে প্রকাশ করে এবং এতে আপনার অ্যাপের সিংহভাগ বিজনেস লজিক থাকে।
|
| একটি সুস্পষ্টভাবে সংজ্ঞায়িত UI লেয়ার ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | UI লেয়ার স্ক্রিনে অ্যাপ্লিকেশন ডেটা প্রদর্শন করে এবং ব্যবহারকারীর মিথস্ক্রিয়ার প্রধান কেন্দ্রবিন্দু হিসেবে কাজ করে। আপনার অ্যাপের UI তৈরির জন্য Jetpack Compose হলো প্রস্তাবিত আধুনিক টুলকিট।
|
| একটি রিপোজিটরি ব্যবহার করে ডেটা লেয়ার থেকে অ্যাপ্লিকেশন ডেটা প্রকাশ করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | নিশ্চিত করুন যে UI লেয়ারের কম্পোনেন্টগুলো, যেমন কম্পোজেবল বা ভিউমডেল, কোনো ডেটা সোর্সের সাথে সরাসরি যোগাযোগ না করে। ডেটা সোর্সের উদাহরণগুলো হলো:
|
| কো-রুটিন এবং ফ্লো ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | লেয়ারগুলোর মধ্যে যোগাযোগের জন্য কো-রুটিন এবং ফ্লো ব্যবহার করুন। কো-রুটিনের সেরা অনুশীলন সম্পর্কে আরও তথ্যের জন্য, অ্যান্ড্রয়েডে কো-রুটিনের সেরা অনুশীলন দেখুন। |
| একটি ডোমেইন লেয়ার ব্যবহার করুন। বড় অ্যাপগুলিতে সুপারিশ করা হয়েছে | যদি একাধিক ViewModel-এর মধ্যে ডেটা লেয়ারের সাথে কাজ করে এমন বিজনেস লজিক পুনরায় ব্যবহার করার প্রয়োজন হয়, অথবা আপনি কোনো নির্দিষ্ট ViewModel-এর বিজনেস লজিকের জটিলতা সরল করতে চান, তাহলে ইউজ কেস সহ একটি ডোমেইন লেয়ার ব্যবহার করুন। |
UI স্তর
UI লেয়ারের ভূমিকা হলো স্ক্রিনে অ্যাপ্লিকেশন ডেটা প্রদর্শন করা এবং ব্যবহারকারীর মিথস্ক্রিয়ার প্রধান কেন্দ্রবিন্দু হিসেবে কাজ করা। UI লেয়ারের জন্য কিছু সেরা অনুশীলন নিচে দেওয়া হলো:
| সুপারিশ | বর্ণনা |
|---|---|
| একমুখী ডেটা প্রবাহ (UDF) অনুসরণ করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | ইউনিডিরেকশনাল ডেটা ফ্লো (UDF) নীতি অনুসরণ করুন, যেখানে ভিউমডেলগুলি অবজারভার প্যাটার্ন ব্যবহার করে UI স্টেট প্রকাশ করে এবং মেথড কলের মাধ্যমে UI থেকে অ্যাকশন গ্রহণ করে। |
| আপনার অ্যাপের জন্য AAC ViewModel-এর সুবিধাগুলো প্রযোজ্য হলে সেগুলো ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | বিজনেস লজিক পরিচালনা করতে এবং UI-এর স্টেট প্রকাশ করার জন্য অ্যাপ্লিকেশন ডেটা ফেচ করতে AAC ViewModel ব্যবহার করুন। ViewModel-এর সর্বোত্তম অনুশীলন সম্পর্কে আরও তথ্যের জন্য, আর্কিটেকচার সুপারিশসমূহ দেখুন। ViewModel-এর সুবিধাসমূহ সম্পর্কে আরও তথ্যের জন্য, "ব্যবসায়িক যুক্তির অবস্থা ধারক হিসেবে ViewModel" দেখুন। |
| লাইফসাইকেল-সচেতন UI স্টেট সংগ্রহ ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | উপযুক্ত লাইফসাইকেল-সচেতন কো-রুটিন বিল্ডার, collectAsStateWithLifecycle ব্যবহার করে UI থেকে UI স্টেট সংগ্রহ করুন। |
| ViewModel থেকে UI-তে ইভেন্ট পাঠাবেন না। জোরালোভাবে সুপারিশ করা হচ্ছে | ViewModel-এ ইভেন্টটি অবিলম্বে প্রসেস করুন এবং ইভেন্টটি হ্যান্ডেল করার ফলাফল দিয়ে একটি স্টেট আপডেট ঘটান। UI ইভেন্ট সম্পর্কে আরও তথ্যের জন্য, “Handle ViewModel events” দেখুন। |
| একটি একক-কার্যকলাপের অ্যাপ্লিকেশন ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | আপনার অ্যাপে একাধিক স্ক্রিন থাকলে, স্ক্রিনগুলোর মধ্যে যাতায়াত করতে নেভিগেশন ৩ ব্যবহার করুন এবং অ্যাপে ডিপ লিঙ্ক করুন। |
| Jetpack Compose ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | ফোন, ট্যাবলেট, ফোল্ডেবল এবং Wear OS-এর জন্য নতুন অ্যাপ তৈরি করতে Jetpack Compose ব্যবহার করুন। |
নিম্নলিখিত কোড স্নিপেটটি লাইফসাইকেল-সচেতন পদ্ধতিতে UI স্টেট সংগ্রহ করার পদ্ধতি বর্ণনা করে:
@Composable
fun MyScreen(
viewModel: MyViewModel = viewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
}
ভিউমডেল
ভিউমডেলগুলো UI স্টেট প্রদান এবং ডেটা লেয়ার অ্যাক্সেস করার জন্য দায়ী। ভিউমডেল ব্যবহারের কিছু সেরা অনুশীলন নিচে দেওয়া হলো:
| সুপারিশ | বর্ণনা |
|---|---|
| ভিউমডেলগুলোকে অ্যান্ড্রয়েড লাইফসাইকেল থেকে স্বাধীন রাখুন। জোরালোভাবে সুপারিশ করা হচ্ছে | ViewModel-এ কোনো লাইফসাইকেল-সম্পর্কিত টাইপের রেফারেন্স রাখবেন না। ডিপেন্ডেন্সি হিসেবে Activity , Context বা Resources পাস করবেন না। ViewModel-এর কোনো কিছুর জন্য যদি Context প্রয়োজন হয়, তবে সেটি সঠিক লেয়ারে আছে কি না, তা সাবধানে মূল্যায়ন করুন। |
| কো-রুটিন এবং ফ্লো ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | ViewModel নিম্নলিখিত পদ্ধতি ব্যবহার করে ডেটা বা ডোমেইন লেয়ারের সাথে যোগাযোগ করে:
|
| স্ক্রিন লেভেলে ভিউমডেল ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | UI-এর পুনঃব্যবহারযোগ্য অংশে ViewModel ব্যবহার করবেন না। নিম্নলিখিত স্থানগুলিতে ViewModel ব্যবহার করা উচিত:
|
| পুনরায় ব্যবহারযোগ্য UI কম্পোনেন্টগুলিতে সাধারণ স্টেট হোল্ডার ক্লাস ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | পুনরায় ব্যবহারযোগ্য UI কম্পোনেন্টগুলোর জটিলতা সামলানোর জন্য সাধারণ স্টেট হোল্ডার ক্লাস ব্যবহার করুন। এর ফলে, স্টেটকে হোইস্ট করে বাইরে থেকে নিয়ন্ত্রণ করা যায়। |
AndroidViewModel ব্যবহার করবেন না। সুপারিশকৃত | AndroidViewModel নয়, ViewModel ক্লাসটি ব্যবহার করুন। ViewModel-এর মধ্যে Application ক্লাসটি ব্যবহার করবেন না। এর পরিবর্তে, ডিপেন্ডেন্সিটি UI বা ডেটা লেয়ারে সরিয়ে নিন। |
| একটি UI অবস্থা প্রকাশ করুন। সুপারিশকৃত | আপনার ViewModel-গুলোকে uiState নামক একটিমাত্র প্রপার্টির মাধ্যমে UI-তে ডেটা প্রকাশ করতে দিন। যদি UI একাধিক, সম্পর্কহীন ডেটা প্রদর্শন করে, তবে VM একাধিক UI স্টেট প্রপার্টি প্রকাশ করতে পারে।
|
নিম্নলিখিত কোড স্নিপেটটিতে একটি ViewModel থেকে UI স্টেট কীভাবে প্রকাশ করতে হয় তার রূপরেখা দেওয়া হয়েছে:
@HiltViewModel
class BookmarksViewModel @Inject constructor(
newsRepository: NewsRepository
) : ViewModel() {
val feedState: StateFlow<NewsFeedUiState> =
newsRepository
.getNewsResourcesStream()
.mapToFeedState(savedNewsResourcesState)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = NewsFeedUiState.Loading
)
// ...
}
জীবনচক্র
অ্যাক্টিভিটি লাইফসাইকেল নিয়ে কাজ করার জন্য সর্বোত্তম পদ্ধতি অনুসরণ করুন:
| সুপারিশ | বর্ণনা |
|---|---|
Activity লাইফসাইকেল কলব্যাক ওভাররাইড করার পরিবর্তে কম্পোজেবলগুলিতে লাইফসাইকেল-সচেতন এফেক্ট ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | UI-সম্পর্কিত কাজ চালানোর জন্য
|
নিম্নলিখিত কোড স্নিপেটটি একটি নির্দিষ্ট লাইফসাইকেল স্টেট দেওয়া থাকলে কীভাবে অপারেশনগুলি সম্পাদন করতে হয় তার রূপরেখা দেয়:
@Composable
fun LocationChangedEffect(
locationManager: LocationManager,
onLocationChanged: (Location) -> Unit
) {
val currentOnLocationChanged by rememberUpdatedState(onLocationChanged)
LifecycleStartEffect(locationManager) {
val listener = LocationListener { newLocation ->
currentOnLocationChanged(newLocation)
}
try {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
1000L,
1f,
listener,
)
} catch (e: SecurityException) {
// TODO: Handle missing permissions
}
onStopOrDispose {
locationManager.removeUpdates(listener)
}
}
}
নির্ভরতা পরিচালনা করুন
কম্পোনেন্টগুলোর মধ্যে নির্ভরতা ব্যবস্থাপনার ক্ষেত্রে সর্বোত্তম পদ্ধতি অনুসরণ করুন:
| সুপারিশ | বর্ণনা |
|---|---|
| ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | ডিপেন্ডেন্সি ইনজেকশনের সর্বোত্তম অনুশীলনগুলো ব্যবহার করুন, বিশেষ করে সম্ভব হলে কনস্ট্রাক্টর ইনজেকশন । |
| প্রয়োজনে কোনো উপাদানের পরিধি নির্ধারণ করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | যখন টাইপটিতে পরিবর্তনযোগ্য ডেটা থাকে যা শেয়ার করা প্রয়োজন, অথবা টাইপটি ইনিশিয়ালাইজ করতে ব্যয়বহুল এবং অ্যাপে ব্যাপকভাবে ব্যবহৃত হয়, তখন সেটিকে একটি ডিপেন্ডেন্সি কন্টেইনারে স্কোপ করুন। |
| হাতল ব্যবহার করুন। সুপারিশকৃত | সহজ অ্যাপের ক্ষেত্রে হিল্ট (Hilt) অথবা ম্যানুয়াল ডিপেন্ডেন্সি ইনজেকশন ব্যবহার করুন। আপনার প্রজেক্টটি যথেষ্ট জটিল হলে হিল্ট ব্যবহার করুন—উদাহরণস্বরূপ, যদি এতে নিম্নলিখিতগুলির কোনোটি অন্তর্ভুক্ত থাকে:
|
পরীক্ষা
টেস্টিং- এর জন্য কিছু উত্তম পদ্ধতি নিচে দেওয়া হলো:
| সুপারিশ | বর্ণনা |
|---|---|
| কী পরীক্ষা করতে হবে তা জানুন । জোরালোভাবে সুপারিশ করা হচ্ছে | প্রকল্পটি যদি একটি 'হ্যালো ওয়ার্ল্ড' অ্যাপের মতো সহজ না হয়, তবে এটি পরীক্ষা করুন। ন্যূনতম নিম্নলিখিত বিষয়গুলো অন্তর্ভুক্ত করুন:
|
| নকলের চেয়ে নকল পছন্দ করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | ফেক ব্যবহারের বিষয়ে আরও তথ্যের জন্য, Android-এ টেস্ট ডাবল ব্যবহার দেখুন। |
| স্টেটফ্লো পরীক্ষা করুন। জোরালোভাবে সুপারিশ করা হচ্ছে | StateFlow পরীক্ষা করার সময়, নিম্নলিখিতগুলি করুন:
|
আরও তথ্যের জন্য, অ্যান্ড্রয়েডে কী পরীক্ষা করতে হবে এবং আপনার কম্পোজ লেআউট পরীক্ষা করুন দেখুন।
মডেল
আপনার অ্যাপে মডেল তৈরি করার সময় এই সর্বোত্তম অনুশীলনগুলি অনুসরণ করুন:
| সুপারিশ | বর্ণনা |
|---|---|
| জটিল অ্যাপে প্রতিটি লেয়ারের জন্য একটি করে মডেল তৈরি করুন। সুপারিশকৃত | জটিল অ্যাপের ক্ষেত্রে, প্রয়োজন অনুযায়ী নতুন মডেলগুলোকে বিভিন্ন লেয়ার বা কম্পোনেন্টে তৈরি করুন। নিম্নলিখিত উদাহরণগুলো বিবেচনা করুন:
|
নামকরণের নিয়মাবলী
আপনার কোডবেসের নামকরণ করার সময় নিম্নলিখিত সর্বোত্তম অনুশীলনগুলো সম্পর্কে সচেতন থাকা উচিত:
| সুপারিশ | বর্ণনা |
|---|---|
| নামকরণের পদ্ধতিসমূহ। ঐচ্ছিক | মেথডের নাম দিতে ক্রিয়াপদগুচ্ছ ব্যবহার করুন—উদাহরণস্বরূপ, makePayment() । |
| প্রপার্টিগুলোর নামকরণ। ঐচ্ছিক | প্রপার্টির নাম দিতে বিশেষ্য পদগুচ্ছ ব্যবহার করুন—উদাহরণস্বরূপ, inProgressTopicSelection । |
| ডেটার প্রবাহের নামকরণ। ঐচ্ছিক | যখন কোনো ক্লাস একটি ফ্লো স্ট্রিম বা অন্য কোনো স্ট্রিম প্রকাশ করে, তখন নামকরণের রীতিটি হলো get{model}Stream । উদাহরণস্বরূপ, getAuthorStream(): Flow<Author> । যদি ফাংশনটি মডেলের একটি তালিকা ফেরত দেয়, তাহলে মডেলের নামের বহুবচন ব্যবহার করুন: getAuthorsStream(): Flow<List<Author>> । |
| ইন্টারফেস ইমপ্লিমেন্টেশনের নামকরণ। ঐচ্ছিক | ইন্টারফেসের ইমপ্লিমেন্টেশনগুলোর জন্য অর্থপূর্ণ নাম ব্যবহার করুন। এর চেয়ে ভালো কোনো নাম খুঁজে না পেলে প্রিফিক্স হিসেবে Default ব্যবহার করুন। উদাহরণস্বরূপ, NewsRepository ইন্টারফেসের জন্য OfflineFirstNewsRepository বা InMemoryNewsRepository থাকতে পারে। যদি আপনি কোনো ভালো নাম খুঁজে না পান, তাহলে DefaultNewsRepository ব্যবহার করুন। নকল ইমপ্লিমেন্টেশনগুলোর আগে Fake প্রিফিক্স ব্যবহার করুন, যেমন FakeAuthorsRepository । |
অতিরিক্ত সম্পদ
অ্যান্ড্রয়েড আর্কিটেকচার সম্পর্কে আরও তথ্যের জন্য, নিম্নলিখিত অতিরিক্ত রিসোর্সগুলো দেখুন: