{"id":302512,"date":"2020-04-26T03:00:12","date_gmt":"2020-04-26T03:00:12","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=302512"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=302512","title":{"rendered":"The Clear Architecture \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 TypeScript \u0438 React"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/499078\/\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/q7\/ls\/cw\/q7lscw7mpm4ex_ivtew-qlanrkw.jpeg\"><\/p>\n<p>  \u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c, \u0443\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u0431 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0432 \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435. \u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u0438 \u043c\u043e\u0438 \u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u044e <a href=\"https:\/\/blog.cleancoder.com\/uncle-bob\/2012\/08\/13\/the-clean-architecture.html\" rel=\"nofollow\">The Clean Architecture<\/a> \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 Frontend \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0432\u0437\u044f\u043b \u0435\u0435 \u043d\u0430 \u0432\u043e\u043e\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043d\u0430 TypeScript, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u0432 \u043c\u0438\u0440\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 React (\u0430 \u043f\u0440\u0438\u0448\u0435\u043b \u044f \u0438\u0437 Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0433\u0434\u0435 \u0434\u0430\u0432\u043d\u044b\u043c-\u0434\u0430\u0432\u043d\u043e, \u0435\u0449\u0435 \u0434\u043e Kotlin, \u043d\u0430\u0434\u0435\u043b\u0430\u043b\u0430 \u0448\u0443\u043c\u0438\u0445\u0438 <a href=\"https:\/\/fernandocejas.com\/2014\/09\/03\/architecting-android-the-clean-way\/\" rel=\"nofollow\">\u0441\u0442\u0430\u0442\u044c\u044f \u043e\u0442 Fernando Cejas<\/a>, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0438\u043d\u043e\u0433\u0434\u0430 \u0441\u0441\u044b\u043b\u0430\u044e\u0441\u044c).<\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u043e \u043d\u0430\u0448\u0435\u043c \u043e\u043f\u044b\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f The Clean Architecture \u0432 React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c TypeScript. \u0417\u0430\u0447\u0435\u043c \u044f \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u044e? \u2014 \u0418\u043d\u043e\u0433\u0434\u0430 \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0437\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0438 \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0449\u0435 \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u0442\u0430\u043a\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u0441 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u043c\u0438 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u044f \u0441\u043c\u043e\u0433\u0443 \u0441\u0441\u044b\u043b\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.<\/p>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<p>  <u><b>\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435<\/b><\/u><\/p>\n<ol>\n<li>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/li>\n<li>\u0422\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c\n<ul>\n<li>\u0414\u043b\u044f \u0447\u0435\u0433\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0443\u0436\u043d\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430?<\/li>\n<li>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 The Clean Architecture<\/li>\n<li>The Clean Architecture \u0434\u043b\u044f Frontend<\/li>\n<\/ul>\n<\/li>\n<li>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c<br \/> \n<ul>\n<li>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438<\/li>\n<li> \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/li>\n<li> UML \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/li>\n<li>\u0420\u0430\u0437\u0431\u043e\u0440 \u043a\u043e\u0434\u0430<\/li>\n<\/ul>\n<\/li>\n<li>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/li>\n<li>\u0420\u0435\u0441\u0443\u0440\u0441\u044b \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438<\/li>\n<\/ol>\n<p>  <b><u>1. \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/u><\/b><\/p>\n<p>  <b>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u2014 \u044d\u0442\u043e, \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0449\u044c.<\/b> \u0415\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0435 \u0432 \u0440\u0430\u0437\u0440\u0435\u0437\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0412\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0438\u0434\u0435\u0439 \u0432 \u0446\u0435\u043b\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0447\u0438\u0442 \u0437\u0430 \u0441\u0447\u0435\u0442 \u0447\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u043e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0442\u043e\u0442 \u0436\u0435, \u0447\u0442\u043e \u0438 \u0441 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 SOLID \u2014 \u043e\u043d\u0438 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043d\u044b \u043d\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0430 \u0434\u043b\u044f \u0446\u0435\u043b\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (\u043a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u041e\u041e\u041f). <\/p>\n<p>  \u0420\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e, \u043a\u043e\u0433\u0434\u0430 \u0432\u0438\u0434\u0438\u0448\u044c \u0432\u0441\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u201c\u0432 \u0442\u0435\u043e\u0440\u0438\u0438\u201d \u2014 \u0430 \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f \u0441 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f The Clean Architecture \u0432\u043e frontend\u2019e, \u0430 \u043f\u043e\u0442\u043e\u043c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 UML \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u043e\u0439 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<p>  \u0412\u0430\u0436\u043d\u043e\u0435 \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u0435: The Clean Architecture \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u0433\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043e\u043d\u0430 \u0434\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438. \u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438 \u044f\u0437\u044b\u043a\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u0432\u043e\u0438 \u043d\u044e\u0430\u043d\u0441\u044b. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u0440\u0435\u043f\u043e\u0434\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0441\u0435\u0439\u0447\u0430\u0441 \u2014 \u043e\u043d \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u043d\u0430\u0446\u0435\u0435\u0439.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043b\u044e\u0431\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u0434 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u043c. \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 JS \u0431\u0435\u0437 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440, \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0447\u0435\u0433\u043e \u2014 \u044d\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>  <u><b>2. \u0422\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c<\/b><\/u><\/p>\n<p>  <u><b>2.1. \u0414\u043b\u044f \u0447\u0435\u0433\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0443\u0436\u043d\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430?<\/b><\/u><\/p>\n<p>  <b>\u041e\u0442\u0432\u0435\u0442: \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0434\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u0438 \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0434\u043e\u043b\u0433\u043e\u0433\u043e \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/b><\/p>\n<p>  \u0411\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0431\u044b\u0432\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0437\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u2014 \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043a\u043d\u0438\u0433\u0435 The Clean Architecture \u0411\u043e\u0431\u0430 \u041c\u0430\u0440\u0442\u0438\u043d\u0430. \u0414\u043b\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f, \u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0433\u0440\u0430\u0444\u0438\u043a \u0438\u0437 \u044d\u0442\u043e\u0439 \u043a\u043d\u0438\u0433\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/7n\/t2\/pr\/7nt2praknbscvpol8lrcqetew7c.png\"><\/p>\n<p>  \u041d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0441 \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 (\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043e\u043d\u0438 \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0441 \u0440\u0430\u0432\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0430\u043c\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438) \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u0435 \u043c\u0435\u043d\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u043e\u043a, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u043e\u0441\u0442 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u0432\u0438\u0434\u0443 \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0430 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043d\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0443\u0441\u0438\u043b\u0438\u0439.<\/p>\n<p>  \u0412 \u043a\u043d\u0438\u0433\u0435 The Clean Architecture \u044d\u0442\u043e\u0442 \u0433\u0440\u0430\u0444\u0438\u043a \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043b\u043e\u0445\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u043e\u0438\u0442\u044c \u0434\u043e\u0440\u043e\u0436\u0435, \u0447\u0435\u043c \u0432\u044b\u0433\u043e\u0434\u0430 \u043e\u0442 \u0441\u0430\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0415\u0449\u0435 \u0440\u0430\u0437 \u043e \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\u041a\u0430\u043a \u0440\u0430\u0437 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0447\u0438\u0442\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u044e \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u0438 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0446\u0438\u0442\u0430\u0442\u0443 (\u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0433\u043b\u0430\u0441\u0435\u043d):<\/p>\n<blockquote><p>\u00ab\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0435 90 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u0434\u0430 \u0443\u0445\u043e\u0434\u0438\u0442 10 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043e\u0432 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443. \u041d\u0430 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f 10 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u0434\u0430 \u0443\u0445\u043e\u0434\u0438\u0442 \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f 90 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u043e\u0432\u00bb<\/p>\n<p>  \u2014 \u0422\u043e\u043c \u041a\u0430\u0440\u0433\u0438\u043b\u043b, Bell Labs<\/p><\/blockquote>\n<p>  \u0412\u044b\u0432\u043e\u0434: \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0440\u043e\u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0435 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.  <\/div>\n<\/p><\/div>\n<p>  \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0439 \u201c\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439\u201d \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u0430\u043a\u043e\u0439 \u043c\u044b (\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438, PM&#8217;\u044b, \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0438) \u0445\u043e\u0442\u0435\u043b\u0438 \u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/46\/h9\/_s\/46h9_st273xssd8efxtwezq5uhw.png\"><\/p>\n<p>  \u041d\u0430 \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u043e\u0441\u0442\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0442\u0440\u043e\u043a \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438. \u0421\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u043a\u043e\u0434\u0430 (\u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438) \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0440\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u0430\u0445 \u0441\u0442\u0440\u043e\u043a. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043c\u0430\u043b\u043e\u0432\u0435\u0440\u043e\u044f\u0442\u0435\u043d, \u0435\u0441\u043b\u0438 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0439 Enterprise \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f, \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u0442\u0438.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u044f \u043c\u043e\u0433\u0443 \u0412\u0430\u0441 \u0438 \u043e\u0431\u0440\u0430\u0434\u043e\u0432\u0430\u0442\u044c \u2014 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e Frontend \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445! \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u0440\u0430\u0432\u0434\u0435 \u0432 \u0433\u043b\u0430\u0437\u0430 \u2014 \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435 \u0432\u044b\u0440\u0430\u0441\u0442\u0430\u044e\u0442 \u0434\u043e \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a, \u0438\u043d\u0430\u0447\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u044b \u0431\u044b \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b\u0438 \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u043a\u0440\u0430\u0439\u043d\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043e\u043d\u0438 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b, \u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043b\u0435\u0436\u0438\u0442 \u043d\u0430 backend \u0441\u0442\u043e\u0440\u043e\u043d\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0435\u0440\u0435 \u043c\u043e\u0436\u0435\u043c \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0439 \u0432\u044b\u0448\u0435 \u0442\u0435\u043d\u0434\u0435\u043d\u0446\u0438\u0438 \u0440\u043e\u0441\u0442\u0430 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430 (\u0441 \u0440\u0430\u0437\u043d\u043e\u0439 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0441\u0442\u044c\u044e, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f). \u0415\u0441\u043b\u0438 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u0434\u0430\u0436\u0435 \u043d\u0430 50% \u0434\u0435\u0448\u0435\u0432\u043b\u0435 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f, \u0447\u0435\u043c \u043c\u043e\u0433 \u0431\u044b \u0431\u0435\u0437 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0430.<\/p>\n<p>  \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0432\u044b\u0441\u0442\u0440\u043e\u0438\u0432 \u0445\u043e\u0440\u043e\u0448\u0443\u044e \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 <b>\u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430<\/b>:<\/p>\n<ul>\n<li><b>\u0434\u0435\u0448\u0435\u0432\u043b\u0435 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430<\/b> (\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0445 \u0437\u0430\u0442\u0440\u0430\u0442);<\/li>\n<li><b>\u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430<\/b> (\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u044c\u0448\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u0432 \u0438 \u043d\u0438\u0436\u0435 \u043f\u043e\u0442\u0435\u0440\u0438 \u0438\u0437-\u0437\u0430 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u201c\u0431\u0430\u0433\u043e\u0432 \u043d\u0430 \u043f\u0440\u043e\u0434\u0435\u201d);<\/li>\n<li><b>\u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442<\/b>.<\/li>\n<\/ul>\n<p>  \u0414\u0443\u043c\u0430\u044e, \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 \u201c\u0430 \u0437\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e?!\u201d, \u044f \u043e\u0442\u0432\u0435\u0442\u0438\u043b. \u0414\u0430\u043b\u0435\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>  <u><b>2.2. \u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435<\/b><\/u><\/p>\n<p>  \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 The Clean Architecture, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u0430 \u0442\u0435\u043c\u0430 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0430 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u043e \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u0443\u044e \u0441\u0443\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>  \u0412 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0411\u043e\u0431\u0430 \u041c\u0430\u0440\u0442\u0438\u043d\u0430 2012-\u0433\u043e \u0433\u043e\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/58\/se\/fx\/58sefxx6ubqmvllmbzzwsiw_yz0.png\"><\/p>\n<p>  \u041a\u043b\u044e\u0447\u0435\u0432\u0430\u044f \u0438\u0434\u0435\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u043b\u043e\u0438 (\u0441\u043b\u043e\u0435\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e). <b>\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0441\u043b\u043e\u0438 \u043d\u0435 \u0437\u043d\u0430\u044e\u0442 \u043e \u0432\u043d\u0435\u0448\u043d\u0438\u0445, \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u044b \u0432 \u0446\u0435\u043d\u0442\u0440<\/b>. \u0427\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435 \u0441\u043b\u043e\u0439 \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430, \u0442\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u043d \u0437\u043d\u0430\u0435\u0442 \u043e \u201c\u043d\u0435\u0431\u0438\u0437\u0435\u0441\u043e\u0432\u044b\u0445\u201d \u0434\u0435\u0442\u0430\u043b\u044f\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e \u0437\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043d\u043e\u043f\u043e\u043a \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435).<\/p>\n<ul>\n<li><b>Entities.<\/b> \u0412 \u0446\u0435\u043d\u0442\u0440\u0435 \u0443 \u043d\u0430\u0441 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f Entities (\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438). \u0412 \u043d\u0438\u0445 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. Entities \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u043a\u043b\u0430\u0441\u0441 Cart (\u043a\u043e\u0440\u0437\u0438\u043d\u0430) \u2014 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u0432\u0430\u0440 \u0432 \u043a\u043e\u0440\u0437\u0438\u043d\u0443, \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u0438 \u0442.\u0434. \u041d\u0438\u0447\u0435\u0433\u043e \u043e \u0442\u0430\u043a\u0438\u0445 \u0432\u0435\u0449\u0430\u0445, \u043a\u0430\u043a React, \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043d\u043e\u043f\u043a\u0430\u0445 \u2014 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442.\n<p>  \u0413\u043e\u0432\u043e\u0440\u044f \u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432\u0432\u0438\u0434\u0443, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a\u0430\u043a React\\Angular\\Express\\Nest.js\\DI \u0438 \u0442.\u0434. \u0415\u0441\u043b\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0432\u0437\u044f\u0442\u044c \u0446\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438\u0437 Web-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 React\u2019e \u2014 \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u0434 \u0434\u043b\u044f NodeJS \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/li>\n<li><b>Use cases.<\/b> \u0412\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b Use Cases (\u043e\u043d\u0438 \u0436\u0435 \u2014 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043e\u043d\u0438 \u0436\u0435 \u2014 Interactors). \u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442, \u043a\u0430\u043a \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0437\u043d\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043a\u0430\u0437 \u2014 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u043d\u0430\u0435\u0442, \u0447\u0442\u043e \u0438\u0437 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u044d\u0442\u043e\u0442 \u0437\u0430\u043a\u0430\u0437 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 (\u0441\u043c. \u0434\u0430\u043b\u0435\u0435).<\/li>\n<li><b>Gateways, Presenters, etc.<\/b> \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 (Gateways = Repositories, Presenters = View Models) \u2014 \u0441\u043b\u043e\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c\u0438 \u0447\u0430\u0441\u0442\u044f\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API \u0438\u043b\u0438 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430\u043c, \u0430 View Model \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441 \u0432\u044b\u0437\u043e\u0432\u0430\u043c\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438.\n<p>  \u0423\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u0435: \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 Use Cases \u0438 Repositories, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0438\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b frontend \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 API.<\/li>\n<li><b>External interfaces.<\/b> \u041f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0439 \u0441\u043b\u043e\u0439. \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u044b\u0435 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a API, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b React&#8217;\u0430 \u0438 \u0442.\u0434. \u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u0441\u043b\u043e\u0439 \u0442\u0440\u0443\u0434\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0434\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e (\u043a\u043d\u043e\u043f\u043e\u0447\u043a\u0430 \u0432 React\u2019e \u2014 \u0435\u0441\u0442\u044c \u043a\u043d\u043e\u043f\u043e\u0447\u043a\u0430 React\u2019e ).<\/li>\n<\/ul>\n<p>  <b>2.3. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 frontend\u2019a<\/b><\/p>\n<p>  \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043d\u0430\u0448\u0435\u0439 frontend \u043e\u0431\u043b\u0430\u0441\u0442\u0438. \u0412 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 Frontend\u2019a, \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443 \u0432\u044b\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/gp\/5l\/_e\/gp5l_eksd3uomyw5w82-gigeozo.png\"><\/p>\n<ul>\n<li><b>Entities.<\/b> \u0411\u0438\u0437\u043d\u0435\u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u0438\u0435 \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0443\u043c\u0435\u044e\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0446\u0435\u043b\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u201c\u043a\u043e\u0440\u0437\u0438\u043d\u0430\u201d \u043c\u043e\u0436\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u0437\u0430\u043a\u0430\u0437\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0435\u0441\u0441\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438 (\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u0449\u0435\u0439 \u0446\u0435\u043d\u044b, \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u043e\u0432\u0430\u0440\u043e\u0432 \u0438 \u0442.\u0434.).<\/li>\n<li><b>Repository interfaces.<\/b> \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API, \u0411\u0414, \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430\u043c \u0438 \u0442. \u0434. \u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c, \u0447\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u201c\u0432\u044b\u0448\u0435\u201d \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u043d\u0430\u044e\u0442 \u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u0445 \u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0438\u0445. \u0410 \u0432\u043e\u0442 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u044e\u0442 \u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0437\u043d\u0430\u044e\u0442 \u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445. \u042d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438\u0437 SOLID\u2019a (\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u043c \u0441\u043b\u043e\u0435, \u0441\u0434\u0435\u043b\u0430\u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u043c). \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0434\u0435\u043b\u0430\u0435\u0442 \u043b\u0438 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a API \u0438\u043b\u0438 \u0431\u0435\u0440\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u0435\u0448\u0430).<\/li>\n<li><b>Use Cases<\/b>. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435. \u041e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0442. \u0435. \u043f\u043e\u043d\u0438\u043c\u0430\u044e\u0442, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u2014 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c, \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c, \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c).<\/li>\n<li><b>View Models \u0438 View Interfaces.<\/b>\n<p>  ViewModel \u2014 \u044d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0430 Presenters \u0438\u0437 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b. \u0412 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 MVVP \u0432\u043c\u0435\u0441\u0442\u043e MVP\\MVC\\MV*. \u0415\u0441\u043b\u0438 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043a\u0440\u0430\u0442\u043a\u043e, \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0441 MVP \u043b\u0438\u0448\u044c \u0432 \u043e\u0434\u043d\u043e\u043c: Presenter \u0437\u043d\u0430\u0435\u0442 \u043e View \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0435\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u0430 ViewModel \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043e View, \u0438\u043c\u0435\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445. View \u043f\u0440\u043e\u0441\u0442\u043e \u201c\u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u0442\u201d \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 View Model. MVVP \u0438\u043c\u0435\u0435\u0442 \u043e\u0434\u043d\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c (View \u2192 ViewModel), \u0430 MVP \u2014 \u0434\u0432\u0443\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u0443\u044e (View \ufe0e Presenter). \u041c\u0435\u043d\u044c\u0448\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u2014 \u043f\u0440\u043e\u0449\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  View Interfaces \u2014 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043e\u0434\u0438\u043d \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 View, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 View Model \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 View \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e \u0442\u0438\u043f\u0443 onViewModelChanged(): void. \u0415\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<\/li>\n<li><b>5. External interfaces.<\/b> \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435, \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u043e\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0438\u0436\u0435 \u2014 \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b React\u2019a \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u0436\u0435 \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a (AngularJS, React Native) \u0438 \u043b\u044e\u0431\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 (IndexDB, local storage \u0438 \u0442.\u0434.). The Clean Architecutre \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0434\u0430\u0432\u0430\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0435\u0440\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0445.<\/li>\n<\/ul>\n<p>  \u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0443 \u0432\u044b\u0448\u0435 \u0432 \u0432\u0438\u0434\u0435 \u0442\u0440\u0435\u0445\u0441\u043b\u043e\u0439\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043e\u043d\u0430 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xo\/wp\/vo\/xowpvop6kgrincjtlrapfycy6hm.png\"><\/p>\n<p>  \u041a\u0440\u0430\u0441\u043d\u044b\u0435 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 \u2014 \u043f\u043e\u0442\u043e\u043a \u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 (\u043d\u043e \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0430 \u043d\u0430 \u043a\u0440\u0443\u0433\u043e\u0432\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435 \u0432\u044b\u0448\u0435). \u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a \u0434\u0432\u0438\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418\u0434\u0435\u044e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0432 \u0432\u0438\u0434\u0435 \u0442\u0430\u043a\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b \u044f \u0443\u0432\u0438\u0434\u0435\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/company\/mobileup\/blog\/335382\/\">\u042d\u0422\u041e\u0419<\/a> \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>  \u0418\u043c\u0435\u0439\u0442\u0435 \u0432\u0432\u0438\u0434\u0443, \u0447\u0442\u043e \u0432 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u043b\u043e\u0435\u0432 \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u0441\u043b\u043e\u0435\u0432 \u0432\u044b\u0448\u0435, \u0447\u0435\u043c domain \u2014 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u0432\u043e\u0438 \u043c\u0430\u043f\u043f\u0435\u0440\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <b><u>3. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/u><\/b><\/p>\n<p>  <b><u>3.1. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438<\/u><\/b><\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0431\u044b\u043b\u043e \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u043c \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c, \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 \u0435\u0435 \u043e\u0441\u043d\u043e\u0432\u0435. \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/RostislavDugin\/clean-architecture-react-typescript\" rel=\"nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 GitHub<\/a>. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/br\/rj\/wy\/brrjwylya7qywcwp6vrjexacmk0.gif\"><\/p>\n<p>  \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043e\u043a\u043d\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0447\u0442\u043e\u0431\u044b \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0431\u044b\u043b\u0430 \u0443\u043c\u0435\u0441\u0442\u043d\u0430), \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u0432\u043e\u0434\u043d\u044b\u0435:<\/p>\n<ol>\n<li>\u041f\u043e\u043b\u044f \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c\u0438 (\u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f).<\/li>\n<li>\u0412\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u043f\u043e\u0447\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 (\u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f).<\/li>\n<li>\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0439\u0442\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430 API) \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u044e\u0447 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438.<\/li>\n<li>\u0414\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u0443 API \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0438 \u043a\u043b\u044e\u0447 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438.<\/li>\n<li>\u041f\u043e\u0441\u043b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0441\u043b\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439).<\/li>\n<li>\u041f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u043a\u043b\u044e\u0447 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0442\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438.<\/li>\n<\/ol>\n<p>  <b><u>3.2. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/u><\/b><\/p>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043f\u043a\u0438 src \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/cu\/5i\/gz\/cu5igzdr9m0fk_kvvyuqm_snlm0.png\"><\/p>\n<ul>\n<li><b>data <\/b> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u042d\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0440\u0430\u0439\u043d\u0438\u043c \u043a\u0440\u0443\u0433\u043e\u043c \u043d\u0430 \u043a\u0440\u0443\u0433\u043e\u0432\u043e\u0439 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u044d\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u044b \u0437\u043d\u0430\u044e\u0442 \u043e\u0431 API \u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0432\u0435\u0449\u0430\u0445 (local storage, cookie \u0438 \u0442.\u0434.).<\/li>\n<li><b>domain <\/b> \u2014 \u043a\u043b\u0430\u0441\u0441\u044b \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438. \u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f Entities, Use Cases \u0438 Repository Interfaces. \u0412 \u043f\u043e\u0434\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 entities \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0432\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438: models \u0438 structures. \u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 \u044d\u0442\u0438\u043c\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u043c\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e models \u2014 \u044d\u0442\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439, \u0430 structures \u2014 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 (\u043f\u043e \u0442\u0438\u043f\u0443 POJO \u0432 Java). \u042d\u0442\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 models \u043c\u044b \u043a\u043b\u0430\u0434\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u044b (\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438) \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438 \u0447\u0430\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c, \u0430 \u0432 structures \u2014 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u0432\u0438\u0434\u0435 JSON-\u043e\u0431\u044a\u0435\u043a\u0442\u0430 (json2ts, \u00ab\u043f\u0440\u0438\u0432\u0435\u0442\u00bb) \u0438 \u043c\u044b \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u044f\u043c\u0438.<\/li>\n<li><b>presentation <\/b> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 View Models, View Interfaces \u0438 View (\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432\u0441\u043a\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b), \u0430 \u0442\u0430\u043a\u0436\u0435 util \u2014 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0439, \u0443\u0442\u0438\u043b\u0438\u0442 \u0438 \u0442.\u043f.<\/li>\n<\/ul>\n<p>  \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043a\u043e\u0440\u043d\u0435 presentation \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043c\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0430\u0439\u0434\u0431\u0430\u0440\u0430 \u0438 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438.<\/p>\n<p>  <b><u>3.3. URM \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/u><\/b><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/580\/b00\/846\/580b008464e6c4e0ea26e20879989581.png\"><\/p>\n<p>  \u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u2014 <a href=\"https:\/\/github.com\/RostislavDugin\/clean-architecture-react-typescript\/tree\/master\/information\" rel=\"nofollow\">GitHub<\/a>.<\/p>\n<p>  \u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043f\u043e \u0441\u043b\u043e\u044f\u043c \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430\u043c\u0438. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0441\u043b\u043e\u044f Domain (\u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u043e\u0439).<\/p>\n<p>  <b><u>3.4. \u0420\u0430\u0437\u0431\u043e\u0440 \u043a\u043e\u0434\u0430<\/u><\/b><\/p>\n<p>  <b>Entities layer<\/b><\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043c\u044b \u043f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u043f\u043e \u0432\u0441\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0438\u0445 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0430\u043b\u044c\u043d\u0435\u0433\u043e \u043a\u0440\u0443\u0433\u0430 \u2014 Entities, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0435 \u0431\u0430\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b.<\/p>\n<p>  <i>AuthListener.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0435\u0439 \/\/ \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 AuthHolder export\u00a0default\u00a0interface\u00a0AuthListener\u00a0{ \u00a0\u00a0onAuthChanged():\u00a0void; }<\/code><\/pre>\n<p>  <i>AuthHolder.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">import\u00a0AuthListener\u00a0from\u00a0'.\/AuthListener';  \/\/ \u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (\u043f. 3.1.5). \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c presentation \u0441\u043b\u043e\u0439, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0430\u0442\u0442\u0435\u0440\u043d Observer \/\/ \u0441\u043e \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f\u043c\u0438 AuthListener export\u00a0default\u00a0class\u00a0AuthHolder\u00a0{ \u00a0\u00a0private\u00a0authListeners:\u00a0AuthListener[]; \u00a0\u00a0private\u00a0isAuthorized:\u00a0boolean; \u00a0\u00a0private\u00a0authToken:\u00a0string;  \u00a0\u00a0public\u00a0constructor()\u00a0{ \u00a0\u00a0\u00a0\u00a0this.isAuthorized\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0this.authListeners\u00a0=\u00a0[]; \u00a0\u00a0\u00a0\u00a0this.authToken\u00a0=\u00a0''; \u00a0\u00a0}  \u00a0\u00a0public\u00a0onSignedIn(authToken:\u00a0string):\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.isAuthorized\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0this.authToken\u00a0=\u00a0authToken; \u00a0\u00a0\u00a0\u00a0this.notifyListeners(); \u00a0\u00a0}  \u00a0\u00a0public\u00a0onSignedOut():\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.isAuthorized\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0this.authToken\u00a0=\u00a0''; \u00a0\u00a0\u00a0\u00a0this.notifyListeners(); \u00a0\u00a0}  \u00a0\u00a0public\u00a0isUserAuthorized():\u00a0boolean\u00a0{ \u00a0\u00a0\u00a0\u00a0return\u00a0this.isAuthorized; \u00a0\u00a0}  \u00a0\u00a0\/** \u00a0\u00a0\u00a0*\u00a0@throws\u00a0{Error}\u00a0if\u00a0user\u00a0is\u00a0not\u00a0authorized \u00a0\u00a0\u00a0*\/ \u00a0\u00a0public\u00a0getAuthToken():\u00a0string\u00a0{ \u00a0\u00a0\u00a0\u00a0if\u00a0(!this.isAuthorized)\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw\u00a0new\u00a0Error('User\u00a0is\u00a0not\u00a0authorized'); \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0return\u00a0this.authToken; \u00a0\u00a0}  \u00a0\u00a0public\u00a0addAuthListener(authListener:\u00a0AuthListener):\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.authListeners.push(authListener); \u00a0\u00a0}  \u00a0\u00a0public\u00a0removeAuthListener(authListener:\u00a0AuthListener):\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.authListeners.splice(this.authListeners.indexOf(authListener),\u00a01); \u00a0\u00a0}  \u00a0\u00a0private\u00a0notifyListeners():\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.authListeners.forEach((listener)\u00a0=&gt;\u00a0listener.onAuthChanged()); \u00a0\u00a0} }<\/code><\/pre>\n<p>  <i>AuthorizationResult.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u041f\u0440\u043e\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u044f\u043c\u0438 export\u00a0default\u00a0interface\u00a0AuthorizationResult\u00a0{ \u00a0\u00a0authorizationToken:\u00a0string; }<\/code><\/pre>\n<p>  <i>ValidationResult.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0415\u0449\u0435 \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u044f\u043c\u0438 export\u00a0default\u00a0interface\u00a0ValidationResult\u00a0{ \u00a0\u00a0validationKey:\u00a0string; }<\/code><\/pre>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0441\u043b\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 (\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f) \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043e \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>  \u0427\u0430\u0441\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u0446\u0435\u043b\u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0441\u0432\u044f\u0437\u043a\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0441\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f (\u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445).<\/p>\n<p>  <b>Repository interfaces<\/b><\/p>\n<p>  <i>AuthRepository.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">import\u00a0ValidationResult\u00a0from\u00a0'..\/..\/entity\/auth\/stuctures\/ValidationResult'; import\u00a0AuthorizationResult\u00a0from\u00a0'..\/..\/entity\/auth\/stuctures\/AuthorizationResult';  \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0442\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API export\u00a0default\u00a0interface\u00a0AuthRepository\u00a0{ \u00a0\u00a0\/** \u00a0\u00a0\u00a0*\u00a0@throws\u00a0{Error}\u00a0if\u00a0validation\u00a0has\u00a0not\u00a0passed \u00a0\u00a0\u00a0*\/ \u00a0\u00a0validateCredentials(email:\u00a0string,\u00a0password:\u00a0string):\u00a0Promise&lt;ValidationResult&gt;;  \u00a0\u00a0\/** \u00a0\u00a0\u00a0*\u00a0@throws\u00a0{Error}\u00a0if\u00a0credentials\u00a0have\u00a0not\u00a0passed \u00a0\u00a0\u00a0*\/ \u00a0\u00a0login(email:\u00a0string,\u00a0password:\u00a0string,\u00a0validationKey:\u00a0string):\u00a0Promise&lt;AuthorizationResult&gt;; }<\/code><\/pre>\n<p>  <b>Use Cases<\/b><\/p>\n<p>  <i>LoginUseCase.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">import\u00a0AuthRepository\u00a0from\u00a0'..\/..\/repository\/auth\/AuthRepository'; import\u00a0AuthHolder\u00a0from\u00a0'..\/..\/entity\/auth\/models\/AuthHolder';  export\u00a0default\u00a0class\u00a0LoginUseCase\u00a0{ \u00a0\u00a0private\u00a0authRepository:\u00a0AuthRepository; \u00a0\u00a0private\u00a0authHolder:\u00a0AuthHolder;  \u00a0\u00a0public\u00a0constructor(authRepository:\u00a0AuthRepository,\u00a0authHolder:\u00a0AuthHolder)\u00a0{ \u00a0\u00a0\u00a0\u00a0this.authRepository\u00a0=\u00a0authRepository; \u00a0\u00a0\u00a0\u00a0this.authHolder\u00a0=\u00a0authHolder; \u00a0\u00a0}  \u00a0\u00a0\/** \u00a0\u00a0\u00a0*\u00a0@throws\u00a0{Error}\u00a0if\u00a0credentials\u00a0are\u00a0not\u00a0valid\u00a0or\u00a0have\u00a0not\u00a0passed \u00a0\u00a0\u00a0*\/ \u00a0\u00a0public\u00a0async\u00a0loginUser(email:\u00a0string,\u00a0password:\u00a0string):\u00a0Promise&lt;void&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0const\u00a0validationResult\u00a0=\u00a0await\u00a0this.authRepository.validateCredentials(email,\u00a0password); \u00a0\u00a0\u00a0\u00a0const\u00a0authResult\u00a0=\u00a0await\u00a0this.authRepository.login( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0email, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0password, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0validationResult.validationKey, \u00a0\u00a0\u00a0\u00a0);  \u00a0\u00a0\u00a0\u00a0this.authHolder.onSignedIn(authResult.authorizationToken); \u00a0\u00a0} }<\/code><\/pre>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 Use Case \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434. \u041e\u0431\u044b\u0447\u043d\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2013 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e, \u0430 \u043f\u043e\u0442\u043e\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432 API \u043c\u0435\u0442\u043e\u0434 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u0436\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u0438\u043d, \u0435\u0441\u043b\u0438 \u0438\u043c\u0435\u044e\u0442 \u043e\u0431\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<p>  \u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u043b\u043e\u0433\u0438\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445. \u0421\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u043b\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 Use Case \u0447\u0430\u0441\u0442\u043e \u0441\u043b\u0443\u0436\u0438\u0442 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u043b\u043e\u0435.<\/p>\n<p>  <b>Repository implenetation<\/b><\/p>\n<p>  <i>AuthFakeApi.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">import\u00a0AuthRepository\u00a0from\u00a0'..\/..\/domain\/repository\/auth\/AuthRepository'; import\u00a0ValidationResult\u00a0from\u00a0'..\/..\/domain\/entity\/auth\/stuctures\/ValidationResult'; import\u00a0AuthorizationResult\u00a0from\u00a0'..\/..\/domain\/entity\/auth\/stuctures\/AuthorizationResult';  \/\/ \u041a\u043b\u0430\u0441\u0441, \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a API export\u00a0default\u00a0class\u00a0AuthFakeApi\u00a0implements\u00a0AuthRepository\u00a0{ \u00a0\u00a0\/** \u00a0\u00a0\u00a0*\u00a0@throws\u00a0{Error}\u00a0if\u00a0validation\u00a0has\u00a0not\u00a0passed \u00a0\u00a0\u00a0*\/ \u00a0\u00a0validateCredentials(email:\u00a0string,\u00a0password:\u00a0string):\u00a0Promise&lt;ValidationResult&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0return\u00a0new\u00a0Promise((resolve,\u00a0reject)\u00a0=&gt;\u00a0{       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0431\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(password.length\u00a0&lt;\u00a05)\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reject(new\u00a0Error('Password\u00a0length\u00a0should\u00a0be\u00a0more\u00a0than\u00a05\u00a0characters')); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0resolve({ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0validationKey:\u00a0'A34dZ7', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0}  \u00a0\u00a0\/** \u00a0\u00a0\u00a0*\u00a0@throws\u00a0{Error}\u00a0if\u00a0credentials\u00a0have\u00a0not\u00a0passed \u00a0\u00a0\u00a0*\/ \u00a0\u00a0login(email:\u00a0string,\u00a0password:\u00a0string,\u00a0validationKey:\u00a0string):\u00a0Promise&lt;AuthorizationResult&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0return\u00a0new\u00a0Promise((resolve,\u00a0reject)\u00a0=&gt;\u00a0{       \/\/ \u0418\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043a\u043b\u044e\u0447\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(validationKey\u00a0===\u00a0'A34dZ7')\u00a0{         \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u0441 \u043b\u043e\u0433\u0438\u043d\u043e\u043c user@email.com \u0438 \u043f\u0430\u0440\u043e\u043b\u0435\u043c password \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(email\u00a0===\u00a0'user@email.com'\u00a0&amp;&amp;\u00a0password\u00a0===\u00a0'password')\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0resolve({ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0authorizationToken:\u00a0'Bearer\u00a0ASKJdsfjdijosd93wiesf93isef', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0else\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reject(new\u00a0Error('Validation\u00a0key\u00a0is\u00a0not\u00a0correct.\u00a0Please\u00a0try\u00a0later')); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reject(new\u00a0Error('Email\u00a0or\u00a0password\u00a0is\u00a0not\u00a0correct')); \u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0} } <\/code><\/pre>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API. \u041c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c Promise, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0440\u043d\u0443\u043b \u0431\u044b \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 fetch-\u0437\u0430\u043f\u0440\u043e\u0441. \u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 API \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u043a\u043b\u0430\u0441\u0441 AuthFakeApi \u043d\u0430 AuthApi \u0432 \u0444\u0430\u0439\u043b\u0435 App.tsx \u0438\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0435 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0430\u043d\u043d\u043e\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043e\u0448\u0438\u0431\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, TypeScript \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u043f\u043e \u0442\u0438\u043f\u0443 throws \u0432 Java, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e.<\/p>\n<p>  <b>util (presentation \u0441\u043b\u043e\u0439)<\/b><\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043c\u044b \u043a\u043b\u0430\u0434\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u044e\u0442 \u043b\u043e\u0433\u0438\u043a\u0443 \u201c\u043f\u0440\u0435\u0432\u0435\u043d\u0442\u0438\u0432\u043d\u043e\u0439\u201d \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 UI \u0441\u043b\u043e\u0435\u043c.<\/p>\n<p>  <i>FormValidator.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\">export\u00a0default\u00a0class\u00a0FormValidator\u00a0{ \u00a0\u00a0static\u00a0isValidEmail(email:\u00a0string):\u00a0boolean\u00a0{ \u00a0\u00a0\u00a0\u00a0const\u00a0emailRegex\u00a0=\u00a0\/^\\S+@\\S+\\.\\S+$\/; \u00a0\u00a0\u00a0\u00a0return\u00a0emailRegex.test(email); \u00a0\u00a0} }<\/code><\/pre>\n<p>  <b>View interfaces<\/b><\/p>\n<p>  <i>BaseView.tsx<\/i><\/p>\n<p>  \u041a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 View Model \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c View \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u043c\u0438 View \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438.<\/p>\n<pre><code class=\"javascript\">export\u00a0default\u00a0interface\u00a0BaseView\u00a0{ \u00a0\u00a0onViewModelChanged():\u00a0void; }<\/code><\/pre>\n<p>  <b>View Models<\/b><\/p>\n<p>  <i>BaseViewModel.tsx<\/i><\/p>\n<p>  \u041a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 View Model \u0438 View. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u043c\u0438 View Models.<\/p>\n<pre><code class=\"javascript\">import\u00a0BaseView\u00a0from\u00a0'..\/view\/BaseView';  export\u00a0default\u00a0interface\u00a0BaseViewModel\u00a0{ \u00a0\u00a0attachView(baseView:\u00a0BaseView):\u00a0void; \u00a0\u00a0detachView():\u00a0void; }<\/code><\/pre>\n<p>  <i>AuthViewModel.tsx<\/i><\/p>\n<pre><code class=\"javascript\">import\u00a0BaseViewModel\u00a0from\u00a0'..\/BaseViewModel';  \/\/ \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 ViewModel, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d View. \u0417\u0434\u0435\u0441\u044c \/\/ \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c View export\u00a0default\u00a0interface\u00a0AuthViewModel\u00a0extends\u00a0BaseViewModel\u00a0{ \u00a0\u00a0emailQuery:\u00a0string; \u00a0\u00a0passwordQuery:\u00a0string; \u00a0\u00a0isSignInButtonVisible:\u00a0boolean; \u00a0\u00a0isSignOutButtonVisible:\u00a0boolean;  \u00a0\u00a0isShowError:\u00a0boolean; \u00a0\u00a0errorMessage:\u00a0string;  \u00a0\u00a0authStatus:\u00a0string; \u00a0\u00a0isAuthStatusPositive:\u00a0boolean;  \u00a0\u00a0onEmailQueryChanged(loginQuery:\u00a0string):\u00a0void; \u00a0\u00a0onPasswordQueryChanged(passwordQuery:\u00a0string):\u00a0void; \u00a0\u00a0onClickSignIn():\u00a0void; \u00a0\u00a0onClickSignOut():\u00a0void; }<\/code><\/pre>\n<p>  <i>AuthViewModelImpl.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\"> import\u00a0AuthViewModel\u00a0from\u00a0'.\/AuthViewModel'; import\u00a0BaseView\u00a0from\u00a0'..\/..\/view\/BaseView'; import\u00a0LoginUseCase\u00a0from\u00a0'..\/..\/..\/domain\/interactors\/auth\/LoginUseCase'; import\u00a0AuthHolder\u00a0from\u00a0'..\/..\/..\/domain\/entity\/auth\/models\/AuthHolder'; import\u00a0AuthListener\u00a0from\u00a0'..\/..\/..\/domain\/entity\/auth\/models\/AuthListener'; import\u00a0FormValidator\u00a0from\u00a0'..\/..\/util\/FormValidator';  export\u00a0default\u00a0class\u00a0AuthViewModelImpl\u00a0implements\u00a0AuthViewModel,\u00a0AuthListener\u00a0{ \u00a0\u00a0public\u00a0emailQuery:\u00a0string; \u00a0\u00a0public\u00a0passwordQuery:\u00a0string; \u00a0\u00a0public\u00a0isSignInButtonVisible:\u00a0boolean; \u00a0\u00a0public\u00a0isSignOutButtonVisible:\u00a0boolean;  \u00a0\u00a0public\u00a0isShowError:\u00a0boolean; \u00a0\u00a0public\u00a0errorMessage:\u00a0string;  \u00a0\u00a0public\u00a0authStatus:\u00a0string; \u00a0\u00a0public\u00a0isAuthStatusPositive:\u00a0boolean;  \u00a0\u00a0private\u00a0baseView?:\u00a0BaseView; \u00a0\u00a0private\u00a0loginUseCase:\u00a0LoginUseCase; \u00a0\u00a0private\u00a0authHolder:\u00a0AuthHolder;  \u00a0\u00a0public\u00a0constructor(loginUseCase:\u00a0LoginUseCase,\u00a0authHolder:\u00a0AuthHolder)\u00a0{ \u00a0\u00a0\u00a0\u00a0this.emailQuery\u00a0=\u00a0''; \u00a0\u00a0\u00a0\u00a0this.passwordQuery\u00a0=\u00a0''; \u00a0\u00a0\u00a0\u00a0this.isSignInButtonVisible\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0this.isSignOutButtonVisible\u00a0=\u00a0false;  \u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0'';  \u00a0\u00a0\u00a0\u00a0this.authStatus\u00a0=\u00a0'is\u00a0not\u00a0authorized'; \u00a0\u00a0\u00a0\u00a0this.isAuthStatusPositive\u00a0=\u00a0false;  \u00a0\u00a0\u00a0\u00a0this.loginUseCase\u00a0=\u00a0loginUseCase; \u00a0\u00a0\u00a0\u00a0this.authHolder = authHolder;      \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438     this.authHolder.addAuthListener(this);   }    public attachView = (baseView: BaseView): void =&gt; {     this.baseView = baseView;   };    public detachView = (): void =&gt; {     this.baseView = undefined;   };    \/\/ \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 AuthListener \u00a0\u00a0public\u00a0onAuthChanged\u00a0=\u00a0():\u00a0void\u00a0=&gt;\u00a0{     \/\/ \u0418\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438, \u0447\u0442\u043e\u0431\u044b View     \/\/ \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u00a0\u00a0\u00a0\u00a0if\u00a0(this.authHolder.isUserAuthorized())\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isSignInButtonVisible\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isSignOutButtonVisible\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.authStatus\u00a0=\u00a0'authorized'; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isAuthStatusPositive\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0}\u00a0else\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isSignInButtonVisible\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isSignOutButtonVisible\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.authStatus\u00a0=\u00a0'is\u00a0not\u00a0autorized'; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isAuthStatusPositive\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0this.notifyViewAboutChanges(); \u00a0\u00a0};  \u00a0\u00a0public\u00a0onEmailQueryChanged\u00a0=\u00a0(loginQuery:\u00a0string):\u00a0void\u00a0=&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0this.emailQuery\u00a0=\u00a0loginQuery; \u00a0\u00a0\u00a0\u00a0this.notifyViewAboutChanges(); \u00a0\u00a0};  \u00a0\u00a0public\u00a0onPasswordQueryChanged\u00a0=\u00a0(passwordQuery:\u00a0string):\u00a0void\u00a0=&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0this.passwordQuery\u00a0=\u00a0passwordQuery; \u00a0\u00a0\u00a0\u00a0this.notifyViewAboutChanges(); \u00a0\u00a0};  \u00a0\u00a0public\u00a0onClickSignIn\u00a0=\u00a0async\u00a0():\u00a0Promise&lt;void&gt;\u00a0=&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0if\u00a0(!this.validateLoginForm())\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.notifyViewAboutChanges(); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0try\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0await\u00a0this.loginUseCase.loginUser(this.emailQuery,\u00a0this.passwordQuery); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0''; \u00a0\u00a0\u00a0\u00a0}\u00a0catch\u00a0(e)\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0e.message; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0this.notifyViewAboutChanges(); \u00a0\u00a0};  \u00a0\u00a0public\u00a0onClickSignOut\u00a0=\u00a0():\u00a0void\u00a0=&gt;\u00a0{     \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0435\u0437 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0430 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u00a0\u00a0\u00a0\u00a0this.authHolder.onSignedOut(); \u00a0\u00a0};  \u00a0\u00a0private\u00a0validateLoginForm\u00a0=\u00a0():\u00a0boolean\u00a0=&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0if\u00a0(!this.emailQuery)\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0'Email\u00a0cannot\u00a0be\u00a0empty'; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0false; \u00a0\u00a0\u00a0\u00a0}     \/\/ \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435 \u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u00a0\u00a0\u00a0\u00a0if\u00a0(this.errorMessage\u00a0===\u00a0'Email\u00a0cannot\u00a0be\u00a0empty')\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0''; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0if\u00a0(!FormValidator.isValidEmail(this.emailQuery))\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0'Email\u00a0format\u00a0is\u00a0not\u00a0valid'; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0false; \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0if\u00a0(this.errorMessage\u00a0===\u00a0'Email\u00a0format\u00a0is\u00a0not\u00a0valid')\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0''; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0if\u00a0(!this.passwordQuery)\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0true; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0'Password\u00a0cannot\u00a0be\u00a0empty'; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0false; \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0if\u00a0(this.errorMessage\u00a0===\u00a0'Password\u00a0cannot\u00a0be\u00a0empty')\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.isShowError\u00a0=\u00a0false; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.errorMessage\u00a0=\u00a0''; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0return\u00a0true; \u00a0\u00a0}  \u00a0\u00a0private\u00a0notifyViewAboutChanges\u00a0=\u00a0():\u00a0void\u00a0=&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0if\u00a0(this.baseView)\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.baseView.onViewModelChanged(); \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0}; } <\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043c\u0435\u0442\u043e\u0434 <code>onClickSignOut<\/code> \u2014 \u0432 \u043d\u0435\u043c \u043c\u044b \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043a\u043b\u0430\u0441\u0441\u0443 AuthHolder. \u042d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0442\u0435\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a \u0432 \u0432\u0438\u0434\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u044b\u043b \u0431\u044b \u043b\u0438\u0448\u043d\u0438\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435\u0432. <\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u0434\u0430, \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u2014 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <b>UI (views)<\/b><\/p>\n<p>  <i>AuthComponent.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\"> import\u00a0React\u00a0from\u00a0'react'; import\u00a0'.\/auth-component.css'; import\u00a0BaseView\u00a0from\u00a0'..\/BaseView'; import\u00a0AuthViewModel\u00a0from\u00a0'..\/..\/view-model\/auth\/AuthViewModel';  export\u00a0interface\u00a0AuthComponentProps\u00a0{ \u00a0\u00a0authViewModel:\u00a0AuthViewModel; }  export\u00a0interface\u00a0AuthComponentState\u00a0{ \u00a0\u00a0emailQuery:\u00a0string; \u00a0\u00a0passwordQuery:\u00a0string; \u00a0\u00a0isSignInButtonVisible:\u00a0boolean; \u00a0\u00a0isSignOutButtonVisible:\u00a0boolean;  \u00a0\u00a0isShowError:\u00a0boolean; \u00a0\u00a0errorMessage:\u00a0string;  \u00a0\u00a0authStatus:\u00a0string; \u00a0\u00a0isAuthStatusPositive:\u00a0boolean; }  export\u00a0default\u00a0class\u00a0AuthComponent\u00a0   extends\u00a0React.Component&lt;AuthComponentProps,\u00a0AuthComponentState&gt; \u00a0\u00a0implements\u00a0BaseView\u00a0{ \u00a0\u00a0private\u00a0authViewModel:\u00a0AuthViewModel;  \u00a0\u00a0public\u00a0constructor(props:\u00a0AuthComponentProps)\u00a0{ \u00a0\u00a0\u00a0\u00a0super(props);  \u00a0\u00a0\u00a0\u00a0const\u00a0{\u00a0authViewModel\u00a0}\u00a0=\u00a0this.props; \u00a0\u00a0\u00a0\u00a0this.authViewModel\u00a0=\u00a0authViewModel;  \u00a0\u00a0\u00a0\u00a0this.state\u00a0=\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0emailQuery:\u00a0authViewModel.emailQuery, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0passwordQuery:\u00a0authViewModel.passwordQuery, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isSignInButtonVisible:\u00a0authViewModel.isSignInButtonVisible, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isSignOutButtonVisible:\u00a0authViewModel.isSignOutButtonVisible,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isShowError:\u00a0authViewModel.isShowError, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0errorMessage:\u00a0authViewModel.errorMessage,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0authStatus:\u00a0authViewModel.authStatus, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isAuthStatusPositive:\u00a0authViewModel.isAuthStatusPositive, \u00a0\u00a0\u00a0\u00a0}; \u00a0\u00a0}  \u00a0\u00a0public\u00a0componentDidMount():\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.authViewModel.attachView(this); \u00a0\u00a0}  \u00a0\u00a0public\u00a0componentWillUnmount():\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.authViewModel.detachView(); \u00a0\u00a0}    \/\/ \u041f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 ViewModel, \u043c\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c    \/\/ state \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u00a0\u00a0public\u00a0onViewModelChanged():\u00a0void\u00a0{ \u00a0\u00a0\u00a0\u00a0this.setState({ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0emailQuery:\u00a0this.authViewModel.emailQuery, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0passwordQuery:\u00a0this.authViewModel.passwordQuery, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isSignInButtonVisible:\u00a0this.authViewModel.isSignInButtonVisible, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isSignOutButtonVisible:\u00a0this.authViewModel.isSignOutButtonVisible,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isShowError:\u00a0this.authViewModel.isShowError, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0errorMessage:\u00a0this.authViewModel.errorMessage,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0authStatus:\u00a0this.authViewModel.authStatus, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isAuthStatusPositive:\u00a0this.authViewModel.isAuthStatusPositive, \u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0}  \u00a0\u00a0public\u00a0render():\u00a0JSX.Element\u00a0{ \u00a0\u00a0\u00a0\u00a0const\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0emailQuery, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0passwordQuery, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isSignInButtonVisible, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isSignOutButtonVisible,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isShowError, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0errorMessage,  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0authStatus, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0isAuthStatusPositive, \u00a0\u00a0\u00a0\u00a0}\u00a0=\u00a0this.state;  \u00a0\u00a0\u00a0\u00a0return\u00a0( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;row\u00a0flex-grow-1\u00a0d-flex\u00a0justify-content-center\u00a0align-items-center&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;auth-container\u00a0col\u00a0bg-white\u00a0border\u00a0rounded-lg\u00a0py-4\u00a0px-5&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;row\u00a0mt-2\u00a0mb-4&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Status:&nbsp; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span\u00a0className={`${isAuthStatusPositive\u00a0?\u00a0'text-success'\u00a0:\u00a0'text-danger'}`}&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{authStatus} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/span&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;row\u00a0mt-2&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=&quot;text&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0placeholder=&quot;user@email.com&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={(e:\u00a0React.FormEvent&lt;HTMLInputElement&gt;):\u00a0void\u00a0=&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.authViewModel.onEmailQueryChanged(e.currentTarget.value); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={emailQuery} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=&quot;form-control&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;row\u00a0mt-2&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=&quot;password&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0placeholder=&quot;password&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={(e:\u00a0React.FormEvent&lt;HTMLInputElement&gt;):\u00a0void\u00a0=&gt;\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.authViewModel.onPasswordQueryChanged(e.currentTarget.value); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={passwordQuery} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=&quot;form-control&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{isShowError\u00a0&amp;&amp;\u00a0( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;row\u00a0my-3\u00a0text-danger\u00a0justify-content-center&quot;&gt;{errorMessage}&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)}  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{isSignInButtonVisible\u00a0&amp;&amp;\u00a0( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;row\u00a0mt-4&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=&quot;button&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=&quot;col\u00a0btn\u00a0btn-primary&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={():\u00a0void\u00a0=&gt;\u00a0this.authViewModel.onClickSignIn()} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Sign\u00a0in \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/button&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)}  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{isSignOutButtonVisible\u00a0&amp;&amp;\u00a0( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;row\u00a0mt-4&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;button \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=&quot;button&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=&quot;col\u00a0btn\u00a0btn-primary&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={():\u00a0void\u00a0=&gt;\u00a0this.authViewModel.onClickSignOut()} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Sign\u00a0out \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/button&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0); \u00a0\u00a0} } <\/code><\/pre>\n<p>  \u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c \u043e\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0438, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u0440\u0430\u0439\u043d\u0435\u043c \u0441\u043b\u043e\u0435 \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u044b.<\/p>\n<p>  <i>AuthComponent<\/i> \u043f\u0440\u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 (<code>componentDidMount<\/code>) \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f \u043a <i>AuthViewModel <\/i>\u0438 \u043e\u0442\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0438\u0441\u0447\u0435\u0437\u043d\u043e\u0432\u0435\u043d\u0438\u0438 (<code>componentWillUnmount<\/code>). \u041f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 <i>ViewModel<\/i>, <i>AuthComponent <\/i>\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438.<\/p>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<pre><code class=\"javascript\"> {isSignOutButtonVisible\u00a0&amp;&amp;\u00a0(   &lt;div\u00a0className=&quot;row\u00a0mt-4&quot;&gt; \u00a0\u00a0  &lt;button \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=&quot;button&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=&quot;col\u00a0btn\u00a0btn-primary&quot; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={():\u00a0void\u00a0=&gt;\u00a0this.authViewModel.onClickSignOut()} \u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0  Sign\u00a0out \u00a0\u00a0\u00a0\u00a0&lt;\/button&gt; \u00a0\u00a0&lt;\/div&gt; )} <\/code><\/pre>\n<p>  \u0410 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043c\u0435\u0442\u043e\u0434\u0430\u043c ViewModel \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"javascript\">onClick={():\u00a0void\u00a0=&gt;\u00a0this.authViewModel.onClickSignOut()}<\/code><\/pre>\n<p>  <b>Entry point<\/b><\/p>\n<p>  \u0414\u043b\u044f \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0430\u0439\u043b\u044b <i>index.tsx<\/i> \u0438 <i>App.tsx<\/i>.<\/p>\n<p>  <i>index.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\"> import\u00a0React\u00a0from\u00a0'react'; import\u00a0ReactDOM\u00a0from\u00a0'react-dom'; import\u00a0'bootstrap\/dist\/css\/bootstrap.css';  import\u00a0App\u00a0from\u00a0'.\/App'; import\u00a0*\u00a0as\u00a0serviceWorker\u00a0from\u00a0'.\/serviceWorker';  ReactDOM.render( \u00a0\u00a0&lt;React.StrictMode&gt; \u00a0\u00a0\u00a0\u00a0&lt;App\u00a0\/&gt; \u00a0\u00a0&lt;\/React.StrictMode&gt;, \u00a0\u00a0document.getElementById('root'), );  serviceWorker.unregister(); <\/code><\/pre>\n<p>  <i>App.tsx<\/i>  <\/p>\n<pre><code class=\"javascript\"> import\u00a0React\u00a0from\u00a0'react'; import\u00a0'.\/app.css'; import\u00a0AuthComponent\u00a0from\u00a0'.\/presentation\/view\/auth\/AuthComponent'; import\u00a0AuthViewModelImpl\u00a0from\u00a0'.\/presentation\/view-model\/auth\/AuthViewModelImpl'; import\u00a0AuthFakeApi\u00a0from\u00a0'.\/data\/auth\/AuthFakeApi'; import\u00a0LoginUseCase\u00a0from\u00a0'.\/domain\/interactors\/auth\/LoginUseCase'; import\u00a0AuthHolder\u00a0from\u00a0'.\/domain\/entity\/auth\/models\/AuthHolder';  function\u00a0App():\u00a0JSX.Element\u00a0{ \u00a0\u00a0\/\/\u00a0data\u00a0layer \u00a0\u00a0const\u00a0authRepository\u00a0=\u00a0new\u00a0AuthFakeApi(); \u00a0\u00a0\/\/\u00a0domain\u00a0layer \u00a0\u00a0const\u00a0authHolder\u00a0=\u00a0new\u00a0AuthHolder(); \u00a0\u00a0const\u00a0loginUseCase\u00a0=\u00a0new\u00a0LoginUseCase(authRepository,\u00a0authHolder); \u00a0\u00a0\/\/\u00a0view\u00a0layer \u00a0\u00a0const\u00a0authViewModel\u00a0=\u00a0new\u00a0AuthViewModelImpl(loginUseCase,\u00a0authHolder);  \u00a0\u00a0return\u00a0( \u00a0\u00a0\u00a0\u00a0&lt;div\u00a0className=&quot;app-container\u00a0d-flex\u00a0container-fluid&quot;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;AuthComponent\u00a0authViewModel={authViewModel}\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0); }  export\u00a0default\u00a0App; <\/code><\/pre>\n<p>  \u0418\u043c\u0435\u043d\u043d\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 <i>App.tsx<\/i> \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043b\u0438\u0448\u043d\u0435 \u043d\u0435 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c \u043a\u043e\u0434.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0435 \u0432 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"javascript\">const\u00a0authRepository\u00a0=\u00a0new\u00a0AuthFakeApi();<\/code><\/pre>\n<p>  \u041d\u0430\u043f\u0438\u0448\u0435\u043c:<\/p>\n<pre><code class=\"javascript\">const\u00a0authRepository\u00a0=\u00a0new\u00a0AuthApi();<\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u0430 \u043d\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438). \u041f\u0440\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043c\u044b \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"javascript\">const\u00a0authRepository: AuthRepository\u00a0=\u00a0new\u00a0AuthFakeApi();<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0435 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430).<\/p>\n<p>  <b>4. \u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/b><\/p>\n<p>  \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432 \u0445\u043e\u0434\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0443 \u0432\u0430\u0441 \u0441\u043b\u043e\u0436\u0438\u043b\u043e\u0441\u044c \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c The Clean Architecture \u0432 React (\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445), \u0438 \u043d\u0430\u0448 \u043e\u043f\u044b\u0442 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0430\u0448\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438.<\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u044b\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f The Clean Architecture \u0432 frontend \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445. \u041a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, The Clean Architecture \u0434\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0412\u0430\u0448\u0443 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443.<\/p>\n<p>  \u0412\u044b\u0448\u0435 \u0431\u044b\u043b \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443. \u0423\u0447\u0442\u0438\u0442\u0435, \u0447\u0442\u043e \u043f\u043e \u043c\u0435\u0440\u0435 \u0440\u043e\u0441\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u043a\u043e\u0434 \u2014 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u043d\u0430\u0446\u0435\u0435\u0439 (\u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0432\u043d\u0430\u0447\u0430\u043b\u0435), \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043b\u0438\u0448\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043e\u043f\u044b\u0442\u0430.<\/p>\n<p>  <b>5. \u0420\u0435\u0441\u0443\u0440\u0441\u044b<\/b><\/p>\n<p>  \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u2014 <a href=\"https:\/\/github.com\/RostislavDugin\/clean-architecture-react-typescript\" rel=\"nofollow\">github.com\/RostislavDugin\/clean-architecture-react-typescript<\/a> <\/p>\n<p>  UML \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u2014 <a href=\"https:\/\/github.com\/RostislavDugin\/clean-architecture-react-typescript\/tree\/master\/information\" rel=\"nofollow\">github.com\/RostislavDugin\/clean-architecture-react-typescript\/tree\/master\/information<\/a><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/499078\/\"> https:\/\/habr.com\/ru\/post\/499078\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/499078\/\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/q7\/ls\/cw\/q7lscw7mpm4ex_ivtew-qlanrkw.jpeg\"><\/p>\n<p>  \u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c, \u0443\u0432\u0430\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0438. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u0431 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0432 \u0432\u0435\u0431-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435. \u0414\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u0438 \u043c\u043e\u0438 \u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u044e <a href=\"https:\/\/blog.cleancoder.com\/uncle-bob\/2012\/08\/13\/the-clean-architecture.html\" rel=\"nofollow\">The Clean Architecture<\/a> \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 Frontend \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0432\u0437\u044f\u043b \u0435\u0435 \u043d\u0430 \u0432\u043e\u043e\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043d\u0430 TypeScript, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043e\u0431\u0449\u0435\u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u0432 \u043c\u0438\u0440\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430 React (\u0430 \u043f\u0440\u0438\u0448\u0435\u043b \u044f \u0438\u0437 Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0433\u0434\u0435 \u0434\u0430\u0432\u043d\u044b\u043c-\u0434\u0430\u0432\u043d\u043e, \u0435\u0449\u0435 \u0434\u043e Kotlin, \u043d\u0430\u0434\u0435\u043b\u0430\u043b\u0430 \u0448\u0443\u043c\u0438\u0445\u0438 <a href=\"https:\/\/fernandocejas.com\/2014\/09\/03\/architecting-android-the-clean-way\/\" rel=\"nofollow\">\u0441\u0442\u0430\u0442\u044c\u044f \u043e\u0442 Fernando Cejas<\/a>, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0438\u043d\u043e\u0433\u0434\u0430 \u0441\u0441\u044b\u043b\u0430\u044e\u0441\u044c).<\/p>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u043e \u043d\u0430\u0448\u0435\u043c \u043e\u043f\u044b\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f The Clean Architecture \u0432 React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c TypeScript. \u0417\u0430\u0447\u0435\u043c \u044f \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u044e? \u2014 \u0418\u043d\u043e\u0433\u0434\u0430 \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0437\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0438 \u043e\u0431\u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0435\u0449\u0435 \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 \u0442\u0430\u043a\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u0441 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u043c\u0438 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u044f \u0441\u043c\u043e\u0433\u0443 \u0441\u0441\u044b\u043b\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-302512","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/302512","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=302512"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/302512\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=302512"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=302512"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=302512"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}