సరళమైన iOS సాఫ్ట్‌వేర్ డిజైన్ యొక్క నాలుగు నియమాలు

1990 ల చివరలో, ఎక్స్‌ట్రీమ్ ప్రోగ్రామింగ్‌ను అభివృద్ధి చేస్తున్నప్పుడు, ప్రసిద్ధ సాఫ్ట్‌వేర్ డెవలపర్ కెంట్ బెక్ సాధారణ సాఫ్ట్‌వేర్ డిజైన్ కోసం నియమాల జాబితాను తీసుకువచ్చారు.

కెంట్ బెక్ ప్రకారం, మంచి సాఫ్ట్‌వేర్ డిజైన్:

  • అన్ని పరీక్షలను నడుపుతుంది
  • నకిలీ లేదు
  • ప్రోగ్రామర్ యొక్క ఉద్దేశాన్ని తెలియజేస్తుంది
  • తరగతులు మరియు పద్ధతుల సంఖ్యను తగ్గిస్తుంది

ఈ వ్యాసంలో, ఆచరణాత్మక iOS ఉదాహరణలు ఇవ్వడం ద్వారా మరియు వాటి నుండి మనం ఎలా ప్రయోజనం పొందవచ్చో చర్చించడం ద్వారా iOS అభివృద్ధి ప్రపంచానికి ఈ నియమాలను ఎలా అన్వయించవచ్చో చర్చించాము.

అన్ని పరీక్షలను నడుపుతుంది

సాఫ్ట్‌వేర్ డిజైన్ ఉద్దేశించిన విధంగా పనిచేసే వ్యవస్థను సృష్టించడానికి మాకు సహాయపడుతుంది. ఒక వ్యవస్థ దాని రూపకల్పన ద్వారా ప్రారంభంలో ఉద్దేశించిన విధంగా పనిచేస్తుందని మేము ఎలా ధృవీకరించగలం? దాన్ని ధృవీకరించే పరీక్షలను సృష్టించడం ద్వారా సమాధానం.

దురదృష్టవశాత్తు, iOS అభివృద్ధి విశ్వ పరీక్షలు చాలా సార్లు నివారించబడతాయి… కానీ బాగా రూపొందించిన సాఫ్ట్‌వేర్‌ను రూపొందించడానికి, మనం ఎల్లప్పుడూ పరీక్షా సామర్థ్యాన్ని దృష్టిలో ఉంచుకొని స్విఫ్ట్ కోడ్‌ను వ్రాయాలి.

పరీక్ష రాయడం మరియు సిస్టమ్ రూపకల్పనను సరళంగా చేయగల రెండు సూత్రాలను చర్చిద్దాం. మరియు అవి సింగిల్ రెస్పాన్స్బిలిటీ ప్రిన్సిపల్ మరియు డిపెండెన్సీ ఇంజెక్షన్.

ఒకే బాధ్యత సూత్రం (SRP)

SRP ఒక తరగతికి ఒకటి ఉండాలి, మరియు మార్చడానికి ఒకే ఒక కారణం ఉండాలి. SRP సరళమైన సూత్రాలలో ఒకటి మరియు సరైనది పొందడం కష్టతరమైనది. బాధ్యతలను కలపడం మనం సహజంగా చేసే పని.

కొన్ని కోడ్ యొక్క ఉదాహరణను పరీక్షించడం చాలా కష్టం మరియు ఆ రిఫ్యాక్టర్ తర్వాత SRP ని ఉపయోగించడం ద్వారా ఉదాహరణను అందిద్దాం. ఇది కోడ్‌ను ఎలా పరీక్షించదగినదిగా చేసిందో చర్చించండి.

మేము ప్రస్తుతం మా ప్రస్తుత వీక్షణ నియంత్రిక నుండి PaymentViewController ను ప్రదర్శించాల్సిన అవసరం ఉందని అనుకుందాం, PaymentViewController మా చెల్లింపు ఉత్పత్తి ధరను బట్టి దాని వీక్షణను కాన్ఫిగర్ చేయాలి. మా విషయంలో, కొన్ని బాహ్య వినియోగదారు సంఘటనలను బట్టి ధర వేరియబుల్.

ఈ అమలు కోసం కోడ్ ప్రస్తుతం ఈ క్రింది విధంగా ఉంది:

మేము ఈ కోడ్‌ను ఎలా పరీక్షించవచ్చు? మనం మొదట ఏమి పరీక్షించాలి? ధర తగ్గింపు సరిగ్గా లెక్కించబడిందా? డిస్కౌంట్‌ను పరీక్షించడానికి మేము చెల్లింపు ఈవెంట్‌లను ఎలా ఎగతాళి చేయవచ్చు?

ఈ తరగతికి పరీక్షలు రాయడం సంక్లిష్టంగా ఉంటుంది, దానిని వ్రాయడానికి మంచి మార్గాన్ని కనుగొనాలి. సరే, మొదట పెద్ద సమస్యను పరిష్కరించుకుందాం. మన డిపెండెన్సీలను అరికట్టాలి.

మా ఉత్పత్తిని లోడ్ చేయడానికి మాకు తర్కం ఉందని మేము చూశాము. డిస్కౌంట్ కోసం వినియోగదారుని అర్హత చేసే చెల్లింపు ఈవెంట్‌లు మాకు ఉన్నాయి. మాకు డిస్కౌంట్లు ఉన్నాయి, డిస్కౌంట్ లెక్కింపు మరియు జాబితా కొనసాగుతుంది.

కాబట్టి వీటిని స్విఫ్ట్ కోడ్‌లోకి అనువదించడానికి ప్రయత్నిద్దాం.

చెల్లింపులకు సంబంధించిన మా తర్కాన్ని నిర్వహించే పేమెంట్‌మేనేజర్‌ను సృష్టించాము మరియు ఇది సులభంగా పరీక్షించదగిన ప్రైస్‌కాల్క్యులేటర్‌ను వేరు చేయండి. అలాగే, మా ఉత్పత్తులను లోడ్ చేయడానికి నెట్‌వర్క్ లేదా డేటాబేస్ ఇంటరాక్షన్‌కు బాధ్యత వహించే డేటా-లోడర్.

డిస్కౌంట్ల నిర్వహణకు మాకు ఒక తరగతి అవసరం అని కూడా మేము ప్రస్తావించాము. దీనిని కూపన్ మేనేజర్ అని పిలుద్దాం మరియు యూజర్ డిస్కౌంట్ కూపన్లను కూడా నిర్వహిద్దాం.

మా చెల్లింపు వీక్షణ నియంత్రిక అప్పుడు ఈ క్రింది విధంగా ఉంటుంది:

మేము ఇప్పుడు వంటి పరీక్షలను వ్రాయవచ్చు

  • testCalculatingFinalPriceWithoutCoupon
  • testCalculatingFinalPriceWithCoupon
  • testCouponExists

మరియు అనేక ఇతర వాటిని! ప్రత్యేక వస్తువులను సృష్టించడం ద్వారా ఇప్పుడు మేము అనవసరమైన నకిలీని నివారించాము మరియు పరీక్షలను వ్రాయడం సులభం అని ఒక కోడ్‌ను కూడా సృష్టించాము.

డిపెండెన్సీ ఇంజెక్షన్

రెండవ సూత్రం డిపెండెన్సీ ఇంజెక్షన్. మరియు మేము ఇప్పటికే మా ఆబ్జెక్ట్ ఇనిషియేజర్‌లపై డిపెండెన్సీ ఇంజెక్షన్‌ను ఉపయోగించామని పై ఉదాహరణల నుండి చూశాము.

పైన పేర్కొన్న మా డిపెండెన్సీలను ఇంజెక్ట్ చేయడం వల్ల రెండు ప్రధాన ప్రయోజనాలు ఉన్నాయి. ఇది మన రకాలు ఏ డిపెండెన్సీలపై ఆధారపడతాయో స్పష్టం చేస్తుంది మరియు ఇది నిజమైన వాటికి బదులుగా పరీక్షించాలనుకున్నప్పుడు మాక్ వస్తువులను చొప్పించడానికి అనుమతిస్తుంది.

ఒక మంచి సాంకేతికత ఏమిటంటే, మా వస్తువులకు ప్రోటోకాల్‌లను సృష్టించడం మరియు కింది విధంగా నిజమైన మరియు మాక్ ఆబ్జెక్ట్ ద్వారా కాంక్రీట్ అమలును అందించడం:

ఇప్పుడు మనం ఏ తరగతిని డిపెండెన్సీగా ఇంజెక్ట్ చేయాలనుకుంటున్నామో తేలికగా నిర్ణయించవచ్చు.

టైట్ కలపడం పరీక్షలు రాయడం కష్టతరం చేస్తుంది. కాబట్టి, అదేవిధంగా, మనం ఎక్కువ పరీక్షలు వ్రాస్తాము, డిఐపి వంటి సూత్రాలను మరియు డిపెండెన్సీ ఇంజెక్షన్, ఇంటర్‌ఫేస్‌లు మరియు సంగ్రహణ వంటి సాధనాలను కలపడం తగ్గించడానికి ఉపయోగిస్తాము.

కోడ్‌ను మరింత పరీక్షించదగినదిగా మార్చడం వల్ల అది విచ్ఛిన్నం అవుతుందనే మన భయాన్ని తొలగిస్తుంది (మనకు బ్యాకప్ చేసే పరీక్షను వ్రాస్తాము కాబట్టి) క్లీనర్ కోడ్ రాయడానికి కూడా దోహదం చేస్తుంది.

అసలు యూనిట్ పరీక్ష రాయడం కంటే పరీక్షించదగిన కోడ్‌ను ఎలా రాయాలో వ్యాసం యొక్క ఈ భాగం ఎక్కువ శ్రద్ధ వహించింది. మీరు యూనిట్ పరీక్ష రాయడం గురించి మరింత తెలుసుకోవాలనుకుంటే, పరీక్ష-ఆధారిత అభివృద్ధిని ఉపయోగించి నేను జీవిత ఆటను సృష్టించే ఈ కథనాన్ని మీరు చూడవచ్చు.

నకిలీ లేదు

బాగా రూపొందించిన వ్యవస్థ యొక్క నకిలీ ప్రాథమిక శత్రువు. ఇది అదనపు పనిని సూచిస్తుంది, అదనపు ప్రమాదం, అనవసరమైన సంక్లిష్టతను జోడిస్తుంది.

ఈ విభాగంలో, iOS లో సాధారణ నకిలీని తొలగించడానికి మూస రూపకల్పన నమూనాను ఎలా ఉపయోగించవచ్చో మేము చర్చిస్తాము. అర్థం చేసుకోవడాన్ని సులభతరం చేయడానికి, మేము నిజ జీవిత చాట్ యొక్క రిఫ్యాక్టర్ అమలుకు వెళ్తున్నాము.

మేము ప్రస్తుతం మా అనువర్తనంలో ప్రామాణిక చాట్ విభాగాన్ని కలిగి ఉన్నామని అనుకుందాం. క్రొత్త అవసరం వస్తుంది మరియు ఇప్పుడు మేము క్రొత్త రకం చాట్‌ను అమలు చేయాలనుకుంటున్నాము - ప్రత్యక్ష-చాట్. గరిష్టంగా 20 సంఖ్యలో అక్షరాలతో సందేశాలను కలిగి ఉన్న చాట్ మరియు మేము చాట్ వీక్షణను తీసివేసినప్పుడు ఈ చాట్ కనుమరుగవుతుంది.

ఈ చాట్ మా ప్రస్తుత చాట్ మాదిరిగానే ఉంటుంది, కానీ కొన్ని విభిన్న నియమాలను కలిగి ఉంటుంది:

  1. చాట్ సందేశాలను పంపడానికి నెట్‌వర్క్ అభ్యర్థన భిన్నంగా ఉంటుంది.

2. చాట్ సందేశాలు చిన్నదిగా ఉండాలి, సందేశానికి 20 అక్షరాల కంటే ఎక్కువ ఉండకూడదు.

3. మా స్థానిక డేటాబేస్లో చాట్ సందేశాలు కొనసాగకూడదు.

మేము MVP నిర్మాణాన్ని ఉపయోగిస్తున్నామని అనుకుందాం మరియు ప్రస్తుతం మా ప్రెజెంటర్‌లో చాట్ సందేశాలను పంపే తర్కాన్ని మేము నిర్వహిస్తున్నాము. లైవ్-చాట్ పేరుతో మా క్రొత్త చాట్ రకం కోసం కొత్త నియమాలను జోడించడానికి ప్రయత్నిద్దాం.

అమాయక అమలు ఈ క్రింది విధంగా ఉంటుంది:

భవిష్యత్తులో మనకు చాలా ఎక్కువ చాట్ రకాలు ఉంటే ఏమి జరుగుతుంది?
ప్రతి ఫంక్షన్‌లో మా చాట్ యొక్క స్థితిని తనిఖీ చేస్తే మనం జోడించడం కొనసాగిస్తే, కోడ్ చదవడం మరియు నిర్వహించడం చాలా గజిబిజిగా మారుతుంది. అలాగే, ఇది పరీక్షించదగినది కాదు మరియు ప్రెజెంటర్ యొక్క పరిధిలో రాష్ట్ర తనిఖీ నకిలీ చేయబడుతుంది.

ఇక్కడే మూస సరళి వాడుకలోకి వస్తుంది. మాకు అల్గోరిథం యొక్క బహుళ అమలులు అవసరమైనప్పుడు మూస సరళి ఉపయోగించబడుతుంది. టెంప్లేట్ నిర్వచించబడింది మరియు తరువాత మరింత వైవిధ్యాలతో నిర్మించబడింది. చాలా ఉపవర్గాలు ఒకే ప్రవర్తనను అమలు చేయాల్సిన అవసరం వచ్చినప్పుడు ఈ పద్ధతిని ఉపయోగించండి.

మేము చాట్ ప్రెజెంటర్ కోసం ఒక ప్రోటోకాల్‌ను సృష్టించగలము మరియు చాట్ ప్రెజెంటర్ దశలలో కాంక్రీట్ వస్తువుల ద్వారా భిన్నంగా అమలు చేయబడే పద్ధతులను వేరు చేస్తాము.

మేము ఇప్పుడు మా ప్రెజెంటర్ IChatPresenter కు అనుగుణంగా ఉండేలా చేయవచ్చు

మా ప్రెజెంటర్ ఇప్పుడు తనలోని సాధారణ ఫంక్షన్లను పిలవడం ద్వారా సందేశాన్ని పంపడాన్ని నిర్వహిస్తుంది మరియు భిన్నంగా అమలు చేయగల విధులను అప్పగిస్తుంది.

ఇప్పుడు మేము ప్రెజెంటర్ దశలకు అనుగుణంగా ఉండే సృష్టించు వస్తువులను అందించగలము మరియు వాటి అవసరాలను బట్టి ఈ విధులను కాన్ఫిగర్ చేయవచ్చు.

మేము మా వ్యూ కంట్రోలర్‌లో డిపెండెన్సీ ఇంజెక్షన్‌ను ఉపయోగిస్తే, ఇప్పుడు ఒకే వీక్షణ కంట్రోలర్‌ను రెండు వేర్వేరు సందర్భాల్లో తిరిగి ఉపయోగించుకోవచ్చు.

డిజైన్ సరళిని ఉపయోగించడం ద్వారా మన iOS కోడ్‌ను నిజంగా సరళీకృతం చేయవచ్చు. మీరు దాని గురించి మరింత తెలుసుకోవాలనుకుంటే, తరువాతి వ్యాసం మరింత వివరణను అందిస్తుంది.

వ్యక్తీకరణ

సాఫ్ట్‌వేర్ ప్రాజెక్ట్ ఖర్చులో ఎక్కువ భాగం దీర్ఘకాలిక నిర్వహణలో ఉంటుంది. సాఫ్ట్‌వేర్ డెవలపర్‌లకు కోడ్ చదవడం మరియు నిర్వహించడం సులభం.

మంచి నామకరణం, SRP ని ఉపయోగించడం మరియు రాయడం పరీక్ష ద్వారా మేము మరింత వ్యక్తీకరణ కోడ్‌ను అందించవచ్చు.

నేమింగ్

కోడ్‌ను మరింత వ్యక్తీకరణ చేసే నంబర్ వన్ విషయం - మరియు దీనికి పేరు పెట్టడం. పేర్లు రాయడం ముఖ్యం:

  • ఉద్దేశాన్ని వెల్లడించండి
  • తప్పు సమాచారం మానుకోండి
  • సులభంగా శోధించవచ్చు

తరగతులు మరియు ఫంక్షన్లకు నామకరణం విషయానికి వస్తే, తరగతులు మరియు వినియోగదారు క్రియలకు నామవాచకం లేదా నామవాచకం-పదబంధాన్ని ఉపయోగించడం లేదా పద్ధతుల కోసం క్రియ పదబంధ పేర్లను ఉపయోగించడం మంచి ఉపాయం.

వేర్వేరు డిజైన్ సరళిని ఉపయోగిస్తున్నప్పుడు కొన్నిసార్లు తరగతి పేరులో కమాండ్ లేదా విజిటర్ వంటి నమూనా పేర్లను చేర్చడం మంచిది. కాబట్టి దాని గురించి తెలుసుకోవడానికి అన్ని కోడ్లను చదవవలసిన అవసరం లేకుండా అక్కడ ఏ నమూనా ఉపయోగించబడుతుందో పాఠకుడికి వెంటనే తెలుస్తుంది.

SRP ని ఉపయోగిస్తోంది

కోడ్ వ్యక్తీకరణ చేసే మరొక విషయం పై నుండి పేర్కొన్న సింగిల్ రెస్పాన్స్బిలిటీ ప్రిన్సిపల్‌ను ఉపయోగించడం. మీ విధులు మరియు తరగతులను చిన్నగా మరియు ఒకే ప్రయోజనం కోసం ఉంచడం ద్వారా మీరు మీరే వ్యక్తపరచవచ్చు. చిన్న తరగతులు మరియు విధులు సాధారణంగా పేరు పెట్టడం సులభం, వ్రాయడం సులభం మరియు అర్థం చేసుకోవడం సులభం. ఒక ఫంక్షన్ ఒక ప్రయోజనం కోసం మాత్రమే ఉపయోగపడుతుంది.

రాయడం పరీక్ష

పరీక్షలు రాయడం కూడా చాలా స్పష్టతను తెస్తుంది, ముఖ్యంగా లెగసీ కోడ్‌తో పనిచేసేటప్పుడు. బాగా వ్రాసిన యూనిట్ పరీక్షలు కూడా వ్యక్తీకరణ. పరీక్షల యొక్క ప్రాధమిక లక్ష్యం ఉదాహరణ ద్వారా డాక్యుమెంటేషన్ వలె పనిచేయడం. మా పరీక్షలను చదివే ఎవరైనా తరగతి గురించి ఏమిటో త్వరగా అర్థం చేసుకోగలుగుతారు.

తరగతులు మరియు పద్ధతుల సంఖ్యను తగ్గించండి

తరగతి యొక్క విధులు చిన్నదిగా ఉండాలి, ఒక ఫంక్షన్ ఎల్లప్పుడూ ఒక పనిని మాత్రమే చేయాలి. ఒక ఫంక్షన్‌లో చాలా ఎక్కువ పంక్తులు ఉంటే, అది రెండు లేదా అంతకంటే ఎక్కువ వేర్వేరు ఫంక్షన్‌లుగా వేరు చేయగల చర్యలను చేస్తుంది.

భౌతిక పంక్తులను లెక్కించడం మరియు గరిష్టంగా నాలుగైదు పంక్తుల ఫంక్షన్లను లక్ష్యంగా చేసుకోవడం మంచి విధానం, చాలా సందర్భాలలో ఆ పంక్తుల సంఖ్య కంటే ఎక్కువ ఏదైనా చదవడం మరియు నిర్వహించడం కష్టమవుతుంది.

IOS లో మంచి ఆలోచన ఏమిటంటే మనం సాధారణంగా వ్యూడిడ్లోడ్ లేదా వ్యూడిడ్అప్పర్ ఫంక్షన్లలో చేసే కాన్ఫిగరేషన్ కాల్స్ ను కత్తిరించడం.

ఈ విధంగా, ప్రతి ఫంక్షన్ ఒక మెస్ వ్యూ డిడ్ లోడ్ ఫంక్షన్కు బదులుగా చిన్నది మరియు నిర్వహించదగినది. అనువర్తన ప్రతినిధికి కూడా అదే దరఖాస్తు చేయాలి. మేము ప్రతి కాన్ఫిగరేషన్ ondidFinishLaunchingWithOptions పద్ధతి మరియు ప్రత్యేక కాన్ఫిగరేషన్ ఫంక్షన్లు లేదా మెరుగైన కాన్ఫిగరేషన్ క్లాసులను విసిరేయకుండా ఉండాలి.

ఫంక్షన్లతో, మనం దానిని పొడవుగా లేదా తక్కువగా ఉంచుతున్నామా అని కొలవడం కొంచెం సులభం, మనం చాలా సార్లు భౌతిక రేఖలను లెక్కించడంపై ఆధారపడవచ్చు. తరగతులతో, మేము వేరే కొలతను ఉపయోగిస్తాము. మేము బాధ్యతలను లెక్కించాము. ఒక తరగతికి కేవలం ఐదు పద్ధతులు ఉంటే, తరగతి చిన్నదని అర్ధం కాదు, ఆ పద్ధతులతో మాత్రమే చాలా బాధ్యతలు ఉండవచ్చు.

IOS లో తెలిసిన సమస్య UIViewControllers యొక్క పెద్ద పరిమాణం. ఆపిల్ వ్యూ కంట్రోలర్ డిజైన్ ద్వారా, ఈ వస్తువులను ఒకే ప్రయోజనం కోసం ఉంచడం చాలా కష్టం, కాని మనం మా వంతు ప్రయత్నం చేయాలి.

UIViewControllers ను చిన్నదిగా చేయడానికి చాలా మార్గాలు ఉన్నాయి, నా ప్రాధాన్యత VIPER లేదా MVP వంటి ఆందోళనలను బాగా వేరుచేసే ఆర్కిటెక్చర్‌ను ఉపయోగించడం, కానీ ఆపిల్ MVC లో కూడా మేము దీన్ని మెరుగ్గా చేయలేమని కాదు.

అనేక ఆందోళనలను వేరు చేయడానికి ప్రయత్నించడం ద్వారా మనం ఏదైనా నిర్మాణంతో చాలా మంచి కోడ్‌ను చేరుకోవచ్చు. వీక్షణ కంట్రోలర్‌లకు సహాయకులుగా ఉపయోగపడే ఒకే-ప్రయోజన తరగతులను సృష్టించడం మరియు కోడ్‌ను మరింత చదవగలిగే మరియు పరీక్షించదగినదిగా చేయాలనే ఆలోచన ఉంది.

వ్యూ కంట్రోలర్‌లలో ఎటువంటి అవసరం లేకుండా నివారించగల కొన్ని విషయాలు:

  • నెట్‌వర్క్ కోడ్‌ను నేరుగా వ్రాయడానికి బదులుగా నెట్‌వర్క్ మేనేజర్లకు నెట్‌వర్క్ కాల్‌లకు బాధ్యత వహించే తరగతి ఉండాలి
  • వ్యూ కంట్రోలర్‌లలో డేటాను మార్చటానికి బదులుగా, డేటా మేనేజర్‌కు దానికి బాధ్యత వహించే తరగతిని సృష్టించవచ్చు.
  • UIViewController లో UserDefaults తీగలతో ఆడటానికి బదులుగా మనం దానిపై ముఖభాగాన్ని సృష్టించవచ్చు.

ముగింపులో

మేము ఖచ్చితంగా పేరు పెట్టబడిన, సరళమైన, చిన్న, ఒక విషయానికి బాధ్యత వహించే మరియు పునర్వినియోగపరచదగిన భాగాల నుండి సాఫ్ట్‌వేర్‌ను కంపోజ్ చేయాలని నేను నమ్ముతున్నాను.

ఈ వ్యాసంలో, మేము కెంట్ బెక్ చేత సరళమైన రూపకల్పన కోసం నాలుగు నియమాలను చర్చించాము మరియు వాటిని iOS అభివృద్ధి వాతావరణంలో ఎలా అమలు చేయవచ్చో ఆచరణాత్మక ఉదాహరణలు ఇచ్చాము.

మీరు ఈ కథనాన్ని ఆస్వాదించినట్లయితే, మీ మద్దతును చూపించడానికి చప్పట్లు కొట్టండి. మీ iOS డెవలపర్ నైపుణ్యాలను తదుపరి స్థాయికి తీసుకెళ్లగల మరెన్నో కథనాలను చూడటానికి నన్ను అనుసరించండి.

మీకు ఏవైనా ప్రశ్నలు లేదా వ్యాఖ్యలు ఉంటే సంకోచించకండి ఇక్కడ ఒక గమనికను ఉంచండి లేదా arlindaliu.dev@gmail.com లో నాకు ఇమెయిల్ చేయండి.