{"id":465408,"date":"2025-07-01T15:10:51","date_gmt":"2025-07-01T15:10:51","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=465408"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=465408","title":{"rendered":"<span>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Android. C\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 State Machine<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/209\/0b5\/aed\/2090b5aedf4c3958777ac3b7d1fa9559.jpg\" width=\"3120\" height=\"1760\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/209\/0b5\/aed\/2090b5aedf4c3958777ac3b7d1fa9559.jpg 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/209\/0b5\/aed\/2090b5aedf4c3958777ac3b7d1fa9559.jpg 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u041e \u0447\u0451\u043c \u0441\u0442\u0430\u0442\u044c\u044f<\/h2>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/companies\/dododev\/articles\/917222\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438<\/a> \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u043e \u0441\u0432\u043e\u0451\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0435 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e\u0439 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u044b. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432\u044b \u0443\u0437\u043d\u0430\u0435\u0442\u0435 \u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u0445. \u041c\u044b:<\/p>\n<ul>\n<li>\n<p>\u0443\u0437\u043d\u0430\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0435 <em>State<\/em> <em>Machine<\/em> \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043a\u043e\u043f\u0430\u0435\u043c\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 <em>Kotlin<\/em> <em>Arrow<\/em>;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 <em>Null<\/em>, \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0447\u043d\u0451\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c <em>Data<\/em> \u0438 <em>Domain<\/em> \u0441\u043b\u043e\u0438 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f)<\/h2>\n<p>\u0423\u0432\u0435\u0440\u0435\u043d, \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043b\u044b\u0448\u0430\u043b\u0438: \u00ab\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 <em>var<\/em> \u0442\u0430\u043c, \u0433\u0434\u0435 \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e\u00bb. \u041d\u043e \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043d\u0438\u043a\u0442\u043e \u0442\u0430\u043a \u0438 \u043d\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u043b.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0434\u0430\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442 \u0432 \u0442\u0440\u0435\u043d\u0430\u0436\u0451\u0440\u043d\u044b\u0439 \u0437\u0430\u043b. \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    var start: LocalDateTime,    var end: LocalDateTime ) {    fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    } }<\/code><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043d\u043e \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0442\u0430\u043a. \u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0431\u0440\u043e\u0441\u043e\u043a \u043a\u043b\u0430\u0441\u0441\u0430 <code>SubscribtionCard<\/code>. \u0421\u043b\u0435\u0434\u0443\u044f \u0441\u0442\u0438\u043b\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c\u0443 \u0432 \u0442\u0438\u043f\u0435 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0434\u0432\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c\u0438 \u0433\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438 \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"kotlin\">val card = SubscriptionCard(    serialNumber = UUID.randomUUID().toString(),    validityDataRange = ValidityDataRange(        start = LocalDateTime.parse(\"2024-10-01T10:15:30\"),        end = LocalDateTime.parse(\"2024-11-01T10:15:30\")    ) ) val date = LocalDateTime.parse(\"2024-10-05T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/ true<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0438\u043f\u0430 <code>Card<\/code>. \u0414\u0430\u0442\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0435\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u2014 1 \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2024 \u0433\u043e\u0434\u0430, \u0430 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u2014 1 \u043d\u043e\u044f\u0431\u0440\u044f 2024 \u0433\u043e\u0434\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u0430 \u043b\u0438 \u043a\u0430\u0440\u0442\u0430 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0434\u0430\u0442\u0443.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0432 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043a\u0430\u0440\u0442\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u0430. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 true. \u041d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0438\u043f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e.<\/p>\n<pre><code class=\"kotlin\">val date = LocalDateTime.parse(\"2024-10-10T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/true card.validityDataRange.end = LocalDateTime.parse(\"2024-10-06T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/false<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0432\u0435\u043d <em>false<\/em>. \u0412\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043d\u0430\u0434\u043e. \u041d\u043e \u0442\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c \u043e\u0431\u044a\u0451\u043c \u043a\u043e\u0434\u0430. \u0418\u043c\u0435\u044f \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441 \u043e\u0434\u043d\u0438\u043c\u0438 \u0438 \u0442\u0435\u043c\u0438 \u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0438\u0441\u043f\u043e\u0440\u0442\u0438\u0442\u044c \u0438\u0445 \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<p>\u041e\u0434\u043d\u0430 \u0447\u0430\u0441\u0442\u044c \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0437\u043d\u0430\u0442\u044c \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043d\u0435\u0441\u043b\u0430 \u0434\u0440\u0443\u0433\u0430\u044f \u0435\u0433\u043e \u0447\u0430\u0441\u0442\u044c \u0432 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043e\u0431\u044a\u0435\u043a\u0442. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430. \u041d\u0430\u0448 \u043f\u0440\u0438\u043c\u0435\u0440 \u2014 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u043c\u0443 \u043e\u0447\u0435\u043d\u044c \u0432\u044b\u0441\u043e\u043a\u0430. \u041e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u0441\u0442\u0430\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u0422\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0439 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0451\u0442 \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0442\u0435\u0440\u044f\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430. \u0418 \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u2014 \u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0444\u043b\u0430\u0433 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430 \u0441 \u043e\u043f\u044b\u0442\u043e\u043c. \u041e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0418 \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043a\u043e\u0434\u0430 \u0432\u044b\u0448\u0435. \u041e\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0436\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u0442\u044b \u043c\u0435\u043d\u044c\u0448\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e, \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0444\u0438\u043a\u0441\u0438\u0442\u044c \u0438 \u0431\u0435\u0437 \u0424\u041f, \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0432 \u0442\u0438\u043f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u044b\u043c, \u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0431\u043e\u043b\u0435\u0435 \u0431\u043b\u0438\u0437\u043a\u0438\u0435 \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u0435\u0439\u0441\u044b.<\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043a\u043e\u0434\u043e\u043c \u0432\u044b\u0448\u0435:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    start: LocalDateTime,    end: LocalDateTime ) {    init {        require(!start.isAfter(end)) { \"End should be ahead of Start or equal\" }    }      var start: LocalDateTime = start        private set    var end: LocalDateTime = end        private set      fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    } }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443, \u2014 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0441\u0434\u0435\u043b\u0430\u0432 \u0441\u0435\u0442\u0442\u0435\u0440\u044b \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c\u0438. \u042d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u044f\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c.<\/p>\n<p>\u041d\u043e \u043a\u0430\u043a \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430? \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0451\u043c <code>isInEffect<\/code>.<\/p>\n<pre><code class=\"kotlin\">val date = LocalDateTime.parse(\"2024-10-10T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/true card.validityDataRange.end = LocalDateTime.parse(\"2024-10-06T10:15:30\") \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 val newDate = LocalDateTime.parse(\"2024-10-06T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/false<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e \u0441\u0442\u0430\u043b \u043b\u0443\u0447\u0448\u0435. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d. \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u0440\u0442\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0430\u043b\u0430 \u043d\u0438\u0436\u0435. \u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043e\u0434 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438 \u0438\u0445 \u00ab\u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438\u00bb.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0441\u0442\u0430\u043b\u0430\u0441\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043a\u0440\u044b\u0442\u0430 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u043c \u0442\u0438\u043f\u0435: \u0438\u0437\u043d\u0443\u0442\u0440\u0438 \u0442\u0438\u043f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439. \u041a\u0430\u043a \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e?<\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    start: LocalDateTime,    end: LocalDateTime ) {    init {        require(!start.isAfter(end)) { \"End should be ahead of Start or equal\" }    }      var start: LocalDateTime = start        private set    var end: LocalDateTime = end        private set      fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    }      fun extend(days: Long) {        end = end.plusDays(days)    } }<\/code><\/pre>\n<p>\u0418\u0437 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043d\u0430\u0448 \u0442\u0438\u043f \u0432\u0441\u0451 \u0435\u0449\u0451 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u0437\u043d\u0443\u0442\u0440\u0438. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u044e\u0431\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u0432\u044b\u043a\u0430\u0442\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0438 \u043d\u0430\u0448 \u0442\u0438\u043f \u043f\u043e\u0442\u0435\u0440\u044f\u043b \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0432 \u0441\u043f\u043e\u0440\u0442\u0437\u0430\u043b. \u041c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0434\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u0430 \u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0437\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u043b\u0430\u0442\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0434\u043b\u0438\u0442\u044c \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<pre><code class=\"kotlin\">fun main() {     val cert1 = SubscriptionCard( \"Certificate A\", ValidityDataRange(         LocalDateTime.of(2024, 10, 1, 0, 0),         LocalDateTime.of(2024, 11, 1, 0, 0)    )     )      val cert2 = SubscriptionCard( \"Certificate B\", ValidityDataRange(         LocalDateTime.of(2024, 11, 1, 0, 0),         LocalDateTime.of(2024, 12, 1, 0, 0)    )     )      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0441 \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438     val catalog = listOf(cert1, cert2)      println(\"Original Validity Ranges:\")     catalog.forEach { println(\"${it.serialNumber}: ${it.validityDateRange.start} to ${it.validityDateRange.end}\") }     \/*       \u0412\u044b\u0432\u0435\u0434\u0435\u0442 Original Validity Ranges:      Certificate A: 2024-10-01T00:00 to 2024-11-01T00:00      Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00      *\/      \/\/ \u041f\u0440\u043e\u0434\u043b\u0435\u0432\u0430\u0435\u043c \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430     cert1.validityDateRange.extend(5)        println(\"\\nUpdated Validity Ranges:\")     catalog.forEach { println(\"${it.serialNumber}: ${it.validityDateRange.start} to ${it.validityDateRange.end}\") }     \/*       \u0412\u044b\u0432\u0435\u0434\u0435\u0442 Updated Validity Ranges:      Certificate A: 2024-10-01T00:00 to 2024-11-06T00:00      Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00      *\/  }<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430 \u043a\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e, \u043d\u043e \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u043c\u044b \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043e\u0434\u0438\u043d \u0434\u0435\u043d\u044c? \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>ValidityDataRange<\/code> \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0432\u0441\u0435\u043c \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430\u043c. \u041d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0438 \u0442\u0430 \u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 extend \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0451\u043c\u0441\u044f \u0441 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0440\u043e\u043a\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0438 \u0441\u0440\u0430\u0437\u0443:<\/p>\n<pre><code class=\"kotlin\">val monthlyRange = ValidityDataRange(   LocalDateTime.of(2024, 11, 1, 0, 0),   LocalDateTime.of(2024, 12, 1, 0, 0) ) val cert1 = SubscriptionCard(\"Certificate A\", monthlyRange)  val cert2 = SubscriptionCard(\"Certificate B\", monthlyRange)  \/\/ \u041f\u0440\u043e\u0434\u043b\u0435\u0432\u0430\u0435\u043c \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430 cert1.validity.extend(5)  Original Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-01T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00  Updated Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-06T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-06T00:00<\/code><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c&#8230; \u041c\u044b \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u0438\u0448\u043b\u0438 \u043a \u0442\u043e\u0439 \u0436\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0439 \u0441 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u044c\u044e \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u0435\u043c \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c\u0441\u044f \u0438 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438. \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443?<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0432 <em>Kotlin<\/em> \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041e\u043d \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>start<\/code> \u0438 <code>end<\/code> \u043a\u0430\u043a <em>readOnly<\/em>:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    val start: LocalDateTime,    val end: LocalDateTime ) {    init {        require(!start.isAfter(end)) { \"End should be ahead of Start or equal\" }    }     fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    }      fun extend(days: Int): ValidityDataRange = ValidityDataRange(        start = start,        end = end.plusDays(days.toLong())    ) }  Original Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-01T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00  Updated Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-01T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>data class<\/em>. \u041e\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>copy()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 <code>val<\/code> \u043f\u043e\u043b\u044f\u043c\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0421\u0442\u043e\u0438\u0442 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c &#8212; \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432\u044b \u043d\u0435 \u0440\u0435\u0448\u0438\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 <em>data class<\/em> <code>var<\/code> \u043f\u043e\u043b\u044f \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u0430\u043c\u043e\u0433\u043e <br \/><em>data class<\/em> \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c <code>var<\/code>.<\/p>\n<pre><code class=\"kotlin\">data class ValidityDataRange(    val start: LocalDateTime,    val end: LocalDateTime ) {    fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    }      fun extend(days: Int): ValidityDataRange = this.copy(end = end.plusDays(days.toLong())) }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u0431\u0443\u0434\u0443\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438. \u0422\u0430\u043a \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438 \u0442\u0438\u043f\u0430. \u0415\u0441\u043b\u0438 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043f\u0440\u0438\u0434\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442, \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0438\u043f \u043e\u043d \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0438 \u0437\u0430\u0434\u0443\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>\u00ab\u0410 \u043a\u0430\u043a \u044d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e? \u2014 \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u0435 \u0432\u044b \u2014 \u041c\u044b \u0438 \u0431\u0435\u0437 \u0442\u0432\u043e\u0435\u0439 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0441\u0432\u043e\u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 <code>val<\/code> \u0438 <code>data class<\/code>.\u00bb<\/p>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441: \u043a\u0430\u043a \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u0443\u044e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u044d\u043a\u0440\u0430\u043d\u044b, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0434\u0438\u0430\u043b\u043e\u0433\u0438 \u0438 \u043f\u0440\u043e\u0434\u043b\u0435\u0432\u0430\u0442\u044c \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u044b \u0432 \u0441\u043f\u043e\u0440\u0442\u0437\u0430\u043b\u0435?<\/p>\n<p>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0442\u0430\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0414\u0430, \u0443 \u043d\u0435\u0433\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432, \u043d\u043e \u043e\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0438 \u0431\u043e\u043b\u0435\u0435 \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0431\u044b\u043b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0438 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0431\u0430\u043b\u0430\u043d\u0441 \u043c\u0435\u0436\u0434\u0443 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<h2>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0438\u043f\u044b-\u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a\u0438.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u044d\u0442\u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u0445, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u041b\u0438\u043d\u0437\u044b.<\/p>\n<p>\u041e\u043d\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439:<\/p>\n<ul>\n<li>\n<p>\u0433\u0435\u0442\u0442\u0435\u0440 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0435\u0442\u0442\u0435\u0440 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441 \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041b\u0438\u043d\u0437\u044b \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u043c\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043b\u0438\u043d\u0437\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043d\u0438\u0445 \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0431\u043e\u043b\u0435\u0435 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u043c \u0443\u0440\u043e\u0432\u043d\u044f\u043c.<\/p>\n<p>\u041b\u0438\u043d\u0437\u044b \u043f\u043e\u043b\u0435\u0437\u043d\u044b \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u043a\u043e\u043f\u0438\u0438. \u041b\u0438\u043d\u0437\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"kotlin\">data class User(val name: String, val address: Address) data class Address(val city: String, val street: String)  \/\/ \u041b\u0438\u043d\u0437\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0430\u0434\u0440\u0435\u0441\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f class Lens&lt;S, A&gt;(val get: (S) -&gt; A, val set: (S, A) -&gt; S)  \/\/ \u041b\u0438\u043d\u0437\u0430 \u0434\u043b\u044f User val userAddressLens = Lens&lt;User, Address&gt;(     get = { it.address },     set = { user, address -&gt; user.copy(address = address) } )  \/\/ \u041b\u0438\u043d\u0437\u0430 \u0434\u043b\u044f Address val addressStreetLens = Lens&lt;Address, String&gt;(     get = { it.street },     set = { address, street -&gt; address.copy(street = street) } )  \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0443\u043b\u0438\u0446\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f fun User.changeStreet(newStreet: String): User {     val address = userAddressLens.get(this)     val newAddress = addressStreetLens.set(address, newStreet)     return userAddressLens.set(this, newAddress) }  fun main() {     val user = User(name = \"Ivan\", address = Address(city = \"Moscow\", street = \"Lenina\"))     val updatedUser = user.changeStreet(\"Mira\")          println(updatedUser) \/\/ User(name=Ivan, address=Address(city=Moscow, street=Mira)) }<\/code><\/pre>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/15f\/f84\/5fe\/15ff845fe596def748818185006f5c16.png\" width=\"1152\" height=\"1046\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/15f\/f84\/5fe\/15ff845fe596def748818185006f5c16.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/15f\/f84\/5fe\/15ff845fe596def748818185006f5c16.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043b\u0438\u043d\u0437\u044b \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u2014 \u043d\u0435 \u043f\u0430\u043d\u0430\u0446\u0435\u044f. \u0412 <em>Kotlin<\/em> \u0443 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a: \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u0430\u043c\u044f\u0442\u0438, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 set \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043d\u043e\u0432\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432. \u042d\u0442\u043e \u0446\u0435\u043d\u0430 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438.<\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 <em>Kotlin<\/em> \u0438 <em>Android<\/em> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c \u0437\u0430\u043c\u0435\u0440\u044b \u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 \u043f\u043e\u043b\u0435\u0439 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0447\u0430\u0441\u0442\u043e, \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u043e\u0431 \u043e\u0442\u043a\u0430\u0437\u0435 \u043e\u0442 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0443\u043b\u0430 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<p>\u0422\u0430\u043a \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435. \u041f\u0430\u043c\u044f\u0442\u044c \u0431\u0443\u0434\u0435\u0442\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0430 \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u0443\u0441\u043e\u0440\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0436\u0435.<\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e sealed class \u0432 <em>Kotlin<\/em> \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0444\u043e\u0440\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u0437\u043c\u0430.<\/p>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0438\u043c \u0438 \u0438\u0445 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e. \u041a\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u044b\u043c \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0434\u043b\u044f \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d35\/dac\/945\/d35dac9453cc139122e0f338fcde728b.png\" width=\"790\" height=\"526\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d35\/dac\/945\/d35dac9453cc139122e0f338fcde728b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d35\/dac\/945\/d35dac9453cc139122e0f338fcde728b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u0440\u0438\u0437\u043c\u0430 \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u041b\u0438\u043d\u0437\u044b, \u0437\u0430 \u043e\u0434\u043d\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u2014 \u0433\u0435\u0442\u0442\u0435\u0440-\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u0437\u043c\u044b \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u043c\u0443 \u0442\u0438\u043f\u0443.<\/p>\n<pre><code class=\"kotlin\">sealed class Result&lt;out T&gt; {     data class Success&lt;out T&gt;(val value: T) : Result&lt;T&gt;()     data class Error(val message: String) : Result&lt;Nothing&gt;() } \/\/ \u041f\u0440\u0438\u0437\u043c\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Result class Prism&lt;S, A&gt;(val get: (S) -&gt; A?, val set: (S, A) -&gt; S)  \/\/ \u041f\u0440\u0438\u0437\u043c\u0430 \u0434\u043b\u044f Result val successPrism = Prism&lt;Result&lt;*&gt;, Any&gt;(     get = { result -&gt; (result as? Result.Success&lt;*&gt;)?.value },     set = { _, value -&gt; Result.Success(value) } )  val errorPrism = Prism&lt;Result&lt;*&gt;, String&gt;(     get = { result -&gt; (result as? Result.Error)?.message },     set = { _, message -&gt; Result.Error(message) } )  \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 fun handleResult(result: Result&lt;Int&gt;): String {     return when (result) {         is Result.Success -&gt; \"Success with value: ${successPrism.get(result)}\"         is Result.Error -&gt; \"Error: ${errorPrism.get(result)}\"     } }  fun main() {     val successResult = Result.Success(42)     val errorResult = Result.Error(\"Something went wrong\")      println(handleResult(successResult)) \/\/ Success with value: 42     println(handleResult(errorResult))    \/\/ Error: Something went wrong }<\/code><\/pre>\n<p>\u041c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0437\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>Result<\/code>. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u0438\u0431\u043e <code>Success<\/code>, \u043b\u0438\u0431\u043e <code>Error<\/code>.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0440\u0438\u0437\u043c\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0432\u0443\u043c\u044f \u0432\u0438\u0434\u0430\u043c\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432: <code>Success<\/code> \u0438 <code>Error<\/code>. \u041a\u0430\u0436\u0434\u0430\u044f \u043f\u0440\u0438\u0437\u043c\u0430 \u0438\u043c\u0435\u0435\u0442 \u0433\u0435\u0442\u0442\u0435\u0440 \u0438 \u0441\u0435\u0442\u0442\u0435\u0440 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c.<\/p>\n<p>\u0417\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>handleResult<\/code>. \u041e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0440\u0438\u0437\u043c\u044b \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043d\u0451\u043c.<\/p>\n<h2>\u041d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u0438 \u0435\u0451 \u0440\u043e\u043b\u044c \u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438<\/h2>\n<p>\u041d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u2014 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0432\u044b\u0448\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u0438 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c. \u042d\u0442\u0430 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432\u044b\u0433\u043e\u0434\u043d\u0430 \u043f\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c:<\/p>\n<ul>\n<li>\n<p>\u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430. \u042d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0430\u043d\u0430\u043b\u0438\u0437 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0432 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0431\u0435\u0437 \u0440\u0438\u0441\u043a\u0430 \u043f\u043e\u0432\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0441\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u041a\u0430\u0436\u0434\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u043a\u0430\u043a \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u042d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0441\u0442\u043e\u0440\u0438\u0435\u0439 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0438\u043f \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>Car<\/code> \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"kotlin\">data class Car(val color: Int, val model: Model) data class Model(val engine: Engine,val name: String, val country: String) data class Engine(val type: EngineType, val numberValves: Int) enum class EngineType {    INJECTOR,    CARBURETOR }   fun Car.changeEngineType(): Car =    this.copy(        model = model.copy(            engine = model.engine.copy(                type = when(model.engine.type) {                    EngineType.INJECTOR -&gt; EngineType.CARBURETOR                    EngineType.CARBURETOR -&gt; EngineType.INJECTOR                }            )        )    )<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u043d\u043e \u043e\u043d \u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0438 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043c\u043d\u043e\u0433\u043e\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438. \u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0438 \u043d\u0443\u0436\u043d\u044b \u043b\u0438\u043d\u0437\u044b \u0438 \u043f\u0440\u0438\u0437\u043c\u044b. \u041e\u043d\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0431\u043e\u043b\u0435\u0435 \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0431\u0435\u0437 \u0447\u0440\u0435\u0437\u043c\u0435\u0440\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"kotlin\">fun Car.changeEngineType(): Car {     \/\/ Get the current engine type using the lens     val currentEngineType = carLens.get(this).let(modelLens.get).let(engineLens.get)      \/\/ Determine the new engine type     val newEngineType = when (currentEngineType) {         EngineType.INJECTOR -&gt; EngineType.CARBURETOR         EngineType.CARBURETOR -&gt; EngineType.INJECTOR     }      \/\/ Use lenses to set the new engine type     return carLens.set(this, modelLens.set(carLens.get(this), engineLens.set(modelLens.get(carLens.get(this)), newEngineType))) }<\/code><\/pre>\n<p>\u042f \u043d\u0435 \u0432\u0438\u0436\u0443 \u0441\u043c\u044b\u0441\u043b\u0430 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434. \u0412\u0441\u0451, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432\u044b\u0448\u0435, \u0434\u0430 \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u0432\u0441\u0451 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 <em>Kotlin<\/em>, \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0432 <em>Open Source<\/em> \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, <a href=\"https:\/\/arrow-kt.io\/\" rel=\"noopener noreferrer nofollow\">Arrow<\/a> \u2014 \u0432\u0430\u0448 \u0432\u044b\u0445\u043e\u0434. \u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0438\u0451\u043c\u043e\u0432 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.\u00a0<\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438. \u041d\u043e \u0432 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445, \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u0422\u0443\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 <em>State Machine<\/em>.<\/p>\n<h2>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 State Machine<\/h2>\n<p>\u0418\u0434\u0435\u044f <em>State Machine<\/em> \u0438\u043b\u0438 \u041a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0435 \u043d\u043e\u0432\u0430.\u00a0 <em>Finite-state machine (FSM)<\/em> \u2014 \u044d\u0442\u043e \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f, \u043c\u043e\u0434\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. <\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/24f\/de6\/c7f\/24fde6c7fc7485c35d63d4db685a7c82.jpeg\" width=\"600\" height=\"551\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/24f\/de6\/c7f\/24fde6c7fc7485c35d63d4db685a7c82.jpeg 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/24f\/de6\/c7f\/24fde6c7fc7485c35d63d4db685a7c82.jpeg 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c. \u041e\u043d \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0438\u0445 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0432\u0432\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. <em>FSM<\/em> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u0438\u043d\u043f\u0443\u0442\u0430\u043c\u0438, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0438\u043c\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e <em>State Machine<\/em>, \u0430 \u0432\u0441\u0435\u043c \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u043c \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044f \u0431\u044b \u0441\u043e\u0432\u0435\u0442\u043e\u0432\u0430\u043b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043c\u0438\u0440 \u0434\u0438\u0441\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0438. \u042f \u0436\u0435 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u0441\u0443\u0442\u044c <em>State Machine<\/em> \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0435\u0442-\u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/337\/0a6\/42b\/3370a642bb6524a7e4d78d9336286889.png\" width=\"2546\" height=\"900\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/337\/0a6\/42b\/3370a642bb6524a7e4d78d9336286889.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/337\/0a6\/42b\/3370a642bb6524a7e4d78d9336286889.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u0435\u0434\u0438\u0430\u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438. \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<ul>\n<li>\n<p><code>Idle<\/code> \u2014 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435. \u041c\u0435\u0434\u0438\u0430\u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439;<\/p>\n<\/li>\n<li>\n<p><code>loading<\/code> \u2014 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430. \u041c\u0435\u0434\u0438\u0430\u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b\u044b;<\/p>\n<\/li>\n<li>\n<p><code>playing<\/code> \u2014 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435. \u041c\u0435\u0434\u0438\u0430\u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b;<\/p>\n<\/li>\n<li>\n<p><code>paused<\/code> \u2014 \u043f\u0430\u0443\u0437\u0430. \u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p><code>stopped<\/code> \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430. \u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p><code>error<\/code> \u2014 \u043e\u0448\u0438\u0431\u043a\u0430. \u041f\u0440\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><code>onPlayClick<\/code> \u2014 \u0437\u0430\u043f\u0443\u0441\u043a \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><code>onPauseClick<\/code> \u2014 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><code>onStop<\/code> \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><code>onSeekForwardClick<\/code> \u2014 \u043f\u0435\u0440\u0435\u043c\u043e\u0442\u043a\u0430 \u0432\u043f\u0435\u0440\u0451\u0434;<\/p>\n<\/li>\n<li>\n<p><code>onSeekBackwardClick<\/code> \u2014 \u043f\u0435\u0440\u0435\u043c\u043e\u0442\u043a\u0430 \u043d\u0430\u0437\u0430\u0434;<\/p>\n<\/li>\n<li>\n<p><code>onAddToFavoritesClick<\/code> \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435;<\/p>\n<\/li>\n<li>\n<p><code>onDownloadClick<\/code> \u2014 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u043c\u0435\u0434\u0438\u0430\u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3d8\/1de\/3c5\/3d81de3c51d016bf511caeca7793d7be.png\" width=\"914\" height=\"920\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/3d8\/1de\/3c5\/3d81de3c51d016bf511caeca7793d7be.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3d8\/1de\/3c5\/3d81de3c51d016bf511caeca7793d7be.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b:<\/p>\n<ul>\n<li>\n<p><code>Idle<\/code> \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>Playing<\/code> \u0441\u0440\u0430\u0437\u0443 \u2014 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b (\u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 <code>Loading<\/code>);<\/p>\n<\/li>\n<li>\n<p><code>Loading<\/code> \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>Paused<\/code> \u0438\u043b\u0438 <code>Stopped<\/code>; \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 Playing \u0438\u043b\u0438 <code>Error<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>Playing<\/code> \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>Loading<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0445\u043e\u0447\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b, \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p><code>Paused<\/code> \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>Loading<\/code>. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0435\u0433\u043e;<\/p>\n<\/li>\n<li>\n<p><code>Stopped<\/code> \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>Paused<\/code>. \u041d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b;<\/p>\n<\/li>\n<li>\n<p><code>Error<\/code> \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 <code>Playing<\/code> \u0438\u043b\u0438 <code>Paused<\/code>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443 \u0438, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043c\u0438\u0440\u0435 \u043c\u044b \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0431\u044b \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u043b\u0438 \u0431\u044b, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0430. \u041d\u043e \u043c\u044b \u0436\u0438\u0432\u0451\u043c \u043d\u0435 \u0432 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043c\u0438\u0440\u0435.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0437\u0430\u043a\u0430\u0437\u044b \u0435\u0434\u044b. \u0412 \u0442\u0435\u043e\u0440\u0438\u0438 \u043d\u0430\u043c \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u0431\u044b \u0442\u0440\u0451\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439: \u00ab\u0432\u044b\u0431\u043e\u0440 \u0440\u0435\u0441\u0442\u043e\u0440\u0430\u043d\u0430\u00bb, \u00ab\u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u043b\u044e\u0434 \u0432 \u043a\u043e\u0440\u0437\u0438\u043d\u0443\u00bb \u0438 \u00ab\u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043a\u0430\u0437\u0430\u00bb. \u041d\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0440\u0435\u0441\u0442\u043e\u0440\u0430\u043d \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0435\u043d\u044e, \u0430 \u0442\u043e \u0438 \u0432\u043e\u0432\u0441\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0437\u0430. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0434\u043e\u0432\u043e\u043b\u0435\u043d. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438.<\/p>\n<p>\u0412\u0430\u0436\u043d\u043e \u0442\u0449\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c <em>State Machine<\/em>, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0432\u0441\u0435 \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u044b\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438. \u0422\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u0443\u044e \u0438 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f FSM \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435<\/h2>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0442\u043e, \u043e \u0447\u0451\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u0432\u044b\u0448\u0435:<\/p>\n<pre><code class=\"kotlin\">\/\/ \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044f sealed class MediaPlayerState {     data object Idle : MediaPlayerState()     data object Loading : MediaPlayerState()     data object Playing : MediaPlayerState()     data object Paused : MediaPlayerState()     data object Stopped : MediaPlayerState()     data object Error : MediaPlayerState() }  \/\/ \u0421\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 sealed class MediaPlayerIntent {     data object onPlayClick : MediaPlayerIntent()     data object onPauseClick : MediaPlayerIntent()     data object onStop : MediaPlayerIntent()     data object onSeekForwardClick : MediaPlayerIntent()     data object onSeekBackwardClick : MediaPlayerIntent()     data object onAddToFavoritesClick : MediaPlayerIntent()     data object onDownloadClick : MediaPlayerIntent() }<\/code><\/pre>\n<pre><code class=\"kotlin\">class MediaPlayerViewModel : ViewModel() {     private val _state = MutableStateFlow&lt;MediaPlayerState&gt;(MediaPlayerState.Idle)     val state: StateFlow&lt;MediaPlayerState&gt; = _state.asStateFlow()      init {         loadAudio()     }      private fun loadAudio() {         _state.value = MediaPlayerState.Playing     }      fun processIntent(intent: MediaPlayerIntent) {         when (intent) {             is MediaPlayerIntent.onPlayClick -&gt; {                 when (_state.value) {                     is MediaPlayerState.Loading -&gt; { \/\/ \u041f\u043e\u043a\u0430\u0437 loader \u0438\u043b\u0438 shimer animation     }                     is MediaPlayerState.Idle, is MediaPlayerState.Paused -&gt; {                         _state.value = MediaPlayerState.Playing                     }                     is MediaPlayerState.Playing -&gt; {}                     is MediaPlayerState.Stopped -&gt; {}                     is MediaPlayerState.Error -&gt; {}                 }             }             is MediaPlayerIntent.onPauseClick -&gt; {                 if (_state.value is MediaPlayerState.Playing) {                     _state.value = MediaPlayerState.Paused                 }             }             is MediaPlayerIntent.onStop -&gt; {                 if (_state.value is MediaPlayerState.Playing || _state.value is MediaPlayerState.Paused) {                     _state.value = MediaPlayerState.Stopped                 }             }             is MediaPlayerIntent.onSeekForwardClick -&gt; {                 \/\/ \u041b\u043e\u0433\u0438\u043a\u0430 \u043f\u0435\u0440\u0435\u043c\u043e\u0442\u043a\u0438 \u0432\u043f\u0435\u0440\u0451\u0434 \u043d\u0430 15 \u0441\u0435\u043a\u0443\u043d\u0434             }             is MediaPlayerIntent.onSeekBackwardClick -&gt; {                 \/\/ \u041b\u043e\u0433\u0438\u043a\u0430 \u043f\u0435\u0440\u0435\u043c\u043e\u0442\u043a\u0438 \u043d\u0430\u0437\u0430\u0434 \u043d\u0430 15 \u0441\u0435\u043a\u0443\u043d\u0434             }             is MediaPlayerIntent.onAddToFavoritesClick -&gt; {                 \/\/ \u041b\u043e\u0433\u0438\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043d\u043e\u0435             }             is MediaPlayerIntent.onDownloadClick -&gt; {                 \/\/ \u041b\u043e\u0433\u0438\u043a\u0430 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0430\u0443\u0434\u0438\u043e             }         }     } }<\/code><\/pre>\n<p>\u0412\u044b\u0448\u0435 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e <em>State Machine<\/em> \u2014 \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u043d\u0430\u043c\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 <em>State<\/em> \u0438 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 <em>Intent<\/em>. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043e\u0442\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u2014 \u0447\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u0435\u0440\u0436\u0438\u043c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435, \u0442\u0435\u043c \u043f\u0440\u043e\u0449\u0435 \u0441 \u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<h2>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 Null, \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a<\/h2>\n<p>\u041a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f <em>State<\/em> <em>Machine<\/em> \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u0442\u0435\u0441\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u043c\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0431\u044b\u0442\u044c. \u0422\u0430\u043a\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435\u043c <em>Nullable<\/em>-\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <em>null<\/em> \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0442\u043e \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0451\u043c\u0441\u044f \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><code>NullPointerException<\/code> \u2014 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a. \u041e\u043d\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u0434 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043c\u0435\u0442\u043e\u0434\u0443 \u0438\u043b\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0440\u0430\u0432\u043d\u043e\u0433\u043e <em>null<\/em>, \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0441\u0431\u043e\u044f\u043c \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u044f\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. \u041a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c <em>null<\/em>, \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u0431\u044f \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e, \u0437\u0430\u0442\u0440\u0443\u0434\u043d\u044f\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u044f\u0432\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <em>null<\/em> \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043f\u0440\u0438\u0432\u043e\u0434\u044f \u043a \u043f\u0443\u0442\u0430\u043d\u0438\u0446\u0430\u043c \u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u043c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 <em>Java<\/em>, \u0432\u044b, \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430, \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u0441 <code>NullPointerException<\/code>. \u041e\u043d \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 null, \u043d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0442\u0443 \u0438\u043b\u0438 \u0438\u043d\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u0432\u0430\u0448\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u043c \u043a\u043e\u0434\u0435. <em>Null<\/em> \u0437\u043b\u043e\u0443\u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044e\u0442, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. <em>Kotlin<\/em> \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u044f\u0441\u044c \u043e\u0442 \u043d\u0443\u043b\u0435\u0432\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u00ab?\u00bb.<\/p>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u043c\u0435\u0441\u0442\u043e <em>null<\/em> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e <code>Optional<\/code>. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0438 \u044f\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0430\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 Arrow \u043c\u043e\u0434\u0435\u043b\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043d\u0430\u043f\u0438\u0441\u0430\u0432 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"kotlin\">fun findElement(list: List&lt;Int&gt;, element: Int): Int? {     return if (element in list) {         element     } else {         null     } } fun main() {     val numbers = listOf(1, 2, 3, 4, 5)     val found = findElement(numbers, 3)     println(found) \/\/ Output: 3      val notFound = findElement(numbers, 6)     println(notFound) \/\/ Output: null     if (found != null) { println(\"\u041d\u0430\u0439\u0434\u0435\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442: $found\") }     else { println(\"\u042d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\") } }<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0432\u044b\u0448\u0435 \u043c\u044b \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e\u0433\u043e, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0434\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c <em>null<\/em>. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <em>Kotlin<\/em> <em>Null<\/em> <em>Safety<\/em> \u0438 \u0436\u0438\u0442\u044c \u0432 \u0441\u0447\u0430\u0441\u0442\u044c\u0435. \u041d\u043e \u043f\u0440\u0435\u0436\u0434\u0435 \u044f \u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b, \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>Arrow<\/em>.<\/p>\n<pre><code class=\"kotlin\">fun findElement(list: List&lt;Int&gt;, element: Int): Option&lt;Int&gt; {     return if (element in list) {         element.some()     } else {         none()     } }  fun main() {     val numbers = listOf(1, 2, 3, 4, 5)      val found = findElement(numbers, 3)     println(found) \/\/ Output: Some(3)      val notFound = findElement(numbers, 6)     println(notFound) \/\/ Output: None      found.fold(       { println(\"\u042d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\") }, \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043b\u0443\u0447\u0430\u044f None       { println(\"\u041d\u0430\u0439\u0434\u0435\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442: $it\") } \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043b\u0443\u0447\u0430\u044f Some     ) }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c? \u041f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u00ab\u0441\u043e\u043c\u00bb \u0438 \u00ab\u043d\u043e\u043d\u00bb.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ada\/289\/33d\/ada28933dc444d3b74371e31cc9c4fae.jpeg\" width=\"645\" height=\"431\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ada\/289\/33d\/ada28933dc444d3b74371e31cc9c4fae.jpeg 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ada\/289\/33d\/ada28933dc444d3b74371e31cc9c4fae.jpeg 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p><code>Option&lt;A&gt;<\/code> \u2014 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0434\u043b\u044f \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 A. \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 A \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, <code>Option&lt;A&gt;<\/code> \u2014 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>Some&lt;A&gt;<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 <code>A<\/code>. \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, <code>Option &lt;A&gt;<\/code> \u2014 \u043e\u0431\u044a\u0435\u043a\u0442 <code>None<\/code>. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441 \u0434\u0432\u0443\u043c\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438: \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435\u0442. \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 <code>Option<\/code> \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u0440\u0430\u0436\u0430\u0442\u044c \u043e\u0434\u043d\u043e \u0438\u0437 \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439. \u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>fold()<\/code>, \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u044f\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043e\u0431\u0430 \u044d\u0442\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0437\u0430 \u043d\u0430\u0441, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043b\u0438 \u043e\u043d\u0438. \u041f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u044b\u0439 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439.<\/p>\n<p>\u0421 \u0440\u0430\u0437\u043d\u0438\u0446\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 <code>Nullable<\/code> \u0438 <code>Optional<\/code> \u043f\u043e\u0434\u0445\u043e\u0434\u0430\u043c\u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c. \u0418\u0434\u0451\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u2014 <em>backend<\/em>-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c 3 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<ol>\n<li>\n<p>\u0418\u043c\u044f \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u043a\u0432\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u0440\u0430\u0441\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0442 0 \u0434\u043e 120 \u043b\u0435\u0442.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0440\u0435\u0448\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435:<\/p>\n<pre><code class=\"kotlin\">data class User(val name: String, val age: Int, val email: String)   fun String.isValidEmail(): Boolean {     val emailRegex = Regex(         \"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$\"     )     return emailRegex.matches(this) }   fun validateUser(user: User): String {     when {         !user.name.all { it.isLetter() } -&gt; throw IllegalArgumentException(\"\u041e\u0448\u0438\u0431\u043a\u0430: \u0438\u043c\u044f \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u043a\u0432\u044b\")         user.age &lt; 0 || user.age &gt; 120 -&gt; throw IllegalArgumentException(\"\u041e\u0448\u0438\u0431\u043a\u0430: \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442 0 \u0434\u043e 120\")         !user.email.isValidEmail() -&gt; throw IllegalArgumentException(\"\u041e\u0448\u0438\u0431\u043a\u0430: \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b\")     }     return \"\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d: ${user.name}\" }  fun main() {     val users = listOf(         User(\"Alice\", 30, \"alice@example.com\"),         User(\"Bob123\", 25, \"bob@example.com\"),         User(\"Charlie\", -5, \"charlie@example.com\"),         User(\"David\", 25, \"davidexample.com\")     )      users.forEach { user -&gt;         try {             val result = validateUser(user)             println(result) \/\/ \u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442         } catch (e: IllegalArgumentException) {             println(e.message) \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043a\u0438         }     } }<\/code><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0432\u0441\u0451 \u043e\u043a. \u0415\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u0447\u0438\u0442\u0430\u044e\u0442 <em>backend<\/em>-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438, \u043d\u0430\u043f\u0438\u0448\u0438\u0442\u0435, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u0442\u043e\u0442, \u0447\u0442\u043e \u043f\u0438\u0448\u0435\u0442\u0435 \u0432\u044b.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u0434 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u043c \u043e\u0431\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0430:<\/p>\n<pre><code class=\"kotlin\">sealed class RegistrationError {     object InvalidName : RegistrationError() {         override fun toString() = \"\u041e\u0448\u0438\u0431\u043a\u0430: \u0438\u043c\u044f \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u043a\u0432\u044b\"     }     object InvalidAge : RegistrationError() {         override fun toString() = \"\u041e\u0448\u0438\u0431\u043a\u0430: \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0442 0 \u0434\u043e 120\"     }     object InvalidEmail : RegistrationError() {         override fun toString() = \"\u041e\u0448\u0438\u0431\u043a\u0430: \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b\"     } }  data class User(val name: String, val age: Int, val email: String)  fun validateUser(user: User): Either&lt;RegistrationError, String&gt; {     return when {         !user.name.all { it.isLetter() } -&gt; Either.Left(RegistrationError.InvalidName)         user.age &lt; 0 || user.age &gt; 120 -&gt; Either.Left(RegistrationError.InvalidAge)         !user.email.isValidEmail() -&gt; Either.Left(RegistrationError.InvalidEmail)         else -&gt; Either.Right(\"\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d: ${user.name}\")     } }  fun main() {     val users = listOf(         User(\"Alice\", 30, \"alice@example.com\"),         User(\"Bob123\", 25, \"bob@example.com\"),         User(\"Charlie\", -5, \"charlie@example.com\"),         User(\"David\", 25, \"davidexample.com\")     )      users.forEach { user -&gt;         when (val result = validateUser(user)) {             is Either.Left -&gt; println(result.value) \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043a\u0438             is Either.Right -&gt; println(result.value) \/\/ \u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442         }     } }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043d\u043e\u0432\u043e\u0433\u043e? \u041f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 <code>Either<\/code> \u2014 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u0438\u0431\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c <code>Right<\/code>, \u043b\u0438\u0431\u043e \u043e\u0448\u0438\u0431\u043a\u043e\u0439 <code>Left<\/code>. \u0422\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043a\u0430\u043a \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435. <\/p>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043d\u0430 <a href=\"https:\/\/youtu.be\/F5NaqGF9oT4?t=735\" rel=\"noopener noreferrer nofollow\"><em>Kotlin Conf<\/em><\/a>  \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438 \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c.<\/p>\n<ul>\n<li>\n<p>\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0441 Either \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0438\u043f\u043e\u0432 \u043e\u0448\u0438\u0431\u043e\u043a, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u043d\u043e\u0432\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432 RegistrationError. \u0422\u0430\u043a \u043c\u044b \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Either, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0435\u044f\u0432\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u0434 \u0431\u043e\u043b\u0435\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u044f\u0432\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u043e\u0435\u043c \u043a\u043e\u0441\u0442\u043e\u0447\u043a\u0438 \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041a\u043e\u0434 \u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0441\u0442\u0430\u0442\u044c \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u043c, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u043c\u0435\u0441\u0442, \u0433\u0434\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430, \u043c\u043d\u043e\u0433\u043e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>validateUser<\/code>. \u041a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u043d\u0438\u0445 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"kotlin\">fun someFunction() {     try {         validateUser(user)     } catch (e: IllegalArgumentException) {         println(e.message)     } }<\/code><\/pre>\n<p>\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0431\u0443\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0441\u0431\u043e\u0438:<\/p>\n<pre><code class=\"kotlin\">fun anotherFunction() {     validateUser(user) \/\/ \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a }<\/code><\/pre>\n<h2>\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u0445, \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430. \u041d\u0443 \u0438 \u0441\u0442\u0430\u0440\u0430\u043b\u0438\u0441\u044c \u043d\u0435 \u0443\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435&#8230;<\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u0441\u0430\u0439\u0434-\u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 DI \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0432 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f: \u043c\u043e\u0440\u0444\u0438\u0437\u043c, \u043c\u0435\u043c\u043e\u0438\u0437\u0430\u0446\u0438\u044f, \u043c\u043e\u043d\u043e\u0438\u0434, \u0444\u0443\u043d\u043a\u0442\u043e\u0440, \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u043a\u0430\u0440\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0447\u0442\u043e \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e! \u0421\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043b\u044e\u0441\u0438\u043a\u0438, \u0435\u0441\u043b\u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c, \u0438 \u0434\u0435\u043b\u0438\u0442\u0435\u0441\u044c \u0438\u043c \u0441 \u0434\u0440\u0443\u0437\u044c\u044f\u043c\u0438. \u0410 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u043c IT \u0432 \u0414\u043e\u0434\u043e, \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0432\u00a0<a href=\"https:\/\/t.me\/+en2c05Bh6ihlM2Yy\" rel=\"noopener noreferrer nofollow\">Telegram-\u043a\u0430\u043d\u0430\u043b\u0435 Dodo Engineering<\/a>. \u0422\u0430\u043c \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e \u043d\u0430\u0448\u0435\u0439 \u0436\u0438\u0437\u043d\u0438, \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u0445.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/articles\/917960\/\"> https:\/\/habr.com\/ru\/articles\/917960\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<h2>\u041e \u0447\u0451\u043c \u0441\u0442\u0430\u0442\u044c\u044f<\/h2>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/companies\/dododev\/articles\/917222\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438<\/a> \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u043e \u0441\u0432\u043e\u0451\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0435 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e\u0439 \u043f\u0430\u0440\u0430\u0434\u0438\u0433\u043c\u044b. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0432\u044b \u0443\u0437\u043d\u0430\u0435\u0442\u0435 \u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u0445. \u041c\u044b:<\/p>\n<ul>\n<li>\n<p>\u0443\u0437\u043d\u0430\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0435 <em>State<\/em> <em>Machine<\/em> \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043a\u043e\u043f\u0430\u0435\u043c\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 <em>Kotlin<\/em> <em>Arrow<\/em>;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 <em>Null<\/em>, \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0447\u043d\u0451\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c <em>Data<\/em> \u0438 <em>Domain<\/em> \u0441\u043b\u043e\u0438 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f)<\/h2>\n<p>\u0423\u0432\u0435\u0440\u0435\u043d, \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043b\u044b\u0448\u0430\u043b\u0438: \u00ab\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 <em>var<\/em> \u0442\u0430\u043c, \u0433\u0434\u0435 \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e\u00bb. \u041d\u043e \u043f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043d\u0438\u043a\u0442\u043e \u0442\u0430\u043a \u0438 \u043d\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u043b.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0434\u0430\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442 \u0432 \u0442\u0440\u0435\u043d\u0430\u0436\u0451\u0440\u043d\u044b\u0439 \u0437\u0430\u043b. \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    var start: LocalDateTime,    var end: LocalDateTime ) {    fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    } }<\/code><\/pre>\n<p>\u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043d\u043e \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0442\u0430\u043a. \u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0431\u0440\u043e\u0441\u043e\u043a \u043a\u043b\u0430\u0441\u0441\u0430 <code>SubscribtionCard<\/code>. \u0421\u043b\u0435\u0434\u0443\u044f \u0441\u0442\u0438\u043b\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c\u0443 \u0432 \u0442\u0438\u043f\u0435 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0434\u0432\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c\u0438 \u0433\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438 \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u0430\u043c\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"kotlin\">val card = SubscriptionCard(    serialNumber = UUID.randomUUID().toString(),    validityDataRange = ValidityDataRange(        start = LocalDateTime.parse(\"2024-10-01T10:15:30\"),        end = LocalDateTime.parse(\"2024-11-01T10:15:30\")    ) ) val date = LocalDateTime.parse(\"2024-10-05T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/ true<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0438\u043f\u0430 <code>Card<\/code>. \u0414\u0430\u0442\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0435\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u2014 1 \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2024 \u0433\u043e\u0434\u0430, \u0430 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u2014 1 \u043d\u043e\u044f\u0431\u0440\u044f 2024 \u0433\u043e\u0434\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u0430 \u043b\u0438 \u043a\u0430\u0440\u0442\u0430 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0443\u044e \u0434\u0430\u0442\u0443.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0432 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043a\u0430\u0440\u0442\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u0430. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 true. \u041d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0438\u043f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e.<\/p>\n<pre><code class=\"kotlin\">val date = LocalDateTime.parse(\"2024-10-10T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/true card.validityDataRange.end = LocalDateTime.parse(\"2024-10-06T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/false<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0432\u0435\u043d <em>false<\/em>. \u0412\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043d\u0430\u0434\u043e. \u041d\u043e \u0442\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c \u043e\u0431\u044a\u0451\u043c \u043a\u043e\u0434\u0430. \u0418\u043c\u0435\u044f \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0441 \u043e\u0434\u043d\u0438\u043c\u0438 \u0438 \u0442\u0435\u043c\u0438 \u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0438\u0441\u043f\u043e\u0440\u0442\u0438\u0442\u044c \u0438\u0445 \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<p>\u041e\u0434\u043d\u0430 \u0447\u0430\u0441\u0442\u044c \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0437\u043d\u0430\u0442\u044c \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043d\u0435\u0441\u043b\u0430 \u0434\u0440\u0443\u0433\u0430\u044f \u0435\u0433\u043e \u0447\u0430\u0441\u0442\u044c \u0432 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043e\u0431\u044a\u0435\u043a\u0442. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430. \u041d\u0430\u0448 \u043f\u0440\u0438\u043c\u0435\u0440 \u2014 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u043c\u0443 \u043e\u0447\u0435\u043d\u044c \u0432\u044b\u0441\u043e\u043a\u0430. \u041e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u0441\u0442\u0430\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u0422\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0439 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0451\u0442 \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0442\u0435\u0440\u044f\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430. \u0418 \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442. \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u2014 \u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0444\u043b\u0430\u0433 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430 \u0441 \u043e\u043f\u044b\u0442\u043e\u043c. \u041e\u043d \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0418 \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043a\u043e\u0434\u0430 \u0432\u044b\u0448\u0435. \u041e\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0436\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u0442\u044b \u043c\u0435\u043d\u044c\u0448\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e, \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0444\u0438\u043a\u0441\u0438\u0442\u044c \u0438 \u0431\u0435\u0437 \u0424\u041f, \u0433\u0440\u0430\u043c\u043e\u0442\u043d\u043e \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0432 \u0442\u0438\u043f. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u044b\u043c, \u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0431\u043e\u043b\u0435\u0435 \u0431\u043b\u0438\u0437\u043a\u0438\u0435 \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u0435\u0439\u0441\u044b.<\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043a\u043e\u0434\u043e\u043c \u0432\u044b\u0448\u0435:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    start: LocalDateTime,    end: LocalDateTime ) {    init {        require(!start.isAfter(end)) { \"End should be ahead of Start or equal\" }    }      var start: LocalDateTime = start        private set    var end: LocalDateTime = end        private set      fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    } }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443, \u2014 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0441\u0434\u0435\u043b\u0430\u0432 \u0441\u0435\u0442\u0442\u0435\u0440\u044b \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c\u0438. \u042d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u044f\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c.<\/p>\n<p>\u041d\u043e \u043a\u0430\u043a \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430? \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0451\u043c <code>isInEffect<\/code>.<\/p>\n<pre><code class=\"kotlin\">val date = LocalDateTime.parse(\"2024-10-10T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/true card.validityDataRange.end = LocalDateTime.parse(\"2024-10-06T10:15:30\") \/\/ \u043e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 val newDate = LocalDateTime.parse(\"2024-10-06T10:15:30\") println(card.validityDataRange.isInEffect(date)) \/\/false<\/code><\/pre>\n<p>\u041a\u043e\u0434 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e \u0441\u0442\u0430\u043b \u043b\u0443\u0447\u0448\u0435. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d. \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u0440\u0442\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0430\u043b\u0430 \u043d\u0438\u0436\u0435. \u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u043e\u0434 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438 \u0438\u0445 \u00ab\u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438\u00bb.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0441\u0442\u0430\u043b\u0430\u0441\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043a\u0440\u044b\u0442\u0430 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u043e\u043c \u0442\u0438\u043f\u0435: \u0438\u0437\u043d\u0443\u0442\u0440\u0438 \u0442\u0438\u043f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439. \u041a\u0430\u043a \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e?<\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    start: LocalDateTime,    end: LocalDateTime ) {    init {        require(!start.isAfter(end)) { \"End should be ahead of Start or equal\" }    }      var start: LocalDateTime = start        private set    var end: LocalDateTime = end        private set      fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    }      fun extend(days: Long) {        end = end.plusDays(days)    } }<\/code><\/pre>\n<p>\u0418\u0437 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043d\u0430\u0448 \u0442\u0438\u043f \u0432\u0441\u0451 \u0435\u0449\u0451 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u0437\u043d\u0443\u0442\u0440\u0438. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u044e\u0431\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u0432\u044b\u043a\u0430\u0442\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0438 \u043d\u0430\u0448 \u0442\u0438\u043f \u043f\u043e\u0442\u0435\u0440\u044f\u043b \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0412\u0435\u0440\u043d\u0451\u043c\u0441\u044f \u043a \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430\u043c \u0432 \u0441\u043f\u043e\u0440\u0442\u0437\u0430\u043b. \u041c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0434\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u0430 \u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0437\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u043b\u0430\u0442\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0434\u043b\u0438\u0442\u044c \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<pre><code class=\"kotlin\">fun main() {     val cert1 = SubscriptionCard( \"Certificate A\", ValidityDataRange(         LocalDateTime.of(2024, 10, 1, 0, 0),         LocalDateTime.of(2024, 11, 1, 0, 0)    )     )      val cert2 = SubscriptionCard( \"Certificate B\", ValidityDataRange(         LocalDateTime.of(2024, 11, 1, 0, 0),         LocalDateTime.of(2024, 12, 1, 0, 0)    )     )      \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0441 \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438     val catalog = listOf(cert1, cert2)      println(\"Original Validity Ranges:\")     catalog.forEach { println(\"${it.serialNumber}: ${it.validityDateRange.start} to ${it.validityDateRange.end}\") }     \/*       \u0412\u044b\u0432\u0435\u0434\u0435\u0442 Original Validity Ranges:      Certificate A: 2024-10-01T00:00 to 2024-11-01T00:00      Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00      *\/      \/\/ \u041f\u0440\u043e\u0434\u043b\u0435\u0432\u0430\u0435\u043c \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430     cert1.validityDateRange.extend(5)        println(\"\\nUpdated Validity Ranges:\")     catalog.forEach { println(\"${it.serialNumber}: ${it.validityDateRange.start} to ${it.validityDateRange.end}\") }     \/*       \u0412\u044b\u0432\u0435\u0434\u0435\u0442 Updated Validity Ranges:      Certificate A: 2024-10-01T00:00 to 2024-11-06T00:00      Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00      *\/  }<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430 \u043a\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e, \u043d\u043e \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u043c\u044b \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043e\u0434\u0438\u043d \u0434\u0435\u043d\u044c? \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>ValidityDataRange<\/code> \u0434\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0432\u0441\u0435\u043c \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430\u043c. \u041d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0438 \u0442\u0430 \u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 extend \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0451\u043c\u0441\u044f \u0441 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0440\u043e\u043a\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0438 \u0441\u0440\u0430\u0437\u0443:<\/p>\n<pre><code class=\"kotlin\">val monthlyRange = ValidityDataRange(   LocalDateTime.of(2024, 11, 1, 0, 0),   LocalDateTime.of(2024, 12, 1, 0, 0) ) val cert1 = SubscriptionCard(\"Certificate A\", monthlyRange)  val cert2 = SubscriptionCard(\"Certificate B\", monthlyRange)  \/\/ \u041f\u0440\u043e\u0434\u043b\u0435\u0432\u0430\u0435\u043c \u0441\u0440\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0430\u0431\u043e\u043d\u0435\u043c\u0435\u043d\u0442\u0430 cert1.validity.extend(5)  Original Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-01T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00  Updated Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-06T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-06T00:00<\/code><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c&#8230; \u041c\u044b \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u0438\u0448\u043b\u0438 \u043a \u0442\u043e\u0439 \u0436\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0439 \u0441 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u044c\u044e \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u0435\u043c \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c\u0441\u044f \u0438 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438. \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443?<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0432 <em>Kotlin<\/em> \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041e\u043d \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>start<\/code> \u0438 <code>end<\/code> \u043a\u0430\u043a <em>readOnly<\/em>:<\/p>\n<pre><code class=\"kotlin\">class ValidityDataRange(    val start: LocalDateTime,    val end: LocalDateTime ) {    init {        require(!start.isAfter(end)) { \"End should be ahead of Start or equal\" }    }     fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    }      fun extend(days: Int): ValidityDataRange = ValidityDataRange(        start = start,        end = end.plusDays(days.toLong())    ) }  Original Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-01T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00  Updated Validity Ranges: Certificate A: 2024-11-01T00:00 to 2024-12-01T00:00 Certificate B: 2024-11-01T00:00 to 2024-12-01T00:00<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>data class<\/em>. \u041e\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>copy()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 <code>val<\/code> \u043f\u043e\u043b\u044f\u043c\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043c\u043e\u0434\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u0421\u0442\u043e\u0438\u0442 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c &#8212; \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432\u044b \u043d\u0435 \u0440\u0435\u0448\u0438\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 <em>data class<\/em> <code>var<\/code> \u043f\u043e\u043b\u044f \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u0430\u043c\u043e\u0433\u043e <br \/><em>data class<\/em> \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c <code>var<\/code>.<\/p>\n<pre><code class=\"kotlin\">data class ValidityDataRange(    val start: LocalDateTime,    val end: LocalDateTime ) {    fun isInEffect(date: LocalDateTime): Boolean {        return (start.isBefore(date) || start.isEqual(date)) &amp;&amp;                (end.isAfter(date) || end.isEqual(date))    }      fun extend(days:<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-465408","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/465408","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=465408"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/465408\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=465408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=465408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=465408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}