এই টিউটোরিয়ালটি আপনাকে Android-এ জেটপ্যাক কম্পোজ UI লাইব্রেরির সাথে সম্পর্কিত কয়েকটি মৌলিক ধারণা এবং শর্তাবলী শেখাবে।
যদিও এটি রচনা করার জন্য একটি শিক্ষানবিস গাইড, এটি Android-এর জন্য একটি শিক্ষানবিস গাইড হবে না – তাই আপনার কমপক্ষে একটি বা দুটি অ্যাপ্লিকেশন তৈরি করা উচিত (যদিও রচনায় নয়, অগত্যা)৷
আমরা শুরু করার আগে, আমি লেল্যান্ড রিচার্ডসনের দুটি অংশের নিবন্ধ সিরিজে না আসা পর্যন্ত আরও সিনিয়র ডেভেলপারদের দিকে নির্দেশিত একটি ফলো-আপ নিবন্ধ লেখার পরিকল্পনা করছিলাম। লেল্যান্ড শুধুমাত্র জেটপ্যাক কম্পোজ টিমে কাজ করা একজন সফটওয়্যার ইঞ্জিনিয়ার নন, কিন্তু আমি দেখতে পাচ্ছি যে তিনি একজন মহান লেখকও।
যদিও আমি মনে করি আমার নিবন্ধটি জেটপ্যাক কম্পোজের মৌলিক বিষয়গুলির একটি ভূমিকা হিসেবে দাঁড়াবে, আমি দৃঢ়ভাবে পরামর্শ দিচ্ছি আপনি রচনার সাথে কিছু বাস্তব অভিজ্ঞতা অর্জন করার পরে আপনি তার নিবন্ধগুলি পড়েন (অথবা আপনি যদি সেভাবে শিখতে চান তবে এখনই)।
এই নিবন্ধে ব্যাখ্যা করা মূল শর্তাবলী/ধারণা:
- পুরানো ভিউ সিস্টেম এবং হায়ারার্কির একটি সংক্ষিপ্ত পর্যালোচনা
- কম্পোজেবল এবং কিভাবে তারা ভিউ এর সাথে সম্পর্ক রাখে
- রিকম্পোজিশন এবং কীভাবে এটি খুব খারাপভাবে করা এড়ানো যায়!
একটি রচনাযোগ্য কি?
এই বিভাগে, আমরা জেটপ্যাক কম্পোজ লাইব্রেরির সবচেয়ে মৌলিক অংশ নিয়ে আলোচনা করব। আপনি যদি একজন অভিজ্ঞ অ্যান্ড্রয়েড ডেভেলপার হন, তাহলে আপনি "কম্পোজেবল ভিউ কি?" শিরোনামের উপ-বিভাগে যেতে চাইতে পারেন।
আপনি যদি ভিউ সিস্টেমের সাথে আগে থেকেই পরিচিত না হন তবে আপনার পরবর্তী বিভাগটি পড়া উচিত কারণ এটি অনুপ্রাণিত করা এবং বোঝার জন্য প্রয়োজনীয় যে একটি কম্পোজেবল কী৷
ক্রমক্রম দেখুন
অ্যান্ড্রয়েড SDK (এই প্ল্যাটফর্মে ইউজার ইন্টারফেস তৈরি করতে আমরা যে লাইব্রেরিগুলি ব্যবহার করি) প্রসঙ্গে, একটি ভিউ হল যা আমরা আমাদের অ্যাপ্লিকেশনগুলিতে গঠন এবং শৈলী দেওয়ার জন্য ব্যবহার করি৷
এটি একটি প্রদত্ত ইউজার ইন্টারফেসের (UI) বিল্ডিং ব্লক বা উপাদানগুলির সবচেয়ে মৌলিক ধরনের, এবং এই বিল্ডিং ব্লকগুলির প্রতিটিতে নিম্নলিখিত ধরণের তথ্য থাকবে (অন্যান্য জিনিসগুলির মধ্যে):
- X এবং Y শুরু এবং শেষ অবস্থান যা কম্পিউটারকে বলে যে ডিভাইসের স্ক্রিনে কোথায় ভিউ আঁকতে হবে
- রঙ এবং আলফা (স্বচ্ছতা) মান
- ফন্টের তথ্য, পাঠ্য, প্রতীক এবং ছবি
- ব্যবহারকারীর ইন্টারঅ্যাকশন (ক্লিক) বা অ্যাপ্লিকেশনের ডেটাতে পরিবর্তনের মতো ইভেন্টের উপর ভিত্তি করে আচরণ (পরে আরও কিছু)
এটা বোঝা গুরুত্বপূর্ণ যে একটি ভিউ একটি বোতামের মত কিছু হতে পারে (সাধারণত একটি "উইজেট" হিসাবে উল্লেখ করা হয়), তবে এটি পুরো স্ক্রীনের একটি ধারক, স্ক্রিনের অংশ বা অন্যান্য শিশু দর্শনের জন্যও হতে পারে .
যেমন পাত্র প্রেক্ষাপটের উপর নির্ভর করে সাধারণত লেআউট বা ভিউগ্রুপ হিসাবে উল্লেখ করা হয়। এবং, উইজেট হিসাবে একই ধরণের বেশিরভাগ তথ্য ভাগ করার সময়, সেগুলিতে নেস্টেড অন্যান্য ভিউগুলি কীভাবে সাজানো এবং প্রদর্শন করা যায় সে সম্পর্কেও তথ্য থাকে। তাদের মধ্যে।
এটি মাথায় রেখে, আমরা ভিউ সিস্টেমের এই পর্যালোচনার গুরুত্বপূর্ণ অংশে পৌঁছেছি:ভিউ হায়ারার্কি . ওয়েব ডেভেলপারদের জন্য, ভিউ হায়ারার্কি মূলত ডকুমেন্ট অবজেক্ট মডেলের (DOM) Android এর সংস্করণ।
অ্যান্ড্রয়েড ডেভেলপারদের জন্য, আপনি XML ফাইলে বা জাভা বা কোটলিনে প্রোগ্রাম্যাটিকভাবে সংজ্ঞায়িত সমস্ত ভিউগুলির ভার্চুয়াল উপস্থাপনা হিসাবে ভিউ হায়ারার্কিকে ভাবতে পারেন৷
এটি ব্যাখ্যা করার জন্য, আসুন এই জাতীয় একটি XML ফাইল দেখি (এটি ঘনিষ্ঠভাবে অধ্যয়নের প্রয়োজন নেই, কেবল নামগুলি নোট করুন)। তারপর, একটি ডিবাগার/স্টেপার টুল ব্যবহার করে, আমরা দেখব যে ফ্র্যাগমেন্টের মেমরি স্পেসে এটি কেমন দেখাচ্ছে যা এই ফাইলটিকে ফুলিয়ে দেয়:
fragment_hour_view.xml:
<?xml version=”1.0" encoding=”utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=”https://schemas.android.com/apk/res/android"
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:id=”@+id/root_hour_view_fragment”
xmlns:app=”https://schemas.android.com/apk/res-auto"
>
<androidx.compose.ui.platform.ComposeView
android:id=”@+id/tlb_hour_view”
//...
/>
<com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView
android:id=”@+id/vqht_one”
//...
/>
<com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView
android:id=”@+id/vqht_two”
//...
/>
<com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView
android:id=”@+id/vqht_three”
//...
/>
<com.wiseassblog.samsaradayplanner.ui.managehourview.HourToggleView
android:id=”@+id/vqht_four”
//...
/>
</androidx.constraintlayout.widget.ConstraintLayout>
(Fragment)HourView.kt: এর মেমরি স্পেস
আমি বিভিন্ন লাইব্রেরি থেকে যে কোডটি ব্যবহার করি তার হুডের নীচে কী চলছে সে সম্পর্কে জানতে ডিবাগার এবং স্টেপার টুলগুলি হল আমার প্রিয় কিছু উপায়। একটু সময় করে দেখুন!
আপনাকে এই XML ফাইলটি দেখানোর উদ্দেশ্য এবং এটি একটি প্রক্রিয়াতে কী পরিণত হয় (একটি প্রক্রিয়া হল একটি প্রোগ্রাম যা চলছে একটি ডিভাইসে), একটি এক্সএমএল ফাইলের নেস্টেড ভিউ কিভাবে রানটাইমে নেস্টেড ভিউ হায়ারার্কিতে অনুবাদ করে তা প্রদর্শন করা হয়।
আশা করি, পুরানো সিস্টেম কীভাবে কাজ করে তার একটি সহজ কিন্তু কংক্রিট মডেলের সাথে, আমরা এটিকে নতুনটির সাথে তুলনা করতে পারি৷
কম্পোজেবল ভিউ কি?
আমি যখন কম্পোজের সাথে কাজ শুরু করি তখন আমি যে প্রথম প্রশ্নগুলি জিজ্ঞাসা করেছি তার মধ্যে এটি একটি ছিল এবং আমি যে উত্তরে পৌঁছেছি তা হল হ্যাঁ এবং না .
হ্যাঁ , এই অর্থে যে একটি কম্পোজেবল একটি ভিউ হিসাবে একই ধারণাগত ভূমিকা পূরণ করে পুরানো সিস্টেমে। একটি কম্পোজেবল একটি বোতামের মতো একটি উইজেট হতে পারে, বা একটি ধারক যেমন একটি কন্সট্রেন্ট লেআউট হতে পারে (এটি লক্ষণীয় যে সীমাবদ্ধতার একটি কম্পোজেবল বাস্তবায়ন উপলব্ধ রয়েছে)।
না৷ , এই অর্থে যে UI আর কার্যতভাবে একটি ভিউ হায়ারার্কিতে প্রতিনিধিত্ব করা হয় না (আন্তঃক্রিয়াশীলতার সাথে জড়িত পরিস্থিতিগুলি ছাড়াও)। এটি বলার সাথে সাথে, রচনা কার্যত প্রতিনিধিত্ব করতে এবং UI এর ট্র্যাক রাখতে যাদু ব্যবহার করে না। এর মানে হল যে এটির নিজস্ব জিনিস থাকতে হবে যা ধারণাগতভাবে একটি ভিউ হায়ারার্কির মতো।
আসুন এই জিনিসটি খুব সংক্ষিপ্তভাবে দেখে নেওয়া যাক। এখানে, আমাদের একটি কার্যকলাপ আছে যা setContent {…}
ব্যবহার করে একটি কম্পোজেবলকে নিজের সাথে আবদ্ধ করার ফাংশন:
ActiveGameActivity.kt:
class ActiveGameActivity : AppCompatActivity(), ActiveGameContainer {
private lateinit var logic: ActiveGameLogic
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel = ActiveGameViewModel()
setContent {
ActiveGameScreen(
onEventHandler = {
logic.onEvent(it)
},
viewModel
)
}
logic = buildActiveGameLogic(this, viewModel, applicationContext)
}
//…
}
ActiveGameScreen.kt:
@Composable
fun ActiveGameScreen(
onEventHandler: ((ActiveGameEvent) -> Unit),
viewModel: ActiveGameViewModel
) {
//...
GraphSudokuTheme {
Column(
Modifier
.background(MaterialTheme.colors.primary)
.fillMaxHeight()
) {
ActiveGameToolbar(
clickHandler = {
onEventHandler.invoke(
ActiveGameEvent.OnNewGameClicked
)
}
)
Box {
//content
}
}
}
}
কম্পোজে, ভিউ হায়ারার্কি এমন কিছু দিয়ে প্রতিস্থাপিত হয় যা আমরা যদি সত্যিই গভীরভাবে mWindow খনন করি তাহলে আমরা তা সনাক্ত করতে পারি। এই কার্যকলাপের ক্ষেত্র। সেই ক্ষেত্রের মধ্যে ভিউ হায়ারার্কির ধারণাগত প্রতিস্থাপন:The Composer
এবং এর slotTable
।
এই মুহুর্তে, আপনি যদি Composer
এর বিস্তারিত ওভারভিউ চান এবং এর slotTable
, আমাকে আবারও পরামর্শ দিতে হবে যে আপনি লেল্যান্ডের নিবন্ধটি পড়বেন (তিনি 2 অংশে বিস্তারিতভাবে যান)। কম্পোজার এবং এর স্লট টেবিলের চেয়ে কম্পোজ হায়ারার্কিতে আরও অনেক কিছু আছে, কিন্তু এটি আমাদের শুরু করার জন্য যথেষ্ট হওয়া উচিত।
সাধারণ পরিভাষায়, জেটপ্যাক কম্পোজ ব্যবহার করে যাকে আমরা এর কম্পোজ হায়ারার্কি বলতে পারি (যা কম্পোজার এবং এর স্লটটেবলের মতো জিনিস দিয়ে তৈরি এবং পরিচালিত হয়)।
আবার, এটি ভিউ হায়ারার্কির মতো একই ধারণাগত ধারণা, মেমরি স্পেসে একগুচ্ছ অবজেক্ট যা সম্মিলিতভাবে UI-এর প্রতিনিধিত্ব করে, কিন্তু এটি খুব ভিন্নভাবে প্রয়োগ করা হয়।
যদিও একটি গুরুত্বপূর্ণ পার্থক্য রয়েছে, যা প্রযুক্তিগতভাবে বোঝা কঠিন, কিন্তু নীতিগতভাবে বোঝা সহজ। এইভাবে কম্পোজ কম্পোজ হায়ারার্কির আপডেটগুলি পরিচালনা করে:পুনঃকম্পোজিশন .
রিকম্পোজিশন:কিভাবে কম্পোজ UI আপডেট করবেন
আমার ESL বন্ধুদের জন্য, কম্পোজ শব্দটি ল্যাটিন componere থেকে এসেছে , যার মোটামুটি অর্থ "একত্র করা।" যে ব্যক্তি সঙ্গীত লেখেন তাকে প্রায়শই "কম্পোজার" বলা হয়, যাকে ভাবা যেতে পারে যে এক বা একাধিক যন্ত্র থেকে আসা নোটগুলিকে একটি রচনায় (গান) একত্রিত করে।
একসাথে করা বোঝায় যে পৃথক টুকরা আছে. এটা বোঝা গুরুত্বপূর্ণ যে প্রায় যেকোনো ভালো সফ্টওয়্যার বিকাশকারী তাদের কোডকে ছোটতম যুক্তিসঙ্গত অংশে ভাঙার জন্য অন্তত কিছু প্রচেষ্টা করে থাকে .
আমি যুক্তিসঙ্গত উল্লেখ করছি , কারণ আমি মনে করি DRY (নিজের পুনরাবৃত্তি করবেন না) এর মতো নীতিগুলি কেবলমাত্র সেই পরিমাণে অনুসরণ করা উচিত যাতে তারা তাদের তৈরির চেয়ে বেশি সমস্যার সমাধান করে।
এই ধারণাটি প্রয়োগ করার অনেক সুবিধা রয়েছে, যাকে প্রায়শই মডুলারিটি বলা হয়, (বা আমি যেমন পছন্দ করি, সেপারেশন অফ কনসার্নস, বা SOC)। আমি সচেতন যে আপনারা কেউ কেউ এটা পড়ে মনে করতে পারেন যে আমি লেল্যান্ড তার নিবন্ধে যা বলেছেন তা অনুলিপি করছি, কিন্তু আমি বহু বছর ধরে সফ্টওয়্যার আর্কিটেকচারের গোল্ডেন প্রিন্সিপল হিসাবে SOC সম্পর্কে কথা বলে আসছি।
যেখানে এটি রচনায় চলে, একই নীতি যা আমরা জনপ্রিয় জাভাস্ক্রিপ্ট লাইব্রেরিতে দেখতে পাই প্রতিক্রিয়া . সঠিকভাবে সম্পন্ন হলে, রচনা শুধুমাত্র "পুনঃকম্পোজ" (পুনরায় আঁকবে, পুনরায় রেন্ডার, আপডেট, যাই হোক না কেন) কম্পোজেবল (ইউআই-এর অংশ/উপাদান) যা পুনঃকম্পোজ করতে হবে।
এটি যখন একটি অ্যাপ্লিকেশনের কর্মক্ষমতা আসে তখন এটি অত্যন্ত গুরুত্বপূর্ণ। এর কারণ হল UI পুনরায় অঙ্কন করা, তা পুরানো ভিউ সিস্টেমে বা কম্পোজে, সিস্টেম সংস্থানগুলির জন্য ব্যয়বহুল৷
আপনি যদি সচেতন না হন, পুরানো রিসাইক্লারভিউ-এর সম্পূর্ণ উদ্দেশ্য (যা আমি 2016 সালে প্রথম একটি টিউটোরিয়াল তৈরি করেছিলাম!) ছিল ডেটার একটি তালিকায় ভিউহোল্ডার প্যাটার্ন নিয়োগ করা। এটি প্রতিটি তালিকা আইটেমের জন্য ক্রমাগত নতুন ভিউ বৃদ্ধি (বানান) করার প্রয়োজন এড়ায়৷
এই নিবন্ধে আমার লক্ষ্য ছিল বেশিরভাগ তত্ত্বের উপর ফোকাস করা, কারণ আমি আগামী কয়েক মাসে প্রচুর ব্যবহারিক বিষয়বস্তু লিখব। যাইহোক, আমি আমার প্রত্যক্ষ অভিজ্ঞতা থেকে একটি গল্প দিয়ে নিবন্ধটি শেষ করব, যা আপনাকে আরও বুঝতে সাহায্য করবে কীভাবে পুনর্গঠন কাজ করে এবং কীভাবে এটি খুব খারাপভাবে করা এড়াতে হয়!
স্টপওয়াচের উদাহরণ
আমার প্রথম সম্পূর্ণ রচনা অ্যাপ্লিকেশনের জন্য, আমি সুডোকু তৈরি করার সিদ্ধান্ত নিয়েছি। অনেকগুলি কারণ রয়েছে, যার মধ্যে আমি এমন একটি প্রকল্প চেয়েছিলাম যার মধ্যে একটি অত্যন্ত জটিল UI ছিল না। আমি গ্রাফ ডিএস এবং অ্যালগোসে গভীরভাবে ডুব দেওয়ার সুযোগও চেয়েছিলাম, যা সুডোকু পাজলগুলির জন্য বেশ উপযুক্ত৷
আমি একটি জিনিস চেয়েছিলাম একটি স্টপওয়াচ যা ব্যবহারকারীর একটি ধাঁধা সম্পূর্ণ করতে কতক্ষণ সময় নেয় তা ট্র্যাক করবে:
আমার পেশার ক্ষেত্রে প্রায়শই যেমন হয়, আমি আশা করেছিলাম যে এই টাইমারটি যোগ করা অনেক সহজ হবে। আমি অ্যান্ড্রয়েডের ক্রোনোমিটার ক্লাসের পাশাপাশি জাভা টাইমার ক্লাসের সাথে তালগোল পাকিয়েছি এবং উভয়ই ভিন্ন কিন্তু এখনও অ্যাপ্লিকেশন-ব্রেকিং সমস্যা উপস্থাপন করেছে।
অবশেষে আমি একধাপ পিছিয়ে গেলাম এবং বুঝতে পারলাম যে আমি কোটলিনে লিখছি। তাই আমি আমার প্রেজেন্টেশন লজিক ক্লাসে একটি Coroutine ভিত্তিক টাইমার সেট আপ করেছি (এটি সেখানে রাখা সবচেয়ে বেশি বোধগম্য হয়েছে), যা প্রতি সেকেন্ডে আমার ভিউমডেল আপডেট করবে:
Class ActiveGameLogic(…):…{
//…
inline fun startCoroutineTimer(
delayMillis: Long = 0,
repeatMillis: Long = 1000,
crossinline action: () -> Unit
) = launch {
delay(delayMillis)
if (repeatMillis > 0) {
while (true) {
action()
delay(repeatMillis)
}
} else {
action()
}
}
private fun onStart() =
launch {
gameRepo.getCurrentGame(
{ puzzle, isComplete ->
viewModel.initializeBoardState(
puzzle,
isComplete
)
if (!isComplete) timerTracker = startCoroutineTimer {
viewModel.updateTimerState()
}
},{
container?.onNewGameClick()
})
}
//…
}
ভিউমডেল (AAC থেকে নয় - আমি আমার নিজের VM লিখি। কিন্তু কম্পোজের ইতিমধ্যেই AAC VM-এর সাথে ভালো ইন্টারঅপারেবিলিটি আছে যা আমি দেখতে পাচ্ছি।) কলব্যাক ফাংশনের রেফারেন্স প্রকাশ করেছে, যা আমি আমার কম্পোজেবল আপডেট করতে ব্যবহার করব:
class ActiveGameViewModel {
//…
internal var subTimerState: ((Long) -> Unit)? = null
internal var timerState: Long = 0L
//…
internal fun updateTimerState(){
timerState++
subTimerState?.invoke(timerState)
}
//…
}
এখন গুরুত্বপূর্ণ অংশ আসে! আমরা রচনার নির্দিষ্ট বৈশিষ্ট্যগুলি ব্যবহার করে রচনা অনুক্রমের পুনর্গঠন ট্রিগার করতে পারি, যেমন remember
ফাংশন:
var timerState by remember {
mutableStateOf(“”)
}
আপনি যদি জানেন যে, এই বৈশিষ্ট্যগুলি আপনি slotTable
-এ যা কিছু মনে করছেন তার অবস্থা সংরক্ষণ করে৷ . সংক্ষেপে, এখানে রাজ্য শব্দের অর্থ হল ডেটার বর্তমান "স্টেট", যা শুধুমাত্র একটি খালি স্ট্রিং থেকে শুরু হয়।
এখানেই আমি জিনিসগুলি খারাপ করেছি . আমি আমার সাধারণ টাইমার কম্পোজেবলকে তার নিজস্ব ফাংশনে (প্রয়োগিত SOC) টেনে নিয়েছিলাম এবং আমি timerState
এ পাস করছিলাম সেই কম্পোজেবলের প্যারামিটার হিসেবে।
যাইহোক, উপরের স্নিপেটগুলি টাইমারের প্যারেন্ট কম্পোজেবলে বসে ছিল, যা UI এর সবচেয়ে জটিল অংশের জন্য একটি ধারক ছিল (একটি 9x9 সুডোকুতে প্রচুর সংখ্যক উইজেট প্রয়োজন):
@Composable
fun GameContent(
onEventHandler: (ActiveGameEvent) -> Unit,
viewModel: ActiveGameViewModel
) {
Surface(
Modifier
.wrapContentHeight()
.fillMaxWidth()
) {
BoxWithConstraints(Modifier.background(MaterialTheme.colors.primary)) {
//…
ConstraintLayout {
val (board, timer, diff, inputs) = createRefs()
var isComplete by remember {
mutableStateOf(false)
}
var timerState by remember {
mutableStateOf("")
}
viewModel.subTimerState = {
timerState = it.toTime()
}
viewModel.subIsCompleteState = { isComplete = it }
//…Sudoku board
//Timer
Box(Modifier
.wrapContentSize()
.constrainAs(timer) {
top.linkTo(board.bottom)
start.linkTo(parent.start)
}
.padding(start = 16.dp))
{
TimerText(timerState)
}
//…difficulty display
//…Input buttons
}
}
}
}
@Composable
fun TimerText(timerState: String) {
Text(
text = timerState,
style = activeGameSubtitle.copy(color = MaterialTheme.colors.secondary)
)
}
এটি কিছু যথেষ্ট ব্যবধান এবং প্রতিক্রিয়াহীনতার কারণ ছিল। ডিবাগারের ভারী ব্যবহার করে, আমি কেন তা খুঁজে বের করতে সক্ষম হয়েছিলাম। কারণ আমার timerState
প্যারেন্ট কম্পোজেবলের ভিতরে ভেরিয়েবল তৈরি এবং আপডেট করা হয়েছিল, এটি UI এর পুরো অংশের পুনর্গঠনকে ট্রিগার করছে। প্রতিটি। একক টিক দিন
উপযুক্ত কোডটি TimerText
-এ সরানোর পর রচনাযোগ্য, জিনিসগুলি খুব মসৃণভাবে কাজ করেছে:
@Composable
fun TimerText(viewModel: ActiveGameViewModel) {
var timerState by remember {
mutableStateOf("")
}
viewModel.subTimerState = {
timerState = it.toTime()
}
Text(
text = timerState,
style = activeGameSubtitle.copy(color = MaterialTheme.colors.secondary)
)
}
আশা করি আমি আপনাকে পুনর্গঠনের একটি কার্যকরী বোঝাপড়া এবং এটি ভুলভাবে করার সবচেয়ে বড় উপায়গুলির মধ্যে একটি দিয়েছি।
অপ্রয়োজনীয় পুনর্গঠন এড়ানো কার্যক্ষমতার জন্য অবিশ্বাস্যভাবে গুরুত্বপূর্ণ। এবং এখন পর্যন্ত মনে হচ্ছে যে SOC কঠোরভাবে প্রয়োগ করা, এমনকি আলাদা কম্পোজেবলে মনে রাখার অবস্থা পর্যন্ত, মান অভ্যাস হওয়া উচিত৷
সম্পদ ও সমর্থন
আপনি যদি এই নিবন্ধটি পছন্দ করেন, অনুগ্রহ করে এটি সোশ্যাল মিডিয়াতে শেয়ার করুন এবং এখানে freeCodeCamp-এ আমার অন্যান্য নিবন্ধগুলি দেখুন৷ আমার শতাধিক টিউটোরিয়াল সহ একটি YouTube চ্যানেলও রয়েছে এবং আমি বিভিন্ন প্ল্যাটফর্মে একজন সক্রিয় লেখক।
সোশ্যাল মিডিয়াতে আমার সাথে সংযোগ করুন
আপনি আমাকে এখানে ইনস্টাগ্রামে এবং এখানে টুইটারে খুঁজে পেতে পারেন৷
৷এছাড়াও, আমি জেটপ্যাক কম্পোজের সাথে শুরু করার জন্য যে একক সংস্থানটি ব্যবহার করেছি তা নির্দেশ করতে চাই:ভাল বিকাশকারীদের থেকে কার্যকরী কোড নমুনা।