1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[623],{7062:function(e,r,t){"use strict";t.r(r),t.d(r,{default:function(){return MDXContent},meta:function(){return c}});var n=t(9499),s=t(5893),o=t(1151),i=t(1214),a=t(6778);function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,n)}return t}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){(0,n.Z)(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}var c={title:"OCP | Ð¨Ð°Ð±Ð»Ð¾Ð½Ñ Ð¿ÑоекÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ пÑиÑÐ¼Ñ ÑеÑакÑоÑинга",description:"Ð¨Ð°Ð±Ð»Ð¾Ð½Ñ Ð¿ÑоекÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ пÑиÑÐ¼Ñ ÑеÑакÑоÑинга, коÑоÑÑе помогаÑÑ ÑледоваÑÑ Ð¿ÑинÑÐ¸Ð¿Ñ Ð¾ÑкÑÑÑоÑÑи-закÑÑÑоÑÑи"},MDXLayout=function(e){var r=e.children;return(0,s.jsx)(i.Z,{meta:c,children:r})};function _createMdxContent(e){var r=_objectSpread(_objectSpread({a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",section:"section",ul:"ul"},(0,o.a)()),e.components);return(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h1,{children:"Ð¨Ð°Ð±Ð»Ð¾Ð½Ñ Ð¿ÑоекÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ пÑиÑÐ¼Ñ ÑеÑакÑоÑинга"}),(0,s.jsx)(r.p,{children:"СоблÑдаÑÑ Ð¿ÑинÑип оÑкÑÑÑоÑÑи-закÑÑÑоÑÑи помогаÑÑ Ð½ÐµÑколÑко Ñаблонов пÑоекÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ пÑиÑмов ÑеÑакÑоÑинга."}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐбÑÑÑакÑÐ½Ð°Ñ ÑабÑика"}),(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"https://github.com/kamranahmedse/design-patterns-for-humans#-simple-factory",children:"ФабÑика"})," â ÑÑо ÑÑÑноÑÑÑ, коÑоÑÐ°Ñ ÑоздаÑÑ Ð´ÑÑгие ÑÑÑноÑÑи по заданнÑм пÑавилам, напÑимеÑ, ÑоздаÑÑ ÑкземплÑÑÑ ÐºÐ»Ð°ÑÑов или обÑекÑÑ."]}),(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"https://refactoring.guru/ru/design-patterns/abstract-factory",children:"ÐбÑÑÑакÑÐ½Ð°Ñ ÑабÑика"})," â ÑÑо ÑабÑика, коÑоÑÐ°Ñ ÑоздаÑÑ ÑабÑики."]}),(0,s.jsx)(r.p,{children:"ÐÑÐ¾Ñ Ñаблон позволÑÐµÑ ÑоздаваÑÑ ÑÑÑноÑÑи без пÑивÑзки к конкÑеÑнÑм клаÑÑам â Ñо еÑÑÑ Ð±ÐµÐ· пÑивÑзки к ÑеализаÑии. Так добавление новÑÑ
Ñипов ÑÑÑноÑÑей изменÑÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñное колиÑеÑÑво модÑлей."}),(0,s.jsxs)(r.p,{children:["РаÑÑмоÑÑим пÑименение абÑÑÑакÑной ÑабÑики на Ñом же пÑимеÑе Ñ Ð¾ÑÑÑÑом, ÑÑо ",(0,s.jsx)(r.a,{href:"/srp/in-ideal-world",children:"бÑл Ñ Ð½Ð°Ñ Ð² Ñазделе об SRP"}),"."]}),(0,s.jsx)(r.p,{children:"Ð ÑÑом пÑимеÑе ÑабоÑа Ð´Ð»Ñ Ð°Ð±ÑÑÑакÑной ÑабÑики â вÑÐ±Ð¾Ñ ÐºÐ»Ð°ÑÑа, коÑоÑÑй бÑÐ´ÐµÑ Ð·Ð°Ð½Ð¸Ð¼Ð°ÑÑÑÑ ÑоÑмаÑиÑованием."}),(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ts",children:"// ЧаÑÑÑ Ñ Ð¸Ð½ÑеÑÑейÑом `Formatter` и клаÑÑами,\n// ÑеализÑÑÑими его, оÑÑаÑÑÑÑ Ñакой же.\n// ÐобавлÑеÑÑÑ Ð½Ð¾Ð²Ñй инÑеÑÑейÑ, опиÑÑваÑÑий ÑабÑÐ¸ÐºÑ ÑабÑик:\n\ninterface FormatterFactory {\n createFormatter(data: ReportData): Formatter\n}\n\n// ÐеÑод `createFormatter` возвÑаÑÐ°ÐµÑ Ð°Ð±ÑÑÑакÑнÑй инÑеÑÑейÑ,\n// поÑÑÐ¾Ð¼Ñ Ð¾Ð±Ðµ ÑабÑики ниже взаимозаменÑемÑ:\n\nclass HtmlFormatterFactory implements FormatterFactory {\n createFormatter(data: ReportData) {\n return new HtmlFormatter(data)\n }\n}\n\nclass TxtFormatterFactory implements FormatterFactory {\n createFormatter(data: ReportData) {\n return new TxtFormatter(data)\n }\n}\n\n// ÐÑи конÑигÑÑаÑии пÑиложение вÑбеÑÐµÑ Ð½ÑжнÑй\n// Ñип ÑабÑики и бÑÐ´ÐµÑ ÑабоÑаÑÑ Ñ Ð½Ð¸Ð¼.\n// ÐÐ¾Ð´Ñ Ð¿ÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñи ÑÑом бÑÐ´ÐµÑ Ð½Ðµ важно,\n// Ñ ÐºÐ°ÐºÐ¾Ð¹ ÑабÑикой он бÑÐ´ÐµÑ ÑабоÑаÑÑ,\n// поÑÐ¾Ð¼Ñ ÑÑо он бÑÐ´ÐµÑ Ð·Ð°Ð²Ð¸ÑеÑÑ Ð¾Ñ Ð¸Ð½ÑеÑÑейÑов,\n// а не Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑнÑÑ
клаÑÑов:\n\nclass AppConfigurator {\n reportType: ReportTypes\n\n constructor(reportType: ReportTypes) {\n this.reportType = reportType\n }\n\n configure(reportData: ReportData): FormatterFactory {\n if (this.reportType === ReportTypes.Html) {\n return new HtmlFormatterFactory(reportData)\n }\n else return new TxtFormatterFactory(reportData)\n }\n}\n"})})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐопÑоÑÑ"}),(0,s.jsx)(a.x,{name:"ocp-patterns-1"}),(0,s.jsx)(a.x,{name:"ocp-patterns-2"})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"СÑÑаÑегиÑ"}),(0,s.jsxs)(r.p,{children:["РпÑоÑлом пÑимеÑе Ð¼Ñ Ð¸Ð·Ð±Ð°Ð²Ð¸Ð»Ð¸ÑÑ Ð¾Ñ Ð½ÐµÐ¾Ð±Ñ
одимоÑÑи менÑÑÑ ÐºÐ¾Ð´ ÑоÑмаÑеÑов пÑи добавлении новÑÑ
ÑÑебований. Ðо Ð²Ñ Ð¼Ð¾Ð³Ð»Ð¸ замеÑиÑÑ, ÑÑо в меÑоде ",(0,s.jsx)(r.code,{children:"configure"})," клаÑÑа ",(0,s.jsx)(r.code,{children:"AppConfigurator"})," еÑÑÑ ÑÑловие, коÑоÑое пÑовеÑÑÐµÑ Ñип ÑоÑмаÑа Ð´Ð»Ñ Ð¾ÑÑÑÑа."]}
1),(0,s.jsxs)(r.p,{children:["Ðо-Ñ
оÑоÑемÑ, подобнÑе ÑÑÐ»Ð¾Ð²Ð¸Ñ ",(0,s.jsx)(r.a,{href:"https://softwareengineering.stackexchange.com/a/302782",children:"ÑледÑÐµÑ Ð·Ð°Ð¼ÐµÐ½ÑÑÑ"})," на динамиÑеÑкий вÑÐ±Ð¾Ñ Ð½ÑжнÑÑ
ÑÑÑноÑÑей. С ÑÑим Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð¼Ð¾ÑÑ ÐµÑÑ Ð¾Ð´Ð¸Ð½ Ñаблон â ",(0,s.jsx)(r.a,{href:"https://github.com/kamranahmedse/design-patterns-for-humans#-strategy",children:"ÑÑÑаÑегиÑ"}),"."]}),(0,s.jsx)(r.p,{children:"ÐÑÐ¾Ñ Ñаблон позволÑÐµÑ Ð¼ÐµÐ½ÑÑÑ Ð½Ð°ÑÑÑойки, конÑигÑÑаÑÐ¸Ñ Ð¸Ð»Ð¸ алгоÑиÑм в завиÑимоÑÑи Ð¾Ñ ÑиÑÑаÑии и ÑÑебований. РнаÑем ÑлÑÑае ÑÑÑаÑегии Ð¼Ñ Ð¾Ñдадим вÑÐ±Ð¾Ñ Ð½ÐµÐ¾Ð±Ñ
одимой ÑабÑики:"}),(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ts",children:"function formatterStrategy(reportType: ReportTypes) {\n const formatters = {\n [ReportTypes.Html]: HtmlFormatterFactory,\n [ReportTypes.Txt]: TxtFormatterFactory,\n default: TxtFormatterFactory\n }\n\n return formatters[reportType] || formatters.default\n}\n"})}),(0,s.jsx)(r.p,{children:"ТепеÑÑ Ð²ÑÐ±Ð¾Ñ ÑабÑик ÑÑал динамиÑеÑким, и пÑи изменении ÑÑебований нам поÑÑебÑеÑÑÑ ÑолÑко добавиÑÑ Ð½Ð¾Ð²ÑÑ ÑÑÑноÑÑÑ Ð¸ обновиÑÑ ÑпиÑок ÑабÑик."})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐопÑоÑÑ"}),(0,s.jsx)(a.x,{name:"ocp-patterns-3"}),(0,s.jsx)(a.x,{name:"ocp-patterns-4"})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐекоÑаÑоÑ"}),(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"https://refactoring.guru/ru/design-patterns/decorator",children:"ÐекоÑаÑоÑ"})," â ÑÑо Ñаблон, коÑоÑÑй заклÑÑаеÑÑÑ Ð² Ñоздании обÑÑÑок Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑной ÑÑнкÑионалÑноÑÑÑÑ Ð´Ð»Ñ Ð¾Ð±ÑекÑов. Такие обÑÑÑки позволÑÑÑ Ð½Ðµ изменÑÑÑ Ñам обÑекÑ, но пÑи ÑÑом ÑаÑÑиÑÑÑÑ ÐµÐ³Ð¾ ÑÑнкÑионалÑноÑÑÑ."]}),(0,s.jsx)(r.p,{children:"ÐÑлиÑие декоÑаÑоÑа Ð¾Ñ Ð½Ð°ÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² возможноÑÑи ÑаÑÑиÑÑÑÑ ÑÑнкÑионалÑноÑÑÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑки, без необÑ
одимоÑÑи опиÑÑваÑÑ ÐºÐ°Ð¶Ð´Ñй клаÑÑ-наÑледник оÑделÑно."}),(0,s.jsxs)(r.p,{children:["РпÑимеÑе Ð¼Ñ ÑоздаÑм клаÑÑ ",(0,s.jsx)(r.code,{children:"BaseGreeting"}),", меÑод ",(0,s.jsx)(r.code,{children:"greet"})," коÑоÑого бÑÐ´ÐµÑ Ð²ÑводиÑÑ ÑÑÑÐ¾ÐºÑ Ñ Ð¿ÑивеÑÑÑвием полÑзоваÑелÑ. ÐекоÑаÑÐ¾Ñ ",(0,s.jsx)(r.code,{children:"GreetingWithUppercase"})," бÑÐ´ÐµÑ Ð¿ÑиводиÑÑ ÑÑÑÐ¾ÐºÑ Ñ Ð¿ÑивеÑÑÑвием к веÑÑ
Ð½ÐµÐ¼Ñ ÑегиÑÑÑÑ."]}),(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ts",children:"interface Greeting {\n username: string\n greet(): string\n}\n\n// ÐÐ°Ð·Ð¾Ð²Ð°Ñ ÑÑнкÑионалÑноÑÑÑ Ð¾Ð¿Ð¸ÑÑваеÑÑÑ Ð² клаÑÑе,\n// коÑоÑÑй бÑÐ´ÐµÑ Ð¾Ð±ÑÑнÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð´ÐµÐºÐ¾ÑаÑоÑов:\n\nclass BaseGreeting implements Greeting {\n username: string\n\n constructor(username: string) {\n this.username = username\n }\n\n greet(): string {\n return `Hello, ${this.username}!`\n }\n}\n\n// ÐдеÑÑ `decorated` â ÑÑо обÑекÑ,\n// ÑÑнкÑионалÑноÑÑÑ ÐºÐ¾ÑоÑого Ð¼Ñ Ð±Ñдем ÑаÑÑиÑÑÑÑ:\n\ninterface GreetingDecorator {\n decorated: Greeting\n greet(): string\n}\n\nclass GreetingWithUppercase implements GreetingDecorator {\n decorated: Greeting\n\n constructor(decorated: Greeting) {\n this.decorated = decorated\n }\n\n greet(): string {\n // 1. ÐÑполÑзÑем базовое поведение:\n const baseGreeting = this.decorated.greet()\n\n // 2. РаÑÑиÑÑем его:\n return baseGreeting.toUpperCase()\n }\n}\n"})}),(0,s.jsx)(r.p,{children:"Сама ÑилоÑоÑÐ¸Ñ ÑÑого Ñаблона повÑоÑÑÐµÑ Ð¿ÑинÑип оÑкÑÑÑоÑÑи-закÑÑÑоÑÑи â Ð¼Ñ Ð½Ðµ менÑем базовÑй клаÑÑ, а добавлÑем ÑÑÑноÑÑи, коÑоÑÑе ÑодеÑÐ¶Ð°Ñ Ð² Ñебе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±Ð¸Ð·Ð½ÐµÑ-ÑÑебований."}),(0,s.jsxs)(r.p,{children:["РазниÑа Ð¼ÐµÐ¶Ð´Ñ Ð´ÐµÐºÐ¾ÑаÑоÑом и ",(0,s.jsx)(r.a,{href:"https://refactoring.guru/ru/design-patterns/proxy",children:"пÑокÑи"})," в Ñом, ÑÑо пÑокÑи вÑегда пÑедоÑÑавлÑÐµÑ ÑÐ¾Ñ Ð¶Ðµ инÑеÑÑейÑ, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº декоÑаÑÐ¾Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедоÑÑавлÑÑÑ ÑаÑÑиÑеннÑй инÑеÑÑейÑ."]})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐопÑоÑÑ"}),(0,s.jsx)(a.x,{name:"ocp-patterns-5"}),(0,s.jsx)(a.x,{name:"ocp-patterns-6"})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐаблÑдаÑелÑ"}),(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"https://refactoring.guru/ru/design-patterns/observer",children:"ÐаблÑдаÑелÑ"})," â Ñаблон, коÑоÑÑй ÑоздаÑÑ Ð¼ÐµÑ
анизм подпиÑки, когда некоÑоÑÑе ÑÑÑноÑÑи могÑÑ ÑеагиÑоваÑÑ Ð½Ð° поведение дÑÑгиÑ
."]}),(0,s.jsxs)(r.p,{children:["РпÑимеÑе ниже Ñ Ð½Ð°Ñ ÐµÑÑÑ ÐºÐ»Ð°ÑÑ ",(0,s.jsx)(r.code,{children:"SoftwareEngineerApplicant"}),", коÑоÑÑй ÑеагиÑÑÐµÑ Ð½Ð° поÑвление ваканÑий в ÑкземплÑÑе клаÑÑа ",(0,s.jsx)(r.code,{children:"HrAgency"}),"."]}),(0,s.jsx)(r.pre,{children:(0,s.jsx)(r.code,{className:"language-ts",children:"// ÐнÑеÑÑÐµÐ¹Ñ ÑоиÑкаÑÐµÐ»Ñ Ð¾Ð¿Ð¸ÑÑÐ²Ð°ÐµÑ ÐµÐ³Ð¾ Ð¸Ð¼Ñ Ð¸ желаемÑÑ Ð¿Ð¾Ð·Ð¸ÑиÑ:\n\ninterface Applicant {\n name: string\n position: string\n}\n\n// ÐнÑеÑÑÐµÐ¹Ñ Ð½Ð°Ð±Ð»ÑдаÑÐµÐ»Ñ Ð¾Ð¿Ð¸ÑÑÐ²Ð°ÐµÑ Ð¼ÐµÑод,\n// коÑоÑÑй бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð½Ð°Ð±Ð»ÑдаемÑм обÑекÑом\n// пÑи наÑÑÑплении ÑобÑÑиÑ:\n\ninterface Observer {\n update(data: any): void\n}\n\ninterface NewPositionObserver extends Applicant, Observer {\n update(position: string): void\n}\n\nclass SoftwareEngineerApplicant implements NewPositionObserver {\n name: string\n position: string\n\n constructor(name: string, position: string) {\n this.name = name\n this.position = position\n }\n\n update(position: string) {\n if (position !== this.position) return\n console.log(`Hello! My name is ${this.name}, I would like to apply to a ${position} position`)\n }\n}\n\n// ÐазовÑй инÑеÑÑÐµÐ¹Ñ Ð½Ð°Ð±Ð»Ñдаемого обÑекÑа:\n\ninterface Observable {\n subscribe(observer: Observer): void\n unsubscribe(observer: Observer): void\n notify(data: any): void\n}\n\n// ÐаблÑдаемÑй обÑÐµÐºÑ Ñ
ÑÐ°Ð½Ð¸Ñ Ð² Ñебе ÑпиÑок наблÑдаÑелей,\n// коÑоÑÑÑ
бÑÐ´ÐµÑ ÑведомлÑÑÑ Ð¾ наÑÑÑплении ÑобÑÑиÑ:\n\ninterface NewPositionObservable extends Observable {\n listeners: NewPositionObserver[]\n notify(position: string): void\n}\n\nclass HrAgency implements NewPositionObservable {\n listeners: NewPositionObserver[] = []\n\n subscribe(applicant: NewPositionObserver): void {\n this.listeners.push(applicant)\n }\n\n unsubscribe(applicant: NewPositionObserver): void {\n this.listeners = this.listeners.filter(listener =>
1\n listener.name !== applicant.name)\n }\n\n // УведомлÑем вÑеÑ
наблÑдаÑелей,\n // когда поÑвлÑеÑÑÑ Ð½Ð¾Ð²Ð°Ñ Ð²Ð°ÐºÐ°Ð½ÑиÑ:\n\n notify(position: string): void {\n this.listeners.forEach(listener => {\n listener.update(position)\n })\n }\n}\n"})}),(0,s.jsx)(r.p,{children:"ÐÑÐ¾Ñ Ñаблон позволÑÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ Ð½Ð¾Ð²ÑÑ
наблÑдаÑелей без необÑ
одимоÑÑи менÑÑÑ ÐºÐ¾Ð´ наблÑдаемого обÑекÑа."})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐопÑоÑÑ"}),(0,s.jsx)(a.x,{name:"ocp-patterns-7"}),(0,s.jsx)(a.x,{name:"ocp-patterns-8"})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"Ðамена пÑÑмого наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð° полимоÑÑизм и композиÑиÑ"}),(0,s.jsx)(r.p,{children:"ÐодÑли, завиÑÑÑие Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑнÑÑ
клаÑÑов, ÑвÑÐ·Ð°Ð½Ñ Ñ Ð½Ð¸Ð¼Ð¸ ÑлиÑком ÑилÑно, из-за Ñего изменение в одном модÑле заÑÑÐ¾Ð½ÐµÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ в дÑÑгом."}),(0,s.jsxs)(r.p,{children:[(0,s.jsx)(r.a,{href:"https://blog.aspiresys.pl/technology/example-of-just-in-time-design-refactor-to-open-closed/",children:"Ðамена"})," пÑÑмого наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð° полимоÑÑизм или композиÑÐ¸Ñ â ÑÑо пÑиÑм ÑеÑакÑоÑинга, коÑоÑÑй оÑлаблÑÐµÑ Ð·Ð°Ñепление модÑлей ÑеÑез введение абÑÑÑакÑий: инÑеÑÑейÑов, обÑÑÑок и Ñ.д."]}),(0,s.jsxs)(r.p,{children:["ÐÑимеÑом Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑлÑжиÑÑ ",(0,s.jsx)(r.a,{href:"/ocp/in-ideal-world",children:"пÑимеÑ"})," из Ñаздела \xabРидеалÑном миÑе\xbb, где Ð¼Ñ Ð²Ð²Ð¾Ð´Ð¸Ð»Ð¸ пÑоÑÐ»Ð¾Ð¹ÐºÑ Ð¸Ð· инÑеÑÑейÑа ",(0,s.jsx)(r.code,{children:"Shape"}),". Ðогда клаÑÑ ",(0,s.jsx)(r.code,{children:"AreaCalculator"})," наÑÐ¸Ð½Ð°ÐµÑ Ð·Ð°Ð²Ð¸ÑеÑÑ Ð¾Ñ Ð¸Ð½ÑеÑÑейÑа, а не Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑнÑÑ
клаÑÑов, изменение в ÑÑебованиÑÑ
не заÑÑÐ°Ð³Ð¸Ð²Ð°ÐµÑ ÐºÐ¾Ð´ клаÑÑа ",(0,s.jsx)(r.code,{children:"AreaCalculator"}),"."]})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐопÑоÑÑ"}),(0,s.jsx)(a.x,{name:"ocp-patterns-9"})]}),(0,s.jsxs)(r.section,{children:[(0,s.jsx)(r.h2,{children:"ÐаÑеÑÐ¸Ð°Ð»Ñ Ðº ÑазделÑ"}),(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://en.wikipedia.org/wiki/Composition_over_inheritance",children:"Composition over inheritance"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://github.com/kamranahmedse/design-patterns-for-humans#-simple-factory",children:"ФабÑика"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://refactoring.guru/ru/design-patterns/abstract-factory",children:"ÐбÑÑÑакÑÐ½Ð°Ñ ÑабÑика"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://github.com/torokmark/design_patterns_in_typescript/blob/master/abstract_factory/abstractFactory.ts",children:"РеализаÑÐ¸Ñ Ð°Ð±ÑÑÑакÑной ÑабÑики на TypeScript"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://github.com/kamranahmedse/design-patterns-for-humans#-strategy",children:"СÑÑаÑегиÑ"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://sergeyzhuk.me/2018/01/25/factory-method-and-open-closed/",children:"ФабÑиÑнÑй меÑод и пÑименение ÑÑÑаÑегии"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://github.com/torokmark/design_patterns_in_typescript/blob/master/strategy/strategy.ts",children:"РеализаÑÐ¸Ñ ÑÑÑаÑегии на TypeScript"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://refactoring.guru/ru/design-patterns/decorator",children:"ÐекоÑаÑоÑ"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://www.cs.colorado.edu/~kena/classes/5448/f09/lectures/18-decoratorfactory.pdf",children:"Decorator and Factory, Colorado Computer Science, PDF"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://github.com/torokmark/design_patterns_in_typescript/blob/master/decorator/decorator.ts",children:"РеализаÑÐ¸Ñ Ð´ÐµÐºÐ¾ÑаÑоÑа на TypeScript"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://refactoring.guru/ru/design-patterns/observer",children:"ÐаблÑдаÑелÑ"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://github.com/torokmark/design_patterns_in_typescript/blob/master/observer/observer.ts",children:"РеализаÑÐ¸Ñ Ð½Ð°Ð±Ð»ÑдаÑÐµÐ»Ñ Ð½Ð° TypeScript"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://blog.aspiresys.pl/technology/example-of-just-in-time-design-refactor-to-open-closed/",children:"Example of Just-in-time design: refactoring to OCP"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"https://www.goodreads.com/book/show/9850098-essential-skills-for-the-agile-developer?ac=1&from_search=true&qid=9fcKu3LDl6&rank=1",children:"Essential Skills for the Agile Developer, Chapter 11: Refactor to the Open-Closed"})}),"\n"]})]})]})}function MDXContent(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return(0,s.jsx)(MDXLayout,_objectSpread(_objectSpread({},e),{},{children:(0,s.jsx)(_createMdxContent,_objectSpread({},e))}))}},6778:function(e,r,t){"use strict";t.d(r,{x:function(){return S}});var n=t(2777),s=t(2262),o=t(748),i=t(5959),a=t(3553),c=t(7247),l=t(9499);let p=/[\p{Lu}]/u,d=/[\p{Ll}]/u,u=/^[\p{Lu}](?![\p{Lu}])/gu,h=/([\p{Alpha}\p{N}
1_]|$)/u,m=/[_.\- ]+/,f=RegExp("^"+m.source),g=RegExp(m.source+h.source,"gu"),x=RegExp("\\d+"+h.source,"gu"),preserveCamelCase=(e,r,t,n)=>{let s=!1,o=!1,i=!1,a=!1;for(let c=0;c<e.length;c++){let l=e[c];a=!(c>2)||"-"===e[c-3],s&&p.test(l)?(e=e.slice(0,c)+"-"+e.slice(c),s=!1,i=o,o=!0,c++):o&&i&&d.test(l)&&(!a||n)?(e=e.slice(0,c-1)+"-"+e.slice(c-1),i=o,o=!1,s=!0):(s=r(l)===l&&t(l)!==l,i=o,o=t(l)===l&&r(l)!==l)}return e},preserveConsecutiveUppercase=(e,r)=>(u.lastIndex=0,e.replaceAll(u,e=>r(e))),postProcess=(e,r)=>(g.lastIndex=0,x.lastIndex=0,e.replaceAll(x,(t,n,s)=>["_","-"].includes(e.charAt(s+t.length))?t:r(t)).replaceAll(g,(e,t)=>r(t)));var j=t(4851),y=t(7294),v=t(3767),b=t(9521),w=b.ZP.fieldset.withConfig({displayName:"style__Container",componentId:"sc-li9fve-0"})(["margin:0 0 1.5rem 0;padding:0;border:0;button{margin-top:-0.2rem;}"]),C=b.ZP.legend.withConfig({displayName:"style__Heading",componentId:"sc-li9fve-1"})(["padding:0;margin:0 0 0.75rem;font-weight:700;display:block;width:100%;max-width:calc(100vw - 2rem);"]),_=b.ZP.button.withConfig({displayName:"style__Button",componentId:"sc-1rihick-0"})(["border:0;background:",";color:",";border-radius:",";padding:0.6em 1.5em;cursor:pointer;font-size:",";margin:0;&:hover{box-shadow:0 2px 10px ",";}&:active,&:active:hover{box-shadow:none;transform:translateY(1px);}&:disabled{cursor:auto;color:",";}&:disabled:hover{box-shadow:none;}"],function(e){return e.theme.buttonBackground},function(e){return e.theme.buttonColor},function(e){return e.theme.radius},function(e){return e.theme.fontSizeRegular},function(e){return e.theme.decorationColorTetriary},function(e){return e.theme.disabledButtonColor}),k=t(512),P=b.ZP.label.withConfig({displayName:"style__Label",componentId:"sc-1uya17d-0"})(["display:block;user-select:none;cursor:pointer;padding:0.5em 2.2em 0.5em 0.8em;position:relative;border:1px solid ",";border-radius:",";line-height:1.4;max-width:calc(100vw - 2rem);&:hover,&:focus-within{background:",";}&::after{content:' ';display:block;position:absolute;top:0.3em;right:0.3em;}&.selected{border-color:",";}&.completed{cursor:default;&::after{content:'\uD83D\uDEAB';}&.correct::after{content:'â
';}&:hover,&:focus-within{background:none;}}"],function(e){return e.theme.decorationColorPrimary},function(e){return e.theme.radius},function(e){return e.theme.variantHoverBackground},function(e){return e.theme.variantSelectedBorderColor}),O=b.ZP.div.withConfig({displayName:"style__Description",componentId:"sc-1uya17d-1"})(["font-style:italic;color:",";line-height:1.4;padding-top:0.5em;"],function(e){return e.theme.textColorSecondary}),Z=b.ZP.div.withConfig({displayName:"style__Item",componentId:"sc-1uya17d-2"})(["margin:0 0 1rem 0;p:last-child{margin-bottom:0;}"]);b.ZP.div.withConfig({displayName:"style__CodeWrapper",componentId:"sc-1uya17d-3"})(["margin-top:0.5em;pre{margin:0 -1.4rem 0.25em 0;box-shadow:inset 0 0 1px ",";}"],function(e){return e.theme.decorationColorPrimary});var N=t(6168),F=t(5893),R=function(e){(0,i.Z)(Variant,e);var r,t=(r=function(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}(),function(){var e,t=(0,c.Z)(Variant);if(r){var n=(0,c.Z)(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return(0,a.Z)(this,e)});function Variant(){var e;(0,n.Z)(this,Variant);for(var r=arguments.length,s=Array(r),i=0;i<r;i++)s[i]=arguments[i];return e=t.call.apply(t,[this].concat(s)),(0,l.Z)((0,o.Z)(e),"handleChange",function(){var r=e.props,t=r.index;(0,r.onToggleAnswer)(t)}),e}return(0,s.Z)(Variant,[{key:"render",value:function(){var e=this.props,r=e.completed,t=e.selected,n=e.correct,s=e.index,o=e.name,i=e.variant,a=i.text,c=i.description;return(0,F.jsxs)(Z,{children:[(0,F.jsxs)(P,{className:(0,k.Z)({selected:t,correct:n,completed:r}),children:[(0,F.jsx)(N.T,{children:(0,F.jsx)("input",{type:"checkbox",name:o,value:s,checked:t,disabled:r,onChange:this.handleChange})}),(0,F.jsx)("div",{children:a})]}),!!c&&r&&(0,F.jsx)(O,{children:c})]})}}]),Variant}(y.PureComponent),T=function(e){(0,i.Z)(BaseQuizContainer,e);var r,t=(r=function(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}(),function(){var e,t=(0,c.Z)(BaseQuizContainer);if(r){var n=(0,c.Z)(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return(0,a.Z)(this,e)});function BaseQuizContainer(){var e;(0,n.Z)(this,BaseQuizContainer);for(var r=arguments.length,s=Array(r),i=0;i<r;i++)s[i]=arguments[i];return e=t.call.apply(t,[this].concat(s)),(0,l.Z)((0,o.Z)(e),"toggleAnswer",function(r){e.props.quizModel.toggleAnswer(r)}),e}return(0,s.Z)(BaseQuizContainer,[{key:"render",value:function(){var e=this,r=this.props,t=r.quizModel,n=r.question,s=r.variants,o=r.name;return(0,F.jsxs)(w,{children:[(0,F.jsx)(C,{children:n}),s.map(function(r,n){return(0,F.jsx)(R,{name:o,selected:t.answers.includes(n),completed:t.isComplete,correct:t.isComplete&&t.isCorrect(n),index:n,variant:r,onToggleAnswer:e.toggleAnswer},n)}),(0,F.jsx)(_,{disabled:0===t.answers.length,onClick:function(){return t.toggleComplete()},type:"button",children:t.isComplete?"ÐÑойÑи заново":"ÐÑовеÑиÑÑ Ð¾ÑвеÑ"})]})}}]),BaseQuizContainer}(y.Component);(0,l.Z)(T,"defaultProps",{completed:!1,variants:[]});var A=(0,j.Pi)(T),D=function(e){(0,i.Z)(QuizLoader,e);var r,t=(r=function(){if("undefined"==typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch(e){return!1}}(),function(){var e,t=(0,c.Z)(QuizLoader);if(r){var n=(0,c.Z)(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return(0,a.Z)(this,e)});function QuizLoader(e){(0,n.Z)(this,QuizLoader),r=t.call(this,e),(0,l.Z)((0,o.Z)(r),"module",void 0),(0,l.Z)((0,o.Z)(r),"moduleName",void 0);var r,s=r.props.name;return r.state={error:null},r.moduleName=function(e,r){if(!("string"==typeof e||Array.isArray(e)))throw TypeError("Expected the input to be `string | string[]`");if(r={pascalCase:!1,preserveConsecutiveUppercase:!1,...r},0===(e=Array.isArray(e)?e.map(e=>e.trim()).filter(e=>e.length).join("-"):e.trim()).length)return"";let t=!1===r.locale?e=>e.toLowerCase():e=>e.toLocaleLowerCase(r.locale),n=!1===r.locale?e=>e.toUpperCase():e=>e.toLocaleUpperCase(r.locale);if(1===e.length)return m.test(e)?"":r.pascalCase?n(e):t(e);let s=e!==t(e);return s&&(e=preserveCamelCase(e,t,n,r.preserveConsecutiveUppercase)),e=e.replace(f,""),e=r.preserveConsecutiveUppercase?preserveConsecutiveUppercase(e,t):t(e),r.pascalCase&&(e=n(e.charAt(0))+e.slice(1)),postProcess(e,n)}(s),r.module=v[r.moduleName],null==r.module&&(r.state={error:"Module ".concat(r.moduleName," not found. Check components/Quiz/quiz-list")}),r}
1return(0,s.Z)(QuizLoader,[{key:"componentDidCatch",value:function(e){console.error(e),this.setState({error:e.message})}},{key:"injected",get:function(){return this.props}},{key:"renderError",value:function(){var e=this.state.error;return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsx)("p",{children:"ÐÑибка загÑÑзки модÑлÑ:"}),(0,F.jsx)("pre",{children:e})]})}},{key:"renderQuiz",value:function(){var e=this.injected.app.getByName(this.moduleName);return(0,F.jsx)(A,{name:this.moduleName,quizModel:e,question:this.module.question,variants:this.module.variants})}},{key:"render",value:function(){var e=this.state.error,r=this.injected.app.getByName(this.moduleName);return e?this.renderError():r?this.renderQuiz():null}}]),QuizLoader}(y.Component),S=(0,j.f3)("app")((0,j.Pi)(D))},2042:function(e,r,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/ocp/patterns",function(){return t(7062)}])}},function(e){e.O(0,[374,214,774,888,179],function(){return e(e.s=2042)}),_N_E=e.O()}]); 2//# sourceMappingURL=patterns-8fe941c575e50cb8.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.