JavaRush /Java блогы /Random-KK /Кодты жазу ережелері: жүйені құрудан бастап объектілермен...
Константин
Деңгей

Кодты жазу ережелері: жүйені құрудан бастап объектілермен жұмыс істеуге дейін

Топта жарияланған
Баршаңызға қайырлы күн: бүгін мен сізбен codeты дұрыс жазу туралы сөйлескім келеді. Мен бағдарламалауды алғаш бастағанда, бұлай жазуға болады деп еш жерде анық жазылмаған, егер осылай жазсаң, мен сені табамын және.... Нәтижесінде менің басымда көптеген сұрақтар болды: қалай дұрыс жазу керек, бағдарламаның осы немесе басқа бөлімінде қандай принциптерді ұстану керек және т.б. Кодты жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 1Таза code сияқты кітаптарға бәрі бірден енгісі келмейді, өйткені оларда көп нәрсе жазылған, бірақ алдымен аз ғана түсінікті. Ал сіз оқуды аяқтаған кезде сіз codeтауға деген барлық қалауыңыздан бас тарта аласыз. Сондықтан жоғарыда айтылғандарға сүйене отырып, бүгін мен сізге жоғары деңгейлі codeты жазуға арналған шағын нұсқаулықты (шағын ұсыныстар жиынтығы) ұсынғым келеді. Бұл мақалада біз жүйені құруға және интерфейстермен, сыныптармен және an objectілермен жұмыс істеуге қатысты негізгі ережелер мен түсініктерді қарастырамыз. Бұл материалды оқу сізге көп уақытты қажет етпейді және сізді жалықтырмайды деп үміттенемін. Мен жоғарыдан төменге қарай, яғни қосымшаның жалпы құрылымынан нақтырақ мәліметтерге дейін барамын. Код жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 2

Жүйе

Жүйенің жалпы қажетті сипаттамалары :
  • минималды күрделілік - тым күрделі жобалардан аулақ болу керек. Ең бастысы - қарапайымдылық пен айқындық (ең жақсы = қарапайым);
  • техникалық қызмет көрсетудің қарапайымдылығы - қолданбаны жасау кезінде оған қолдау көрсету қажет болатынын есте сақтау керек (тіпті ол сіз болмасаңыз), сондықтан code анық және айқын болуы керек;
  • әлсіз байланыс – бағдарламаның әртүрлі бөліктері арасындағы байланыстардың ең аз саны (OOP принциптерін максималды пайдалану);
  • қайта пайдалануға жарамдылық – оның фрагменттерін басқа қолданбаларда қайта пайдалану мүмкіндігі бар жүйені жобалау;
  • портативтілік - жүйе басқа ортаға оңай бейімделуі керек;
  • бір стиль – жүйені оның әртүрлі фрагменттері бойынша бір стильде жобалау;
  • кеңейту (масштабтылық) – жүйені оның негізгі құрылымын бұзбай жетілдіру (егер фрагментті қоссаңыз немесе өзгертсеңіз, бұл қалған бөлігіне әсер етпеуі керек).
Функционалдылықты қоспай, өзгертулерді қажет етпейтін қолданбаны құру іс жүзінде мүмкін емес. Баламыз заман ағымына ілесе алуы үшін біз үнемі жаңа элементтерді енгізуіміз керек. Және бұл жерде масштабталады . Масштабтау - бұл қолданбаны кеңейту, жаңа функционалдылықты қосу, көбірек ресурстармен (немесе, басқаша айтқанда, көбірек жүктемемен) жұмыс істеу. Яғни, жаңа логиканы қосу оңай болуы үшін модульді арттыру арқылы жүйенің байланысын азайту сияқты кейбір ережелерді сақтауымыз керек.

Жүйені жобалау кезеңдері

  1. Бағдарламалық жүйе – қосымшаны жалпы формада жобалау.
  2. Ішкі жүйелерге/пакеттерге бөлу – логикалық түрде бөлінетін бөліктерді анықтау және олардың арасындағы өзара әрекеттесу ережелерін анықтау.
  3. Ішкі жүйелерді класстарға бөлу – жүйенің бөліктерін белгілі бір кластарға және интерфейстерге бөлу, сонымен қатар олардың арасындағы өзара әрекеттесуді анықтау.
  4. Класстарды әдістерге бөлу – осы сыныптың тапсырмасы негізінде сыныпқа қажетті әдістердің толық анықтамасы. Әдістерді жобалау – жеке әдістердің функционалдығын егжей-тегжейлі анықтау.
Әдетте, қарапайым әзірлеушілер дизайнға жауапты, ал қолданбаның сәулетшісі жоғарыда сипатталған элементтер үшін жауап береді.

Жүйені жобалаудың негізгі принциптері мен тұжырымдамалары

Жалқау инициализация идиома Қолданба an objectіні ол пайдаланылғанға дейін жасауға уақыт жұмсамайды, бұл инициализация процесін жылдамдатады және қоқыс жинаушы жүктемесін азайтады. Бірақ сіз мұнымен тым алысқа бармауыңыз керек, өйткені бұл модульдіктің бұзылуына әкелуі мүмкін. Барлық дизайн қадамдарын белгілі бір бөлікке, мысалы, негізгіге немесе зауыт сияқты жұмыс істейтін сыныпқа жылжыту қажет болуы мүмкін . Жақсы codeтың аспектілерінің бірі - жиі қайталанатын, стандартты codeтың болмауы. Әдетте, мұндай code қажетті уақытта шақырылуы үшін бөлек сыныпқа орналастырылады. AOP бөлек, мен аспектіге бағытталған бағдарламалауды атап өткім келеді . Бұл түпкілікті логиканы енгізу арқылы бағдарламалау, яғни қайталанатын code сыныптарға – аспектілерге қойылады және белгілі бір шарттарға жеткенде шақырылады. Мысалы, белгілі бір атаумен әдіске қатынасу немесе белгілі бір түрдегі айнымалыға қол жеткізу. Кейде аспектілер шатастыруы мүмкін, өйткені codeтың қайдан шақырылғаны бірден белгісіз, бірақ соған қарамастан бұл өте пайдалы функционалдылық. Атап айтқанда, кэштеу немесе тіркеу кезінде: біз бұл функцияны әдеттегі сыныптарға қосымша логиканы қоспай қосамыз. OAP туралы толығырақ мына жерден оқи аласыз . Кент Бек бойынша қарапайым архитектураны жобалаудың 4 ережесі
  1. Экспрессивтілік – сыныптың нақты көрсетілген мақсатына деген қажеттілік, дұрыс атау, шағын өлшем және біртұтас жауапкершілік принципін сақтау арқылы жүзеге асады (оны төменде толығырақ қарастырамыз).
  2. Сабақтар мен әдістердің ең азы - сыныптарды мүмкіндігінше кішігірім және бір бағытқа бөлуді қаласаңыз, сіз тым алысқа бара аласыз (антиптерн - шолақ ату). Бұл принцип жүйені ықшам ұстауды және тым алысқа бармауды, әрбір түшкіру үшін класс құруды талап етеді.
  3. Қайталанудың болмауы - шатастыратын қосымша code жүйенің нашар дизайнының белгісі және бөлек орынға ауыстырылады.
  4. Барлық сынақтардың орындалуы - барлық сынақтардан өткен жүйе бақыланады, өйткені кез келген өзгеріс сынақтардың сәтсіздігіне әкелуі мүмкін, бұл әдістің ішкі логикасының өзгеруі де күтілетін мінез-құлықтың өзгеруіне әкелетінін көрсете алады. .
SOLID Жүйені жобалау кезінде SOLID-тің белгілі қағидаларын ескерген жөн: S – бір жауапкершілік – біртұтас жауапкершілік принципі; О – ашық-жабық – ашықтық/тұйықтық принципі; Л - Лисков ауыстыру - Барбара Лисковтың ауыстыру принципі; I – интерфейсті бөлу – интерфейсті бөлу принципі; D – тәуелділік инversionсы – тәуелділік инversionсы принципі; Біз әрбір принципке арнайы тоқталмаймыз (бұл осы мақаланың ауқымынан сәл ғана емес, бірақ сіз осы жерден көбірек біле аласыз.

Интерфейс

Адекватты сыныпты құрудың ең маңызды кезеңдерінің бірі класстың іске асыру мәліметтерін жасыратын жақсы абстракцияны көрсететін және сонымен бірге бір-бірімен анық сәйкес келетін әдістер тобын көрсететін адекватты интерфейсті құру болуы мүмкін. . SOLID принциптерінің бірін толығырақ қарастырайық - интерфейсті бөлу : клиенттер (сыныптар) өздері пайдаланbyteын қажетсіз әдістерді қолданбауы керек. Яғни, егер біз осы интерфейстің жалғыз тапсырмасын орындауға бағытталған әдістердің ең аз саны бар интерфейстерді құру туралы айтатын болсақ (мен үшін бұл жалғыз жауапкершілікке өте ұқсас ), бірнеше кішірек етіп жасаған дұрыс. бір толып жатқан интерфейстің орнына. Бақытымызға орай, сынып мұрагерлік жағдайдағыдай бірнеше интерфейсті жүзеге асыра алады. Сондай-ақ интерфейстерді дұрыс атау туралы есте сақтау қажет: атау оның міндетін мүмкіндігінше дәл көрсетуі керек. Және, әрине, ол неғұрлым қысқа болса, соғұрлым ол аз шатастыруға әкеледі. Дәл интерфейс деңгейінде әдетте құжаттамаға түсініктемелер жазылады , бұл өз кезегінде әдіс не істеу керектігін, ол қандай аргументтерді қажет ететінін және ол не қайтаратынын егжей-тегжейлі сипаттауға көмектеседі.

Сынып

Кодты жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 3Сабақтардың ішкі ұйымдастырылуын қарастырайық. Дәлірек айтқанда, сыныптарды құру кезінде ұстануға тиіс кейбір көзқарастар мен ережелер. Әдетте, сынып белгілі бір ретпен реттелген айнымалылар тізімінен басталуы керек:
  1. жалпы статикалық тұрақтылар;
  2. жеке статикалық тұрақтылар;
  3. жеке даналық айнымалылар.
Әрі қарай әр түрлі конструкторлар аздан көп аргументке қарай орналасады. Олардан кейін неғұрлым ашық қолжетімділіктен ең жабық әдістерге дейін: әдетте, біз шектегіміз келетін кейбір функционалдылықты жүзеге асыруды жасыратын жеке әдістер ең төменгі жағында орналасқан.

Сынып мөлшері

Енді мен сынып көлемі туралы айтқым келеді. SOLID - жалғыз жауапкершілікКод жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 4 қағидаларының бірін еске түсірейік . Бірыңғай жауапкершілік – біртұтас жауапкершілік принципі. Онда әрбір an objectінің бір ғана мақсаты (жауапкершілігі) болатыны және оның барлық әдістерінің логикасы оны қамтамасыз етуге бағытталғаны айтылады. Яғни, осыған сүйене отырып, біз үлкен, толып жатқан сыныптардан аулақ болуымыз керек (олар табиғаты бойынша антипаттерн - «құдайлық нысан»), ал егер бізде сыныпта әртүрлі, гетерогенді логика әдістері көп болса, біз ойлануымыз керек. оны бірнеше логикалық бөліктерге (сыныптарға) бөлу туралы. Бұл, өз кезегінде, codeтың оқылуын жақсартады, өйткені берілген сыныптың болжалды мақсатын білсек, әдіс мақсатын түсіну үшін көп уақыт қажет емес. Сіз сондай-ақ сынып атауын қадағалауыңыз керек : ол құрамындағы логиканы көрсетуі керек. Айталық, егер бізде аты 20+ сөзден тұратын сынып болса, біз рефакторинг туралы ойлануымыз керек. Әрбір өзін-өзі құрметтейтін сыныпта мұндай көп ішкі айнымалылар болмауы керек. Шындығында, әрбір әдіс олардың біреуімен немесе бірнешеуімен жұмыс істейді, бұл сынып ішінде үлкен байланысты тудырады (дәл солай болуы керек, өйткені сынып біртұтас болуы керек). Нәтижесінде сыныптың үйлесімділігін арттыру оның азаюына әкеледі және, әрине, біздің сыныптарымыздың саны артады. Кейбіреулер үшін бұл тітіркендіргіш; олар белгілі бір үлкен тапсырманың қалай жұмыс істейтінін көру үшін сабаққа көбірек баруы керек. Басқа нәрселермен қатар, әрбір сынып басқалармен минималды түрде қосылуы керек шағын модуль болып табылады. Бұл оқшаулау сыныпқа қосымша логиканы қосқанда енгізу қажет өзгерістер санын азайтады.

Объектілер

Кодты жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 5

Инкапсуляция

Бұл жерде біз ең алдымен OOP - инкапсуляция принциптерінің бірі туралы айтатын боламыз . Сонымен, іске асыруды жасыру айнымалылар арасында әдіс қабатын құруға келмейді (бір әдістер, геттер және орнатушылар арқылы қол жеткізуді ойланбастан шектеу, бұл жақсы емес, өйткені инкапсуляцияның барлық нүктесі жоғалады). Қол жеткізуді жасыру абстракцияларды қалыптастыруға бағытталған, яғни класс біздің деректермен жұмыс істейтін жалпы нақты әдістерді ұсынады. Бірақ пайдаланушыға бұл деректермен қалай жұмыс істейтінімізді білудің қажеті жоқ - ол жұмыс істейді және бұл жақсы.

Деметер заңы

Сондай-ақ Деметр заңын қарастыруға болады: бұл сынып пен әдіс деңгейінде күрделілікті басқаруға көмектесетін ережелердің шағын жиынтығы. CarСонымен, бізде an object бар және оның әдісі бар деп есептейік - move(Object arg1, Object arg2). Деметр заңына сәйкес бұл әдіс қоңырау шалумен шектеледі:
  • an objectінің өзінің әдістері Car(басқаша айтқанда, бұл);
  • жылы құрылған an objectілердің әдістері move;
  • аргумент ретінде берілген an objectілердің әдістері - arg1, arg2;
  • ішкі an objectілердің әдістері Car(дәл солай).
Басқаша айтқанда, Деметер заңы балалар ережесі сияқты нәрсе - сіз достарыңызбен сөйлесе аласыз, бірақ бейтаныс адамдармен емес .

Деректер құрылымы

Деректер құрылымы - өзара байланысты элементтердің жиынтығы. Объектіні деректер құрылымы ретінде қарастырғанда, ол әдістермен өңделетін деректер элементтерінің жиынтығы, олардың болуы жанама түрде көрсетіледі. Яғни, мақсаты сақталған деректерді сақтау және пайдалану (өңдеу) болып табылатын an object. Кәдімгі нысаннан негізгі айырмашылығы - бұл an object бар болуы болжанатын деректер элементтерімен жұмыс істейтін әдістер жиынтығы. Сен түсінесің бе? Кәдімгі нысанда негізгі аспект әдістер болып табылады, ал ішкі айнымалылар олардың дұрыс жұмыс істеуіне бағытталған, бірақ деректер құрылымында бұл керісінше: әдістер мұнда негізгі болып табылатын сақталған элементтермен жұмысты қолдайды және көмектеседі. Деректер құрылымының бір түрі Деректерді тасымалдау нысаны (DTO) болып табылады . Бұл жалпы айнымалылары бар және дерекқорлармен жұмыс істеу кезінде деректерді беретін, ұялардан хабарларды талдаумен жұмыс істейтін және т.б. әдістері жоқ (немесе тек оқу/жазу әдістері) класс. Әдетте мұндай нысандардағы деректер ұзақ уақыт сақталмайды және қолданбамыз жұмыс істейтін нысанға дерлік түрлендірілді. Нысан өз кезегінде деректер құрылымы болып табылады, бірақ оның мақсаты қолданбаның әртүрлі деңгейлеріндегі бизнес логикасына қатысу, ал DTO қолданбаға/қосымшадан деректерді тасымалдау болып табылады. DTO мысалы:
@Setter
@Getter
@NoArgsConstructor
public class UserDto {
    private long id;
    private String firstName;
    private String lastName;
    private String email;
    private String password;
}
Барлығы түсінікті сияқты, бірақ бұл жерде гибридтердің бар екендігі туралы білеміз. Гибридтер маңызды логиканы өңдеу және ішкі элементтерді және оларға кіру әдістерін (алу/орнату) сақтау әдістерін қамтитын нысандар болып табылады. Мұндай нысандар ретсіз және жаңа әдістерді қосуды қиындатады. Сіз оларды пайдаланбауыңыз керек, өйткені олар не үшін арналғаны белгісіз - элементтерді сақтау немесе логиканың қандай да бір түрін орындау. Нысандардың ықтимал түрлері туралы осы жерден оқи аласыз .

Айнымалыларды құру принциптері

Кодты жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 6Айнымалылар туралы аздап ойланайық, дәлірек айтсақ, оларды құру принциптері қандай болуы мүмкін екендігі туралы ойланайық:
  1. Ең дұрысы, айнымалы мәнді қолданбас бұрын бірден жариялап, инициализациялау керек (оны жасап, ұмытып кетудің орнына).
  2. Мүмкіндігінше, инициализациядан кейін олардың мәні өзгермеуі үшін айнымалы мәндерді түпкілікті деп жариялаңыз.
  3. Есептегіш айнымалылар туралы ұмытпаңыз (әдетте біз оларды қандай да бір циклде қолданамыз for, яғни біз оларды қалпына келтіруді ұмытпауымыз керек, әйтпесе ол бүкіл логиканы бұзуы мүмкін).
  4. Конструктордағы айнымалы мәндерді инициализациялауға тырысу керек.
  5. Егер нысанды сілтемесі бар немесе сілтемесіз пайдалану арасында таңдау болса ( new SomeObject()), онсыз ( ) таңдаңыз, себебі бұл нысан бір рет пайдаланылған кезде келесі қоқыс жинау кезінде жойылады және ресурстарды ысырап етпейді.
  6. Айнымалылардың қызмет ету мерзімін мүмкіндігінше қысқа етіңіз (айнымалыны жасау мен соңғы қол жеткізу арасындағы қашықтық).
  7. Циклде пайдаланылатын айнымалы мәндерді циклды қамтитын әдістің басында емес, тікелей цикл алдында инициализациялаңыз.
  8. Әрқашан ең шектеулі аумақтан бастаңыз және оны қажет болған жағдайда ғана кеңейтіңіз (айнымалыны мүмкіндігінше жергілікті етуге тырысуыңыз керек).
  9. Әрбір айнымалыны тек бір мақсат үшін пайдаланыңыз.
  10. Жасырын мағыналары бар айнымалылардан аулақ болыңыз (айнымалы екі тапсырма арасында үзілген, яғни оның түрі олардың біреуін шешуге жарамайды).
Кодты жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 7

Әдістері

Кодты жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 8Біздің логикамызды жүзеге асыруға, атап айтқанда, әдістерге тікелей көшейік.
  1. Бірінші ереже - жинақылық. Ең дұрысы, бір әдіс 20 жолдан аспауы керек, сондықтан, айталық, жалпыға ортақ әдіс айтарлықтай «ісіп кетсе», бөлінген логиканы жеке әдістерге ауыстыру туралы ойлану керек.

  2. Екінші ереже - пәрмендердегі блоктар if, elseжәне whileт.б. жоғары кірістірілген болмауы керек: бұл codeтың оқылуын айтарлықтай төмендетеді. Ең дұрысы, ұя салу екі блоктан аспауы керек {}.

    Сондай-ақ бұл блоктардағы codeты ықшам және қарапайым етіп жасаған жөн.

  3. Үшінші ереже - әдіс тек бір операцияны орындауы керек. Яғни, егер әдіс күрделі, әртүрлі логиканы орындаса, біз оны ішкі әдістерге бөлеміз. Нәтижесінде әдістің өзі қасбет болады, оның мақсаты барлық басқа операцияларды дұрыс тәртіпте шақыру болып табылады.

    Бірақ операция бөлек әдісті жасау үшін тым қарапайым болып көрінсе ше? Иә, кейде бұл зеңбіректен торғай ату сияқты көрінуі мүмкін, бірақ шағын әдістер бірқатар артықшылықтарды береді:

    • codeты оқуды жеңілдету;
    • әдістер даму барысында күрделене түседі, ал егер әдіс бастапқыда қарапайым болса, оның функционалдығын қиынdate біршама жеңіл болады;
    • іске асыру мәліметтерін жасыру;
    • codeты қайта пайдалануды жеңілдету;
    • жоғары code сенімділігі.
  4. Төменгі ереже: codeты жоғарыдан төменге қарай оқу керек: неғұрлым төмен болса, соғұрлым логика тереңірек болады және керісінше, соғұрлым жоғарырақ, әдістер абстрактілі болады. Мысалы, коммутатор пәрмендері өте ықшам емес және қалаусыз, бірақ коммутаторды қолданбай жасай алмасаңыз, оны мүмкіндігінше төменірек, ең төменгі деңгей әдістеріне жылжытуға тырысыңыз.

  5. Әдіс аргументтері – қаншасы идеалды? Ең дұрысы, мүлде жоқ)) Бірақ бұл шынымен бола ма? Дегенмен, олардың мүмкіндігінше аз болуына тырысу керек, өйткені олар неғұрлым аз болса, бұл әдісті пайдалану оңайырақ және оны тексеру оңайырақ. Егер күмәніңіз болса, кіріс аргументтерінің көп саны бар әдісті пайдаланудың барлық сценарийлерін болжап көріңіз.

  6. Бөлек, кіріс аргументі ретінде логикалық жалауы бар әдістерді ерекше атап өткім келеді , өйткені бұл, әрине, бұл әдіс бірнеше операцияны орындайтынын білдіреді (егер шын болса, біреуі, жалған болса - басқа). Жоғарыда жазғанымдай, бұл жақсы емес және мүмкіндігінше аулақ болу керек.

  7. Егер әдісте кіріс аргументтерінің көп саны болса (төтенше мән 7, бірақ бұл туралы 2-3-тен кейін ойлану керек), кейбір аргументтерді бөлек нысанда топтау керек.

  8. Егер бірнеше ұқсас әдістер болса (шамадан тыс жүктелген) , онда ұқсас параметрлерді бірдей ретпен беру керек: бұл оқылу және пайдалану мүмкіндігін арттырады.

  9. Параметрлерді әдіске бергенде, олардың барлығы пайдаланылатынына сенімді болуыңыз керек, әйтпесе аргумент не үшін қажет? Оны интерфейстен кесіп тастаңыз және солай.

  10. try/catchОл өзінің табиғаты бойынша өте жақсы көрінбейді, сондықтан оны аралық бөлек әдіске (ерекшеліктерді өңдеу әдісі) көшіру жақсы қадам болады:

    public void exceptionHandling(SomeObject obj) {
        try {
            someMethod(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
Мен жоғарыда codeты қайталау туралы айттым, бірақ мен оны осында қосамын: Егер бізде code бөліктерін қайталайтын бірнеше әдіс болса, біз оны бөлек әдіске жылжытуымыз керек, бұл әдістің де, әдістің де жинақылығын арттырады. сынып. Және дұрыс атаулар туралы ұмытпаңыз. Класстарды, интерфейстерді, әдістерді және айнымалыларды дұрыс атау туралы мәліметтерді мақаланың келесі бөлімінде айтамын. Және бұл менде бүгінгі күннің бәрі. Код жазу ережелері: жүйені құрудан бастап an objectілермен жұмыс істеуге дейін – 9Код ережелері: дұрыс атау, жақсы және жаман пікірлердің күші
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION