কম্পাইল-টাইম স্টেট ভ্যালিডেশন সহ শক্তিশালী স্টেট মেশিন তৈরি করতে টাইপস্ক্রিপ্ট টেমপ্লেট লিটারেল টাইপগুলি কীভাবে ব্যবহার করবেন তা শিখুন, যা টাইপ সুরক্ষা নিশ্চিত করে এবং রানটাইম ত্রুটিগুলি প্রতিরোধ করে। বিশ্বব্যাপী সফটওয়্যার উন্নয়ন দলের জন্য উপযুক্ত।
টাইপস্ক্রিপ্ট টেমপ্লেট লিটারেল স্টেট মেশিন: কম্পাইল-টাইম স্টেট ভ্যালিডেশন
সফটওয়্যার ডেভেলপমেন্টের সর্বদা পরিবর্তনশীল ল্যান্ডস্কেপে, কোড কোয়ালিটি বজায় রাখা এবং রানটাইম ত্রুটিগুলি প্রতিরোধ করা অত্যন্ত গুরুত্বপূর্ণ। টাইপস্ক্রিপ্ট, এর শক্তিশালী টাইপিং সিস্টেমের সাথে, এই লক্ষ্যগুলি অর্জনের জন্য একটি শক্তিশালী অস্ত্র সরবরাহ করে। একটি বিশেষভাবে মার্জিত কৌশল হল টেমপ্লেট লিটারেল টাইপগুলির ব্যবহার, যা আমাদের কম্পাইল-টাইম ভ্যালিডেশন করতে দেয়, বিশেষ করে স্টেট মেশিন তৈরির সময় এটি বিশেষভাবে উপযোগী। এই পদ্ধতিটি কোডের নির্ভরযোগ্যতা উল্লেখযোগ্যভাবে বৃদ্ধি করে, যা বিভিন্ন প্রকল্প এবং সময় অঞ্চলে কাজ করা বিশ্বব্যাপী সফটওয়্যার উন্নয়ন দলগুলির জন্য একটি মূল্যবান সম্পদ তৈরি করে।
কেন স্টেট মেশিন?
স্টেট মেশিন, যা ফাইনাইট স্টেট মেশিন (FSM) নামেও পরিচিত, কম্পিউটার বিজ্ঞানের মৌলিক ধারণা। তারা এমন সিস্টেমগুলিকে উপস্থাপন করে যা একটি সীমিত সংখ্যক স্টেটের মধ্যে থাকতে পারে, নির্দিষ্ট ঘটনা বা ইনপুটের উপর ভিত্তি করে এই স্টেটগুলির মধ্যে পরিবর্তিত হতে পারে। উদাহরণস্বরূপ, একটি সাধারণ অর্ডার প্রসেসিং সিস্টেম বিবেচনা করুন: একটি অর্ডার 'পেন্ডিং', 'প্রসেসিং', 'শিপড' বা 'ডেলিভারড'-এর মতো স্টেটগুলিতে থাকতে পারে। স্টেট মেশিনগুলির সাথে এই ধরনের সিস্টেমগুলি বাস্তবায়ন করলে লজিক আরও পরিষ্কার, আরও পরিচালনাযোগ্য এবং ত্রুটি প্রবণতা কম হয়।
সঠিক ভ্যালিডেশন ছাড়া, স্টেট মেশিনগুলি সহজেই বাগের উৎস হতে পারে। কল্পনা করুন ভুলবশত 'পেন্ডিং' থেকে সরাসরি 'ডেলিভারড'-এ চলে যাওয়া, গুরুত্বপূর্ণ প্রসেসিং ধাপগুলি এড়িয়ে যাওয়া। এখানেই কম্পাইল-টাইম ভ্যালিডেশন উদ্ধার করতে আসে। টাইপস্ক্রিপ্ট এবং টেমপ্লেট লিটারেল টাইপ ব্যবহার করে, আমরা বৈধ পরিবর্তনগুলি প্রয়োগ করতে পারি এবং বিকাশের পর্যায় থেকে অ্যাপ্লিকেশনটির অখণ্ডতা নিশ্চিত করতে পারি।
টেমপ্লেট লিটারেল টাইপগুলির শক্তি
টাইপস্ক্রিপ্টের টেমপ্লেট লিটারেল টাইপগুলি আমাদের স্ট্রিং প্যাটার্নের উপর ভিত্তি করে টাইপগুলি সংজ্ঞায়িত করতে দেয়। এই শক্তিশালী বৈশিষ্ট্যটি সংকলনের সময় পরীক্ষা এবং ভ্যালিডেশন করার ক্ষমতা উন্মুক্ত করে। আমরা বৈধ স্টেট এবং পরিবর্তনের একটি সেট সংজ্ঞায়িত করতে পারি এবং এই টাইপগুলি ব্যবহার করে কোন স্টেট পরিবর্তনগুলি অনুমোদিত তা সীমাবদ্ধ করতে পারি। এই পদ্ধতিটি রানটাইম থেকে কম্পাইল টাইমে ত্রুটি সনাক্তকরণ সরিয়ে নেয়, উল্লেখযোগ্যভাবে ডেভেলপারদের উৎপাদনশীলতা এবং কোডবেসের দৃঢ়তা উন্নত করে, বিশেষ করে এমন দলগুলিতে যেখানে যোগাযোগ এবং কোড পর্যালোচনার ক্ষেত্রে ভাষার বাধা বা সময় অঞ্চলের পার্থক্য থাকতে পারে।
টেমপ্লেট লিটারেল টাইপগুলির সাথে একটি সাধারণ স্টেট মেশিন তৈরি করা
আসুন আমরা একটি ব্যবহারিক উদাহরণ দিয়ে এটি ব্যাখ্যা করি, একটি অর্ডার প্রসেসিং ওয়ার্কফ্লো। আমরা বৈধ স্টেট এবং পরিবর্তনের জন্য একটি টাইপ সংজ্ঞায়িত করব।
type OrderState = 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled';
type ValidTransitions = {
pending: 'processing' | 'cancelled';
processing: 'shipped' | 'cancelled';
shipped: 'delivered';
cancelled: never; // No transitions allowed from cancelled
delivered: never; // No transitions allowed from delivered
};
এখানে, আমরা একটি ইউনিয়ন টাইপ ব্যবহার করে সম্ভাব্য স্টেটগুলি সংজ্ঞায়িত করি: OrderState। তারপরে, আমরা ValidTransitions সংজ্ঞায়িত করি, যা একটি টাইপ যা প্রতিটি বর্তমান স্টেটের জন্য বৈধ পরবর্তী স্টেটগুলি বর্ণনা করতে একটি অবজেক্ট লিটারেল ব্যবহার করে। 'নেভার' একটি অবৈধ পরিবর্তন নির্দেশ করে, আরও স্টেট পরিবর্তনগুলি প্রতিরোধ করে। এখানেই জাদু ঘটে। টেমপ্লেট লিটারেল টাইপ ব্যবহার করে, আমরা নিশ্চিত করতে পারি যে শুধুমাত্র বৈধ স্টেট পরিবর্তনগুলি অনুমোদিত।
স্টেট মেশিন বাস্তবায়ন করা
এখন, আসুন আমাদের স্টেট মেশিনের মূল অংশ তৈরি করি, `Transition` টাইপ, যা একটি টেমপ্লেট লিটারেল টাইপ ব্যবহার করে পরিবর্তনগুলিকে সীমাবদ্ধ করে।
type Transition<CurrentState extends OrderState, NextState extends keyof ValidTransitions> =
NextState extends keyof ValidTransitions
? CurrentState extends keyof ValidTransitions
? NextState extends ValidTransitions[CurrentState]
? NextState
: never
: never
: never;
interface StateMachine<S extends OrderState> {
state: S;
transition<T extends Transition<S, OrderState>>(nextState: T): StateMachine<T>;
}
function createStateMachine<S extends OrderState>(initialState: S): StateMachine<S> {
return {
state: initialState,
transition(nextState) {
return createStateMachine(nextState as any);
},
};
}
আসুন এটি ভেঙে দেখি:
Transition<CurrentState, NextState>: এই জেনেরিক টাইপটিCurrentStateথেকেNextState-এ পরিবর্তনের বৈধতা নির্ধারণ করে।- টার্নারি অপারেটরগুলি পরীক্ষা করে যে
NextState`ValidTransitions`-এ বিদ্যমান কিনা এবং বর্তমান স্টেটের উপর ভিত্তি করে পরিবর্তনটি অনুমোদিত কিনা। - যদি পরিবর্তনটি অবৈধ হয়, তাহলে টাইপটি
never-এ সমাধান হয়, যার ফলে একটি কম্পাইল-টাইম ত্রুটি ঘটে। StateMachine<S extends OrderState>: আমাদের স্টেট মেশিন ইন্সটেন্সের জন্য ইন্টারফেস সংজ্ঞায়িত করে।transition<T extends Transition<S, OrderState>>: এই পদ্ধতিটি টাইপ-সুরক্ষিত পরিবর্তনগুলি প্রয়োগ করে।
আসুন এর ব্যবহার প্রদর্শন করি:
const order = createStateMachine('pending');
// Valid transitions
const processingOrder = order.transition('processing'); // OK
const cancelledOrder = order.transition('cancelled'); // OK
// Invalid transitions (will cause a compile-time error)
// @ts-expect-error
const shippedOrder = order.transition('shipped');
// Correct transitions after processing
const shippedAfterProcessing = processingOrder.transition('shipped'); // OK
// Invalid transitions after shipped
// @ts-expect-error
const cancelledAfterShipped = shippedAfterProcessing.transition('cancelled'); // ERROR
মন্তব্যগুলি যেমন চিত্রিত করে, আপনি যদি কোনও অবৈধ স্টেটে যাওয়ার চেষ্টা করেন তবে টাইপস্ক্রিপ্ট একটি ত্রুটি জানাবে। এই কম্পাইল-টাইম চেক অনেক সাধারণ বাগ প্রতিরোধ করে, কোডের গুণমান উন্নত করে এবং বিভিন্ন উন্নয়ন পর্যায়ে ডিবাগিংয়ের সময় হ্রাস করে, যা বিভিন্ন অভিজ্ঞতার স্তর এবং বিশ্বব্যাপী অবদানকারীদের দলগুলির জন্য বিশেষভাবে মূল্যবান।
কম্পাইল-টাইম স্টেট ভ্যালিডেশনের সুবিধা
স্টেট মেশিন ভ্যালিডেশনের জন্য টেমপ্লেট লিটারেল টাইপ ব্যবহারের সুবিধাগুলি উল্লেখযোগ্য:
- টাইপ সুরক্ষা: নিশ্চিত করে যে স্টেট পরিবর্তনগুলি সর্বদা বৈধ, ভুল স্টেট পরিবর্তনের কারণে রানটাইম ত্রুটিগুলি প্রতিরোধ করে।
- আর্লি এরর ডিটেকশন: রানটাইমে নয়, বিকাশের সময় ত্রুটি ধরা পড়ে, ফলে দ্রুত ডিবাগিং চক্র ঘটে। দ্রুত পুনরাবৃত্তি অপরিহার্য এমন এজাইল পরিবেশে এটি অত্যন্ত গুরুত্বপূর্ণ।
- উন্নত কোড পাঠযোগ্যতা: স্টেট পরিবর্তনগুলি স্পষ্টভাবে সংজ্ঞায়িত করা হয়েছে, যা স্টেট মেশিনের আচরণ বোঝা এবং বজায় রাখা সহজ করে তোলে।
- উন্নত রক্ষণাবেক্ষণযোগ্যতা: নতুন স্টেট যোগ করা বা পরিবর্তনগুলি পরিবর্তন করা নিরাপদ, কারণ কম্পাইলার নিশ্চিত করে যে কোডের সমস্ত প্রাসঙ্গিক অংশ সেই অনুযায়ী আপডেট করা হয়েছে। দীর্ঘ জীবনচক্র এবং ক্রমবর্ধমান প্রয়োজনীয়তা সহ প্রকল্পগুলির জন্য এটি বিশেষভাবে গুরুত্বপূর্ণ।
- রিফ্যাক্টরিং সমর্থন: টাইপস্ক্রিপ্টের টাইপ সিস্টেম রিফ্যাক্টরিংয়ে সহায়তা করে, পরিবর্তনগুলি সম্ভাব্য সমস্যাগুলি উপস্থাপন করলে স্পষ্ট প্রতিক্রিয়া সরবরাহ করে।
- সহযোগিতা সুবিধা: দলের সদস্যদের মধ্যে ভুল বোঝাবুঝি হ্রাস করে, বিশেষত বিশ্বব্যাপী বিতরণ করা দলগুলিতে সহায়ক যেখানে স্পষ্ট যোগাযোগ এবং ধারাবাহিক কোড শৈলী অপরিহার্য।
গ্লোবাল বিবেচনা এবং ব্যবহারের ক্ষেত্র
এই পদ্ধতিটি আন্তর্জাতিক দল এবং বিভিন্ন উন্নয়ন পরিবেশের প্রকল্পগুলির জন্য বিশেষভাবে উপকারী। এই বিশ্ব ব্যবহারের ক্ষেত্রগুলি বিবেচনা করুন:
- ই-কমার্স প্ল্যাটফর্ম: 'পেন্ডিং' থেকে 'প্রসেসিং' থেকে 'শিপড' এবং অবশেষে 'ডেলিভারড' পর্যন্ত অর্ডারের জটিল জীবনচক্র পরিচালনা করা। বিভিন্ন আঞ্চলিক বিধিবিধান এবং পেমেন্ট গেটওয়েগুলি স্টেট পরিবর্তনের মধ্যে অন্তর্ভুক্ত করা যেতে পারে।
- ওয়ার্কফ্লো অটোমেশন: ডকুমেন্ট অনুমোদন বা কর্মচারী অনবোর্ডিংয়ের মতো ব্যবসায়িক প্রক্রিয়া স্বয়ংক্রিয় করা। বিভিন্ন আইনি প্রয়োজনীয়তা সহ বিভিন্ন স্থানে ধারাবাহিক আচরণ নিশ্চিত করুন।
- মাল্টি-ল্যাঙ্গুয়েজ অ্যাপ্লিকেশন: বিভিন্ন ভাষা এবং সংস্কৃতির জন্য ডিজাইন করা অ্যাপ্লিকেশনগুলিতে স্টেট-নির্ভর টেক্সট এবং ইউআই উপাদানগুলি পরিচালনা করা। বৈধ পরিবর্তনগুলি অপ্রত্যাশিত প্রদর্শনের সমস্যাগুলি প্রতিরোধ করে।
- আর্থিক সিস্টেম: আর্থিক লেনদেনের স্টেট পরিচালনা করা, যেমন 'অনুমোদিত', 'প্রত্যাখ্যান', 'সম্পন্ন'। বিশ্বব্যাপী আর্থিক বিধিবিধানের সাথে সম্মতি নিশ্চিত করা।
- সরবরাহ চেইন ম্যানেজমেন্ট: সরবরাহ চেইনের মাধ্যমে পণ্যের চলাচল ট্র্যাক করা। এই পদ্ধতিটি ধারাবাহিক ট্র্যাকিং নিশ্চিত করে এবং শিপিং এবং ডেলিভারিতে ত্রুটি প্রতিরোধ করে, বিশেষত জটিল বিশ্ব সরবরাহ চেইনে।
এই উদাহরণগুলি এই কৌশলটির বিস্তৃত প্রয়োগযোগ্যতা তুলে ধরে। তদুপরি, কম্পাইল-টাইম ভ্যালিডেশন স্থাপনার আগে স্বয়ংক্রিয়ভাবে ত্রুটি সনাক্ত করতে CI/CD পাইপলাইনগুলিতে একত্রিত করা যেতে পারে, সামগ্রিক সফটওয়্যার উন্নয়ন জীবনচক্রকে উন্নত করে। ভৌগোলিকভাবে বিতরণ করা দলগুলির জন্য এটি বিশেষভাবে কার্যকর যেখানে ম্যানুয়াল টেস্টিং আরও চ্যালেঞ্জিং হতে পারে।
উন্নত কৌশল এবং অপটিমাইজেশন
বেসিক পদ্ধতি একটি শক্ত ভিত্তি সরবরাহ করার সময়, আপনি আরও উন্নত কৌশলগুলির সাথে এটি প্রসারিত করতে পারেন:
- প্যারামিটারাইজড স্টেটস: প্যারামিটার সহ স্টেটগুলি উপস্থাপন করতে টেমপ্লেট লিটারেল টাইপ ব্যবহার করুন, যেমন একটি স্টেট যা একটি অর্ডার আইডি অন্তর্ভুক্ত করে, যেমন
'order_processing:123'। - স্টেট মেশিন জেনারেটর: আরও জটিল স্টেট মেশিনগুলির জন্য, একটি কোড জেনারেটর তৈরি করার কথা বিবেচনা করুন যা একটি কনফিগারেশন ফাইলের (যেমন, JSON বা YAML) উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে টাইপস্ক্রিপ্ট কোড তৈরি করে। এটি প্রাথমিক সেটআপকে সহজ করে এবং ম্যানুয়াল ত্রুটির সম্ভাবনা হ্রাস করে।
- স্টেট মেশিন লাইব্রেরি: যদিও টাইপস্ক্রিপ্ট টেমপ্লেট লিটারেল টাইপগুলির সাথে একটি শক্তিশালী পদ্ধতি সরবরাহ করে, XState বা Robot-এর মতো লাইব্রেরিগুলি আরও উন্নত বৈশিষ্ট্য এবং পরিচালনা ক্ষমতা সরবরাহ করে। আপনার জটিল স্টেট মেশিনগুলিকে উন্নত এবং গঠন করতে সেগুলি ব্যবহার করার কথা বিবেচনা করুন।
- কাস্টম ত্রুটি বার্তা: সংকলনের সময় কাস্টম ত্রুটি বার্তা সরবরাহ করে ডেভেলপারদের অভিজ্ঞতা বাড়ান, ডেভেলপারদের সঠিক পরিবর্তনে গাইড করুন।
- স্টেট ম্যানেজমেন্ট লাইব্রেরির সাথে ইন্টিগ্রেশন: আপনার অ্যাপ্লিকেশনগুলির মধ্যে আরও জটিল স্টেট ম্যানেজমেন্টের জন্য রেডক্স বা জুস্ট্যান্ডের মতো স্টেট ম্যানেজমেন্ট লাইব্রেরির সাথে এটি একত্রিত করুন।
গ্লোবাল টিমগুলির জন্য সেরা অনুশীলন
এই কৌশলগুলি কার্যকরভাবে বাস্তবায়নের জন্য নির্দিষ্ট সেরা অনুশীলনগুলি মেনে চলা প্রয়োজন, বিশেষত ভৌগোলিকভাবে বিতরণ করা দলগুলির জন্য গুরুত্বপূর্ণ:
- স্পষ্ট ডকুমেন্টেশন: স্টেট পরিবর্তন এবং কোনও ব্যবসায়িক নিয়ম বা সীমাবদ্ধতা সহ স্টেট মেশিন ডিজাইনটি স্পষ্টভাবে ডকুমেন্টিং করুন। এটি বিশেষভাবে গুরুত্বপূর্ণ যখন দলের সদস্যরা বিভিন্ন সময় অঞ্চলে কাজ করছেন এবং কোনও প্রধান ডেভেলপারের তাৎক্ষণিক অ্যাক্সেস নাও থাকতে পারে।
- কোড পর্যালোচনা: সমস্ত স্টেট পরিবর্তন বৈধ কিনা এবং ডিজাইন প্রতিষ্ঠিত নিয়মগুলি মেনে চলছে কিনা তা নিশ্চিত করার জন্য পুঙ্খানুপুঙ্খ কোড পর্যালোচনা প্রয়োগ করুন। বিভিন্ন দৃষ্টিকোণের জন্য বিভিন্ন অঞ্চল থেকে পর্যালোচকদের উত্সাহিত করুন।
- সামঞ্জস্যপূর্ণ কোড শৈলী: কোডটি সহজেই পাঠযোগ্য এবং সমস্ত দলের সদস্যদের মধ্যে রক্ষণাবেক্ষণযোগ্য তা নিশ্চিত করার জন্য একটি সামঞ্জস্যপূর্ণ কোড শৈলী গাইড (যেমন, প্রিটিয়ারের মতো একটি সরঞ্জাম ব্যবহার করে) গ্রহণ করুন। এটি প্রতিটি দলের সদস্যের পটভূমি এবং অভিজ্ঞতা নির্বিশেষে সহযোগিতা উন্নত করে।
- স্বয়ংক্রিয় টেস্টিং: স্টেট মেশিনের আচরণ যাচাই করার জন্য বিস্তৃত ইউনিট এবং ইন্টিগ্রেশন পরীক্ষা লিখুন। প্রতিটি কোড পরিবর্তনে স্বয়ংক্রিয়ভাবে এই পরীক্ষাগুলি চালানোর জন্য ক্রমাগত ইন্টিগ্রেশন (CI) ব্যবহার করুন।
- সংস্করণ নিয়ন্ত্রণ ব্যবহার করুন: কোড পরিবর্তনগুলি পরিচালনা করতে, ইতিহাস ট্র্যাক করতে এবং দলের সদস্যদের মধ্যে সহযোগিতা সহজতর করতে একটি শক্তিশালী সংস্করণ নিয়ন্ত্রণ সিস্টেম (যেমন গিট) ব্যবহার করুন। আন্তর্জাতিক দলগুলির জন্য উপযুক্ত ব্রাঞ্চিং কৌশল প্রয়োগ করুন।
- যোগাযোগ এবং সহযোগিতা সরঞ্জাম: রিয়েল-টাইম যোগাযোগ এবং আলোচনার সুবিধার্থে স্ল্যাক, মাইক্রোসফ্ট টিমস বা অনুরূপ প্ল্যাটফর্মগুলির মতো যোগাযোগ সরঞ্জামগুলি ব্যবহার করুন। টাস্ক ম্যানেজমেন্ট এবং স্ট্যাটাস ট্র্যাকিংয়ের জন্য প্রকল্প পরিচালনার সরঞ্জাম (যেমন জিরা, আসানা, ট্রেলো) ব্যবহার করুন।
- জ্ঞান ভাগ করে নেওয়া: ডকুমেন্টেশন তৈরি করে, প্রশিক্ষণ সেশন সরবরাহ করে বা কোড ওয়াকথ্রু পরিচালনা করে দলের মধ্যে জ্ঞান ভাগ করে নেওয়াকে উত্সাহিত করুন।
- সময় অঞ্চলের পার্থক্য বিবেচনা করুন: সভা নির্ধারণ বা টাস্ক অর্পণ করার সময়, দলের সদস্যদের সময় অঞ্চলের পার্থক্য বিবেচনা করুন। নমনীয় হন এবং সম্ভব হলে বিভিন্ন কাজের সময়গুলিকে সামঞ্জস্য করুন।
উপসংহার
টাইপস্ক্রিপ্টের টেমপ্লেট লিটারেল টাইপগুলি টাইপ-সুরক্ষিত স্টেট মেশিন তৈরির জন্য একটি শক্তিশালী এবং মার্জিত সমাধান সরবরাহ করে। কম্পাইল-টাইম ভ্যালিডেশনকে কাজে লাগিয়ে, ডেভেলপাররা রানটাইম ত্রুটির ঝুঁকি উল্লেখযোগ্যভাবে কমাতে এবং কোডের গুণমান উন্নত করতে পারে। এই পদ্ধতিটি বিশ্বব্যাপী বিতরণ করা সফটওয়্যার উন্নয়ন দলগুলির জন্য বিশেষভাবে মূল্যবান, আরও ভাল ত্রুটি সনাক্তকরণ, সহজ কোড বোঝা এবং উন্নত সহযোগিতা সরবরাহ করে। প্রকল্পগুলি জটিলতায় বাড়ার সাথে সাথে এই কৌশলটি ব্যবহারের সুবিধাগুলি আরও স্পষ্ট হয়ে ওঠে, আধুনিক সফটওয়্যার উন্নয়নে টাইপ সুরক্ষা এবং কঠোর পরীক্ষার গুরুত্বকে শক্তিশালী করে।
এই কৌশলগুলি বাস্তবায়ন করে এবং সেরা অনুশীলনগুলি অনুসরণ করে, দলগুলি ভৌগোলিক অবস্থান বা দলের গঠন নির্বিশেষে আরও স্থিতিস্থাপক এবং রক্ষণাবেক্ষণযোগ্য অ্যাপ্লিকেশন তৈরি করতে পারে। ফলস্বরূপ কোডটি বোঝা সহজ, আরও নির্ভরযোগ্য এবং এটির সাথে কাজ করতে আরও উপভোগ্য, এটি ডেভেলপার এবং শেষ ব্যবহারকারী উভয়ের জন্যই একটি জয়-জয় পরিস্থিতি তৈরি করে।