From 3a28caed27ed57654133dfdecedf3f2c4bf7341b Mon Sep 17 00:00:00 2001
From: Dvurechensky <46356631+Dvurechensky@users.noreply.github.com>
Date: Sat, 5 Oct 2024 09:15:54 +0300
Subject: [PATCH] 1.0
Main
---
.gitattributes | 63 +++
.gitignore | 3 +
LICENSE | 121 ++++++
.../1_Принцип единственной обязанности.csproj | 11 +
.../Program.cs | 71 +++
.../2_Принцип открытости, закрытости.csproj | 11 +
.../Program.cs | 55 +++
.../3_Принцип подстановки Барбары Лисков.csproj | 11 +
.../Program.cs | 127 ++++++
.../4_Принцип разделения интерфейсов.csproj | 11 +
.../Program.cs | 48 ++
.../5_Принцип инверсии зависимостей.csproj | 11 +
.../Program.cs | 107 +++++
.../AbstractFactory/AbstractFactory.csproj | 10 +
Patterns/AbstractFactory/Program.cs | 148 +++++++
Patterns/Adapter/Adapter.csproj | 10 +
Patterns/Adapter/Program.cs | 78 ++++
.../Base.UserLibrary.Tests.csproj | 19 +
Patterns/Base.UserLibrary.Tests/TestData.xml | 6 +
Patterns/Base.UserLibrary.Tests/UnitTest1.cs | 31 ++
Patterns/Base.UserLibrary.Tests/Usings.cs | 1 +
Patterns/Base.cs | 28 ++
Patterns/Base/AssertMsTest.cs | 26 ++
Patterns/Base/BaseInfo.csproj | 14 +
Patterns/Base/Extension.cs | 17 +
Patterns/Base/Program.cs | 410 ++++++++++++++++++
Patterns/BaseTests/000_TestsMain.cs | 31 ++
Patterns/BaseTests/001_TestInitAndCleanUp.cs | 38 ++
Patterns/BaseTests/002_ClassInitAndCleanUp.cs | 41 ++
Patterns/BaseTests/003_AssemblyInit.cs | 26 ++
Patterns/BaseTests/004_AssertMethods.cs | 65 +++
.../BaseTests/005_CollectionAssertMethods.cs | 65 +++
Patterns/BaseTests/006_StringAssetMethods.cs | 44 ++
Patterns/BaseTests/007_ExpectingExceptions.cs | 27 ++
Patterns/BaseTests/Base.Tests.csproj | 22 +
Patterns/BaseTests/Usings.cs | 1 +
Patterns/Bridge/Bridge.csproj | 10 +
Patterns/Bridge/Program.cs | 96 ++++
Patterns/Builder/Builder.csproj | 10 +
Patterns/Builder/Program.cs | 120 +++++
.../ChainOfResponsibility.csproj | 10 +
Patterns/ChainOfResponsibility/Program.cs | 165 +++++++
Patterns/Command/Command.csproj | 10 +
Patterns/Command/Program.cs | 225 ++++++++++
Patterns/Composite/Composite.csproj | 10 +
Patterns/Composite/Program.cs | 129 ++++++
Patterns/Decorator/Decorator.csproj | 10 +
Patterns/Decorator/Program.cs | 62 +++
Patterns/Dict/DictionaryInfo.csproj | 10 +
Patterns/Dict/Program.cs | 116 +++++
Patterns/Facade/Facade.csproj | 10 +
Patterns/Facade/Program.cs | 55 +++
Patterns/FactoryMethod/FactoryMethod.csproj | 10 +
Patterns/FactoryMethod/Program.cs | 120 +++++
Patterns/FluentBuilder/FluentBuilder.csproj | 10 +
Patterns/FluentBuilder/Program.cs | 68 +++
Patterns/Flyweight/Flyweight.csproj | 10 +
Patterns/Flyweight/Program.cs | 97 +++++
Patterns/Interpreter/Interpreter.csproj | 10 +
Patterns/Interpreter/Program.cs | 148 +++++++
Patterns/Iterator/Iterator.csproj | 10 +
Patterns/Iterator/Program.cs | 263 +++++++++++
Patterns/LetCode.Tests/LetCode.Tests.csproj | 23 +
Patterns/LetCode.Tests/Tests.cs | 65 +++
Patterns/LetCode.Tests/Usings.cs | 1 +
Patterns/LetCode/LetCode.csproj | 10 +
Patterns/LetCode/Program.cs | 160 +++++++
Patterns/Mediator/Mediator.csproj | 10 +
Patterns/Mediator/Program.cs | 112 +++++
Patterns/Memento/Memento.csproj | 10 +
Patterns/Memento/Program.cs | 119 +++++
Patterns/Observer/Observer.csproj | 10 +
Patterns/Observer/Program.cs | 103 +++++
Patterns/Patterns Programming.sln | 269 ++++++++++++
Patterns/Prototype/Program.cs | 132 ++++++
Patterns/Prototype/Prototype.csproj | 10 +
Patterns/Proxy/Program.cs | 94 ++++
Patterns/Proxy/Proxy.csproj | 14 +
Patterns/Singleton/Program.cs | 44 ++
Patterns/Singleton/Singleton.csproj | 10 +
Patterns/State/Program.cs | 76 ++++
Patterns/State/State.csproj | 10 +
Patterns/Strategy/ILogReader.cs | 6 +
Patterns/Strategy/LogEntry.cs | 15 +
Patterns/Strategy/LogFileReader.cs | 17 +
Patterns/Strategy/LogProcessor.cs | 21 +
Patterns/Strategy/Program.cs | 218 ++++++++++
Patterns/Strategy/Strategy.csproj | 10 +
Patterns/Strategy/WindowsEventLogReader.cs | 17 +
Patterns/TemplateMethod/Program.cs | 115 +++++
Patterns/TemplateMethod/TemplateMethod.csproj | 10 +
Patterns/Visitor/Program.cs | 138 ++++++
Patterns/Visitor/Visitor.csproj | 10 +
README.md | 156 +++++++
94 files changed, 5617 insertions(+)
create mode 100644 .gitattributes
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 Patterns/1_Принцип единственной обязанности/1_Принцип единственной обязанности.csproj
create mode 100644 Patterns/1_Принцип единственной обязанности/Program.cs
create mode 100644 Patterns/2_Принцип открытости, закрытости/2_Принцип открытости, закрытости.csproj
create mode 100644 Patterns/2_Принцип открытости, закрытости/Program.cs
create mode 100644 Patterns/3_Принцип подстановки Барбары Лисков/3_Принцип подстановки Барбары Лисков.csproj
create mode 100644 Patterns/3_Принцип подстановки Барбары Лисков/Program.cs
create mode 100644 Patterns/4_Принцип разделения интерфейсов/4_Принцип разделения интерфейсов.csproj
create mode 100644 Patterns/4_Принцип разделения интерфейсов/Program.cs
create mode 100644 Patterns/5_Принцип инверсии зависимостей/5_Принцип инверсии зависимостей.csproj
create mode 100644 Patterns/5_Принцип инверсии зависимостей/Program.cs
create mode 100644 Patterns/AbstractFactory/AbstractFactory.csproj
create mode 100644 Patterns/AbstractFactory/Program.cs
create mode 100644 Patterns/Adapter/Adapter.csproj
create mode 100644 Patterns/Adapter/Program.cs
create mode 100644 Patterns/Base.UserLibrary.Tests/Base.UserLibrary.Tests.csproj
create mode 100644 Patterns/Base.UserLibrary.Tests/TestData.xml
create mode 100644 Patterns/Base.UserLibrary.Tests/UnitTest1.cs
create mode 100644 Patterns/Base.UserLibrary.Tests/Usings.cs
create mode 100644 Patterns/Base.cs
create mode 100644 Patterns/Base/AssertMsTest.cs
create mode 100644 Patterns/Base/BaseInfo.csproj
create mode 100644 Patterns/Base/Extension.cs
create mode 100644 Patterns/Base/Program.cs
create mode 100644 Patterns/BaseTests/000_TestsMain.cs
create mode 100644 Patterns/BaseTests/001_TestInitAndCleanUp.cs
create mode 100644 Patterns/BaseTests/002_ClassInitAndCleanUp.cs
create mode 100644 Patterns/BaseTests/003_AssemblyInit.cs
create mode 100644 Patterns/BaseTests/004_AssertMethods.cs
create mode 100644 Patterns/BaseTests/005_CollectionAssertMethods.cs
create mode 100644 Patterns/BaseTests/006_StringAssetMethods.cs
create mode 100644 Patterns/BaseTests/007_ExpectingExceptions.cs
create mode 100644 Patterns/BaseTests/Base.Tests.csproj
create mode 100644 Patterns/BaseTests/Usings.cs
create mode 100644 Patterns/Bridge/Bridge.csproj
create mode 100644 Patterns/Bridge/Program.cs
create mode 100644 Patterns/Builder/Builder.csproj
create mode 100644 Patterns/Builder/Program.cs
create mode 100644 Patterns/ChainOfResponsibility/ChainOfResponsibility.csproj
create mode 100644 Patterns/ChainOfResponsibility/Program.cs
create mode 100644 Patterns/Command/Command.csproj
create mode 100644 Patterns/Command/Program.cs
create mode 100644 Patterns/Composite/Composite.csproj
create mode 100644 Patterns/Composite/Program.cs
create mode 100644 Patterns/Decorator/Decorator.csproj
create mode 100644 Patterns/Decorator/Program.cs
create mode 100644 Patterns/Dict/DictionaryInfo.csproj
create mode 100644 Patterns/Dict/Program.cs
create mode 100644 Patterns/Facade/Facade.csproj
create mode 100644 Patterns/Facade/Program.cs
create mode 100644 Patterns/FactoryMethod/FactoryMethod.csproj
create mode 100644 Patterns/FactoryMethod/Program.cs
create mode 100644 Patterns/FluentBuilder/FluentBuilder.csproj
create mode 100644 Patterns/FluentBuilder/Program.cs
create mode 100644 Patterns/Flyweight/Flyweight.csproj
create mode 100644 Patterns/Flyweight/Program.cs
create mode 100644 Patterns/Interpreter/Interpreter.csproj
create mode 100644 Patterns/Interpreter/Program.cs
create mode 100644 Patterns/Iterator/Iterator.csproj
create mode 100644 Patterns/Iterator/Program.cs
create mode 100644 Patterns/LetCode.Tests/LetCode.Tests.csproj
create mode 100644 Patterns/LetCode.Tests/Tests.cs
create mode 100644 Patterns/LetCode.Tests/Usings.cs
create mode 100644 Patterns/LetCode/LetCode.csproj
create mode 100644 Patterns/LetCode/Program.cs
create mode 100644 Patterns/Mediator/Mediator.csproj
create mode 100644 Patterns/Mediator/Program.cs
create mode 100644 Patterns/Memento/Memento.csproj
create mode 100644 Patterns/Memento/Program.cs
create mode 100644 Patterns/Observer/Observer.csproj
create mode 100644 Patterns/Observer/Program.cs
create mode 100644 Patterns/Patterns Programming.sln
create mode 100644 Patterns/Prototype/Program.cs
create mode 100644 Patterns/Prototype/Prototype.csproj
create mode 100644 Patterns/Proxy/Program.cs
create mode 100644 Patterns/Proxy/Proxy.csproj
create mode 100644 Patterns/Singleton/Program.cs
create mode 100644 Patterns/Singleton/Singleton.csproj
create mode 100644 Patterns/State/Program.cs
create mode 100644 Patterns/State/State.csproj
create mode 100644 Patterns/Strategy/ILogReader.cs
create mode 100644 Patterns/Strategy/LogEntry.cs
create mode 100644 Patterns/Strategy/LogFileReader.cs
create mode 100644 Patterns/Strategy/LogProcessor.cs
create mode 100644 Patterns/Strategy/Program.cs
create mode 100644 Patterns/Strategy/Strategy.csproj
create mode 100644 Patterns/Strategy/WindowsEventLogReader.cs
create mode 100644 Patterns/TemplateMethod/Program.cs
create mode 100644 Patterns/TemplateMethod/TemplateMethod.csproj
create mode 100644 Patterns/Visitor/Program.cs
create mode 100644 Patterns/Visitor/Visitor.csproj
create mode 100644 README.md
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c8b1dde
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.vs
+Patterns/bin
+Patterns/obj
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0e259d4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/Patterns/1_Принцип единственной обязанности/1_Принцип единственной обязанности.csproj b/Patterns/1_Принцип единственной обязанности/1_Принцип единственной обязанности.csproj
new file mode 100644
index 0000000..af348a6
--- /dev/null
+++ b/Patterns/1_Принцип единственной обязанности/1_Принцип единственной обязанности.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net6.0
+ _1_Принцип_единственной_обязанности
+ enable
+ enable
+
+
+
diff --git a/Patterns/1_Принцип единственной обязанности/Program.cs b/Patterns/1_Принцип единственной обязанности/Program.cs
new file mode 100644
index 0000000..5d3351f
--- /dev/null
+++ b/Patterns/1_Принцип единственной обязанности/Program.cs
@@ -0,0 +1,71 @@
+/*
+ * Глава 17: Принцип единственной обязанности (SOLID SRP)
+ *
+ * - инкапсуляция сущности с целью организации архитектуры
+ * приложения, которую будет легко поддерживать и расширять в
+ * течении всего промежутка эксплуатации
+ *
+ * Автор: Роберт Мартин (Дядя Боб)
+ *
+ * Принципы:
+ * 1. Single responsibility - принцип единственной ответственности
+ * 2. Open-closed - принцип открытости/закрытости
+ * 3. Liskov substitution - принцип подстановки Барбары Лисков (самый сложный)
+ * 4. Interface Segregation - принцип разделения интерфейса
+ * 5. Dependency inversion - принцип инверсии зависисмостей
+ */
+
+
+/*
+ * Принцип единственной ответственности (англ. single-responsibility principle, SPR) -
+ * принцип ООП, обозначающий, что каждый объект должен иметь одну ответственность и эта
+ * ответственность должна быть полностью инкапсулирована в класс.
+ * Все его поведения должны быть направлены исключительно на обеспечение этой отвественности.
+ */
+///
+/// К примеру: Разработать класс который будет работать с изображениями
+///
+abstract class Attach
+{
+
+}
+
+class Image : Attach
+{
+ private int width;
+ private int height;
+ public int Width => width;
+ public int Height => height;
+ private Image(int width, int height) { }
+ //Добавление других методов предполагающих иной функционал не рационально
+ //Следуем принципу - декомпозировать - делать максимально минимальные классы под свою ответственность
+ public static Image CreateImage(int width, int height) { return new Image(width, height); }
+}
+
+///
+/// EMail сервис
+/// Если отваливается модуль отправки Email
+/// мы чиним только его, нам не требуется разбирать класс Image
+///
+class EmailService
+{
+ private string email;
+ private string text;
+ private string subject;
+ private Attach[] attach;
+ public EmailService(string email,
+ string text = "",
+ string subject = "",
+ params Attach[] args)
+ { }
+ public void SendTo(string email, string text, string subject) { }
+}
+
+
+class Program
+{
+ public static void Main(string[] argv)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Patterns/2_Принцип открытости, закрытости/2_Принцип открытости, закрытости.csproj b/Patterns/2_Принцип открытости, закрытости/2_Принцип открытости, закрытости.csproj
new file mode 100644
index 0000000..88bb7f1
--- /dev/null
+++ b/Patterns/2_Принцип открытости, закрытости/2_Принцип открытости, закрытости.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net6.0
+ _2_Принцип_открытости__закрытости
+ enable
+ enable
+
+
+
diff --git a/Patterns/2_Принцип открытости, закрытости/Program.cs b/Patterns/2_Принцип открытости, закрытости/Program.cs
new file mode 100644
index 0000000..2473e68
--- /dev/null
+++ b/Patterns/2_Принцип открытости, закрытости/Program.cs
@@ -0,0 +1,55 @@
+/*
+ * Глава 18: Принцип открытости/закрытости (SOLID SRP)
+ *
+ * Автор: Роберт Мартин (Дядя Боб)
+ *
+ * Постулаты:
+ * - если какая-то сущность описана, то она уже
+ * полностью закрыта для каких либо изменений;
+ * - сущность открыта для модификаций;
+ *
+ * Принципы:
+ * 1. Single responsibility - принцип единственной ответственности
+ * 2. Open-closed - принцип открытости/закрытости
+ * 3. Liskov substitution - принцип подстановки Барбары Лисков (самый сложный)
+ * 4. Interface Segregation - принцип разделения интерфейса
+ * 5. Dependency inversion - принцип инверсии зависисмостей
+ */
+public abstract class Attach
+{
+
+}
+
+public class Image : Attach
+{
+ private int width;
+ private int height;
+ public int Width => width;
+ public int Height => height;
+ private Image(int width, int height) { }
+ private Image(int width, int height, ISave save) { }
+ public static Image CreateImage(int width, int height) { return new Image(width, height); }
+ public static Image CreateImage(int width, int height, ISave save) { return new Image(width, height, save); }
+ public void SaveToFile(string path) { }
+}
+
+public interface ISave
+{
+ ISave SaveTo(string path);
+}
+
+public class SaveToBmp : ISave
+{
+ public ISave SaveTo(string path)
+ {
+ return this;
+ }
+}
+
+public class Program
+{
+ public static void Main(string[] argv)
+ {
+ Image.CreateImage(100, 100, new SaveToBmp().SaveTo(""));
+ }
+}
\ No newline at end of file
diff --git a/Patterns/3_Принцип подстановки Барбары Лисков/3_Принцип подстановки Барбары Лисков.csproj b/Patterns/3_Принцип подстановки Барбары Лисков/3_Принцип подстановки Барбары Лисков.csproj
new file mode 100644
index 0000000..38b1041
--- /dev/null
+++ b/Patterns/3_Принцип подстановки Барбары Лисков/3_Принцип подстановки Барбары Лисков.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net6.0
+ _3_Принцип_подстановки_Барбары_Лисков
+ enable
+ enable
+
+
+
diff --git a/Patterns/3_Принцип подстановки Барбары Лисков/Program.cs b/Patterns/3_Принцип подстановки Барбары Лисков/Program.cs
new file mode 100644
index 0000000..dc4c4b3
--- /dev/null
+++ b/Patterns/3_Принцип подстановки Барбары Лисков/Program.cs
@@ -0,0 +1,127 @@
+/*
+ * Глава 19: Принцип подстановки Барбары Лисков (SOLID SRP)
+ *
+ * Автор: Роберт Мартин (Дядя Боб)
+ *
+ * Сам принцип:
+ * - Пусть Q(x) является свойством, верным относительно объектов x некоторого
+ * типа T. Тогда Q(y) также должно быть верным для объектов y типа S, где S является подтипом T.
+ *
+ * или
+ *
+ * - Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.
+ * Поведение классов-наследников не должно противоречить поведению, заданному базовым классом
+ *
+ * Принципы:
+ * 1. Single responsibility - принцип единственной ответственности
+ * 2. Open-closed - принцип открытости/закрытости
+ * 3. Liskov substitution - принцип подстановки Барбары Лисков (самый сложный)
+ * 4. Interface Segregation - принцип разделения интерфейса
+ * 5. Dependency inversion - принцип инверсии зависисмостей
+ */
+
+public class Coordinates
+{
+ public int Longtitude { get; set; }
+ public int Latitude { get; set; }
+ public override string ToString()
+ {
+ return $"Широта: {Longtitude} Долгота: {Latitude}";
+ }
+}
+
+///
+/// Шаблон летающей птицы
+///
+public class Bird
+{
+ protected Random rand;
+ public Coordinates Position { get; set; }
+ protected int speed, spacing;
+ public int Spacing { get => spacing; }
+
+ public Bird()
+ {
+ Position = new Coordinates();
+ rand = new Random();
+ }
+
+ protected void Mark(int x, int y) { }
+
+ ///
+ /// Полёт птицы
+ ///
+ private void Fly()
+ {
+ speed = 1;
+ switch (rand.Next(2))
+ {
+ case 0: Position.Latitude += speed; break;
+ default: Position.Longtitude += speed; break;
+ }
+ spacing++;
+ Console.SetCursorPosition(Position.Latitude, Position.Longtitude);
+ Console.WriteLine("B");
+ }
+
+ ///
+ /// Движение птицы
+ ///
+ public virtual void Move()
+ {
+ Fly();
+ }
+}
+
+///
+/// Шаблон бегущей птицы
+///
+public class Kiwi : Bird
+{
+ private void Run()
+ {
+ speed = 1;
+ switch (rand.Next(2, 6))
+ {
+ case 3: Position.Latitude += speed; break;
+ default: Position.Longtitude += speed; break;
+ }
+ spacing++;
+ Console.SetCursorPosition(Position.Latitude, Position.Longtitude);
+ Console.WriteLine("K");
+ }
+
+ public override void Move()
+ {
+ Run();
+ }
+}
+
+///
+/// Шаблон отображеня движения
+///
+class CalculatingDistance
+{
+ private int time;
+ public CalculatingDistance(int time) { this.time = time; }
+ public void Calculate(Bird bird)
+ {
+ for (int i = 0; i < time; i++)
+ {
+ bird.Move();
+ }
+ Console.Title = ($"\n\n\nРасстояние: {bird.Spacing} {bird.Position}");
+ }
+}
+
+public class Program
+{
+ public static void Main(string[] argv)
+ {
+ var bird = new Bird();
+ new CalculatingDistance(10).Calculate(bird);
+ var kiwi = new Kiwi();
+ new CalculatingDistance(10).Calculate(kiwi);
+ Console.ReadLine();
+ }
+}
\ No newline at end of file
diff --git a/Patterns/4_Принцип разделения интерфейсов/4_Принцип разделения интерфейсов.csproj b/Patterns/4_Принцип разделения интерфейсов/4_Принцип разделения интерфейсов.csproj
new file mode 100644
index 0000000..b76962e
--- /dev/null
+++ b/Patterns/4_Принцип разделения интерфейсов/4_Принцип разделения интерфейсов.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net6.0
+ _4_Принцип_разделения_интерфейсов
+ enable
+ enable
+
+
+
diff --git a/Patterns/4_Принцип разделения интерфейсов/Program.cs b/Patterns/4_Принцип разделения интерфейсов/Program.cs
new file mode 100644
index 0000000..5197c56
--- /dev/null
+++ b/Patterns/4_Принцип разделения интерфейсов/Program.cs
@@ -0,0 +1,48 @@
+/*
+ * Глава 20: Принцип разделения интерфейсов (SOLID SRP)
+ *
+ * Автор: Роберт Мартин (Дядя Боб)
+ *
+ * Сам принцип:
+ * - клиенты не должны зависеть от методов которые они не используют
+ *
+ * или
+ *
+ * - если какая-то сущность заявляет о своем функционале, то он должен работать
+ *
+ * или
+ *
+ * - от реализации исбыточных интерфейсов следует отказаться в пользу специфичных
+ *
+ * Принципы:
+ * 1. Single responsibility - принцип единственной ответственности
+ * 2. Open-closed - принцип открытости/закрытости
+ * 3. Liskov substitution - принцип подстановки Барбары Лисков (самый сложный)
+ * 4. Interface Segregation - принцип разделения интерфейса
+ * 5. Dependency inversion - принцип инверсии зависисмостей
+ */
+public abstract class Car
+{
+ public string Model { get; set; }
+ public string Brand { get; set; }
+
+ public Car(string model, string name)
+ {
+ Model = model;
+ Brand = name;
+ }
+}
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//!!! вместо огромного набора функций в одном интерфейсе !!!
+//!!! в случае если при наследовании от него множество функций не реализуется !!!
+//!!! нужно перейти в сторону множественного наследования интерфейсов под каждую из функций !!!
+//!!! или под каждый набор функций !!!
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+public class Program
+{
+ public static void Main(string[] argv)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Patterns/5_Принцип инверсии зависимостей/5_Принцип инверсии зависимостей.csproj b/Patterns/5_Принцип инверсии зависимостей/5_Принцип инверсии зависимостей.csproj
new file mode 100644
index 0000000..a1b8871
--- /dev/null
+++ b/Patterns/5_Принцип инверсии зависимостей/5_Принцип инверсии зависимостей.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Exe
+ net6.0
+ _5_Принцип_инверсии_зависимостей
+ enable
+ enable
+
+
+
diff --git a/Patterns/5_Принцип инверсии зависимостей/Program.cs b/Patterns/5_Принцип инверсии зависимостей/Program.cs
new file mode 100644
index 0000000..637bb36
--- /dev/null
+++ b/Patterns/5_Принцип инверсии зависимостей/Program.cs
@@ -0,0 +1,107 @@
+/*
+ * Глава 21: Принцип инверсии зависимостей (SOLID SRP)
+ *
+ * Автор: Роберт Мартин (Дядя Боб)
+ *
+ * Сам принцип:
+ *
+ * - Модули верхних уровней не должны зависеть от модулей нижних уровней
+ * (Оба типа должны зависеть от абстракций)
+ *
+ * - Абстракции не должны зависеть от деталей
+ * (Детали должны зависеть от абстракций)
+ *
+ * Принципы:
+ * 1. Single responsibility - принцип единственной ответственности
+ * 2. Open-closed - принцип открытости/закрытости
+ * 3. Liskov substitution - принцип подстановки Барбары Лисков (самый сложный)
+ * 4. Interface Segregation - принцип разделения интерфейса
+ * 5. Dependency inversion - принцип инверсии зависисмостей
+ */
+public class Person
+{
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public int Age { get; set; }
+}
+
+///
+/// Поведение поиска в хранилищах информации
+///
+public interface IFindStorage
+{
+ List FindAll(Predicate predicate);
+}
+
+///
+/// Шаблон списка пользователей
+///
+public class ListStorage : IFindStorage
+{
+ private List storage;
+ public ListStorage()
+ {
+ storage = new List();
+ }
+
+ public List GetPersons() => storage;
+
+ public void Add(Person p) => storage.Add(p);
+
+ public List FindAll(Predicate predicate)
+ {
+ return storage.Where(e => predicate(e)).ToList();
+ }
+}
+
+///
+/// Шаблон словаря пользователей
+///
+public class DictionaryStorage : IFindStorage
+{
+ private Dictionary storage;
+ public DictionaryStorage()
+ {
+ storage = new Dictionary();
+ }
+
+ public Dictionary GetPersons() => storage;
+
+ public void Add(string key, Person p) => storage.Add(key, p);
+
+ public List FindAll(Predicate predicate)
+ {
+ return storage.Where(e => predicate(e.Value)).Select(e => e.Value).ToList();
+ }
+}
+
+///
+/// Щаблон поисковика
+///
+public class SearchByAge
+{
+ IFindStorage storage;
+ public SearchByAge(IFindStorage storage) => this.storage = storage;
+ public void Search()
+ {
+ foreach (var p in storage.FindAll(e => e.Age > 45))
+ {
+ Console.WriteLine($"{p.FirstName} {p.Age}");
+ }
+ }
+}
+
+public class Program
+{
+ public static void Main(string[] argv)
+ {
+ Console.WriteLine("DictionaryStorage: ");
+ var storageDict = new DictionaryStorage();
+ storageDict.Add("1", new Person() { Age = 90 });
+ new SearchByAge(storageDict).Search();
+ Console.WriteLine("ListStorage: ");
+ var storageList = new ListStorage();
+ storageList.Add(new Person() { Age = 43 });
+ new SearchByAge(storageList).Search();
+ }
+}
\ No newline at end of file
diff --git a/Patterns/AbstractFactory/AbstractFactory.csproj b/Patterns/AbstractFactory/AbstractFactory.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/AbstractFactory/AbstractFactory.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/AbstractFactory/Program.cs b/Patterns/AbstractFactory/Program.cs
new file mode 100644
index 0000000..88ff2a2
--- /dev/null
+++ b/Patterns/AbstractFactory/Program.cs
@@ -0,0 +1,148 @@
+/* Абстрактная фабрика
+ Предоставляет интерфейс для создания
+ групп связанных или зависимых объектов,
+ не указывая их конкретный класс
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var soldier = new Hero(new SoldierFactory());
+ soldier.Run();
+ soldier.Hit();
+
+ var elf = new Hero(new ElfFactory());
+ elf.Run();
+ elf.Hit();
+
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Оружие базовая логика
+///
+abstract class Weapon
+{
+ public abstract void Hit();
+}
+
+///
+/// Движение базовая логика
+///
+abstract class Movement
+{
+ public abstract void Move();
+}
+
+///
+/// Огнестрел
+///
+class Gun : Weapon
+{
+ public override void Hit()
+ {
+ Console.WriteLine("Hit Gun");
+ }
+}
+
+///
+/// Арбалет
+///
+class Arbalet : Weapon
+{
+ public override void Hit()
+ {
+ Console.WriteLine("Hit Arbalet");
+ }
+}
+
+///
+/// Герой летает
+///
+class Fly : Movement
+{
+ public override void Move()
+ {
+ Console.WriteLine("Hero Fly");
+ }
+}
+
+///
+/// Герой бежит
+///
+class Run : Movement
+{
+ public override void Move()
+ {
+ Console.WriteLine("Hero Run");
+ }
+}
+
+///
+/// Супергерой
+///
+class Hero
+{
+ private Weapon Weapon { get; set; }
+ private Movement Movement { get; set; }
+
+ public Hero(HeroFactory factory)
+ {
+ Weapon = factory.CreateWeapon();
+ Movement = factory.CreateMovement();
+ }
+
+ public void Run()
+ {
+ Movement.Move();
+ }
+
+ public void Hit()
+ {
+ Weapon.Hit();
+ }
+}
+
+///
+/// Абстракция фабрика героев
+///
+abstract class HeroFactory
+{
+ public abstract Weapon CreateWeapon();
+ public abstract Movement CreateMovement();
+}
+
+///
+/// Эльфы
+///
+class ElfFactory : HeroFactory
+{
+ public override Movement CreateMovement()
+ {
+ return new Fly();
+ }
+
+ public override Weapon CreateWeapon()
+ {
+ return new Arbalet();
+ }
+}
+
+///
+/// Солдаты
+///
+class SoldierFactory : HeroFactory
+{
+ public override Movement CreateMovement()
+ {
+ return new Run();
+ }
+
+ public override Weapon CreateWeapon()
+ {
+ return new Gun();
+ }
+}
diff --git a/Patterns/Adapter/Adapter.csproj b/Patterns/Adapter/Adapter.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Adapter/Adapter.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Adapter/Program.cs b/Patterns/Adapter/Program.cs
new file mode 100644
index 0000000..08e48d1
--- /dev/null
+++ b/Patterns/Adapter/Program.cs
@@ -0,0 +1,78 @@
+/* Адаптер
+ Конвенртирует интерфейс класса в другой интерфейс,
+ ожидаемый клиентом. Позволяет классам
+ с разными интерфейсами работать вместе.
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var man = new Driver();
+ var car = new Auto(); //машина она едет также как мотоцикл, всё отлично
+ var camelTransport = //но мы хотим добраться на пешем транспорте (на верблюде)
+ new CamelToTransport(new Camel());
+
+ man.Travel(camelTransport);
+ man.Travel(car);
+
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+interface ITransport
+{
+ void Drive();
+}
+
+///
+/// Шаблон автомобиля
+///
+class Auto : ITransport
+{
+ public void Drive()
+ {
+ Console.WriteLine(GetType().Name + " Move");
+ }
+}
+
+///
+/// Шаблон верблюда
+///
+class Camel
+{
+ public void Move()
+ {
+ Console.WriteLine(GetType().Name + " Move");
+ }
+}
+
+///
+/// Шаблон движения верблюда
+///
+class CamelToTransport : ITransport
+{
+ Camel camel;
+
+ public CamelToTransport(Camel camel)
+ {
+ this.camel = camel;
+ }
+
+ public void Drive()
+ {
+ camel.Move();
+ }
+}
+
+///
+/// Шаблон путешественника
+///
+class Driver
+{
+ public void Travel(ITransport transport)
+ {
+ transport.Drive();
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Base.UserLibrary.Tests/Base.UserLibrary.Tests.csproj b/Patterns/Base.UserLibrary.Tests/Base.UserLibrary.Tests.csproj
new file mode 100644
index 0000000..ed22915
--- /dev/null
+++ b/Patterns/Base.UserLibrary.Tests/Base.UserLibrary.Tests.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/Patterns/Base.UserLibrary.Tests/TestData.xml b/Patterns/Base.UserLibrary.Tests/TestData.xml
new file mode 100644
index 0000000..7d39bc1
--- /dev/null
+++ b/Patterns/Base.UserLibrary.Tests/TestData.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Patterns/Base.UserLibrary.Tests/UnitTest1.cs b/Patterns/Base.UserLibrary.Tests/UnitTest1.cs
new file mode 100644
index 0000000..2b61bf2
--- /dev/null
+++ b/Patterns/Base.UserLibrary.Tests/UnitTest1.cs
@@ -0,0 +1,31 @@
+namespace Base.UserLibrary.Tests
+{
+ [TestClass]
+ public class UnitTest1
+ {
+ private TestContext testContextInstance;
+ public TestContext TestContextInstance
+ {
+ get { return testContextInstance; }
+ set { testContextInstance = value; }
+ }
+ private UserManagerMsTest manager = new UserManagerMsTest();
+
+ ///
+ /// DataSource -
+ /// 1 -
+ /// 2 -
+ /// 3 - XML
+ /// 4 -
+ ///
+ [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
+ "TestData.xml",
+ "User",
+ DataAccessMethod.Sequential)]
+ [TestMethod]
+ public void AddDataTest()
+ {
+ string userId = Convert.ToString(TestContextInstance.DataRow["Row1"]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Base.UserLibrary.Tests/Usings.cs b/Patterns/Base.UserLibrary.Tests/Usings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/Patterns/Base.UserLibrary.Tests/Usings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file
diff --git a/Patterns/Base.cs b/Patterns/Base.cs
new file mode 100644
index 0000000..d39fe33
--- /dev/null
+++ b/Patterns/Base.cs
@@ -0,0 +1,28 @@
+using System;
+
+public class Base
+
+
+//абстрактный класс
+abstract class AbstrTest
+{
+ void Move()
+ {
+
+ }
+
+ //реализация по умолчанию
+ public virtual void Resize()
+ {
+
+ }
+ void Declare();
+}
+
+public class Class_Main : AbstrTest
+{
+ public Class_Main()
+ {
+ Declare();
+ }
+}
diff --git a/Patterns/Base/AssertMsTest.cs b/Patterns/Base/AssertMsTest.cs
new file mode 100644
index 0000000..2d7c2dc
--- /dev/null
+++ b/Patterns/Base/AssertMsTest.cs
@@ -0,0 +1,26 @@
+namespace Base;
+
+public class AssertMsTest
+{
+ ///
+ /// Получить квадратный корень
+ ///
+ /// Значение
+ /// double
+ public static double GetSqrt(double value)
+ {
+ return Math.Sqrt(value);
+ }
+
+ ///
+ /// Получить приветствие
+ ///
+ /// Имя
+ ///
+ /// пустое имя
+ public string SayHello(string name)
+ {
+ if (name == null) throw new ArgumentNullException("Parameter name can not be null");
+ return "Hi! " + name;
+ }
+}
diff --git a/Patterns/Base/BaseInfo.csproj b/Patterns/Base/BaseInfo.csproj
new file mode 100644
index 0000000..7d211a9
--- /dev/null
+++ b/Patterns/Base/BaseInfo.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Patterns/Base/Extension.cs b/Patterns/Base/Extension.cs
new file mode 100644
index 0000000..5dabef8
--- /dev/null
+++ b/Patterns/Base/Extension.cs
@@ -0,0 +1,17 @@
+namespace Base
+{
+ ///
+ /// Тестовый класс статических реализаций
+ ///
+ internal static class Extension
+ {
+ ///
+ /// Тестовый статический метод
+ ///
+ /// Представитель определённого поведения
+ public static void ResizeExt(this IInterTest classMain)
+ {
+ Console.WriteLine("Resize Class Extension");
+ }
+ }
+}
diff --git a/Patterns/Base/Program.cs b/Patterns/Base/Program.cs
new file mode 100644
index 0000000..32aba57
--- /dev/null
+++ b/Patterns/Base/Program.cs
@@ -0,0 +1,410 @@
+using Newtonsoft.Json;
+using static Base.Records;
+
+namespace Base;
+
+///
+/// Важно: ссылочные типы лежат в куче, значимые - ссылка в куче, значение в стеке
+/// ***
+/// Шаблон, по которому определяется форма объекта
+/// Определение:
+/// Класс - это ссылочный тип данных, шаблон по которому определяется объект, информацию о себе хранит в куче.
+///
+class Program
+{
+ static void Main()
+ {
+ var person = new Person() //реализация record сборки разборки
+ {
+ Id = 1,
+ Name = "john"
+ };
+ Console.WriteLine(person.ToString());
+ var job = new Job()
+ {
+ Ida = 786897980,
+ Names = "Address"
+ };
+ Console.WriteLine(job.ToString());
+ var gl = new GlobalInfo();
+ person.Deconstruct(out gl.Name, out gl.Id);
+ job.Deconstruct(out gl.Names, out gl.Ida);
+ Console.WriteLine($"{gl.Name}/{gl.Names}/{gl.Id}/{gl.Ida}");
+
+ IInterTest interTest = new ClassMain();
+ interTest.ResizeExt(); //методы static
+ interTest.Relocate(); //метод объявлен и реализован в самом интерфейсе
+ var Records = new Records(1, "rec1"); //экзмепляр Records (аналог class)
+ var (NameS, idS) = Records; //можно разложить record на переменные
+ var RecNew = Records with { Name = "rec2" };//можно инициализировать другой класс на основе данных первого
+ Console.WriteLine($"{NameS} {idS}");
+ var (NameS2, idS2) = RecNew; //можно разложить record на переменные
+ Console.WriteLine($"{NameS2} {idS2}");
+ Console.WriteLine(Records == RecNew); //можно сравнить record обычными операторами сравнения
+ Console.WriteLine();
+ Console.WriteLine(RecNew); //можно напечать JSON представление содержимого record по умолчанию
+ Console.WriteLine(Records); //можно напечать JSON представление содержимого record по умолчанию
+ var json = JsonConvert.SerializeObject(Records, Formatting.Indented);
+ Console.WriteLine(json);
+ var otherSideRecord = JsonConvert.DeserializeObject(json);
+ Console.WriteLine(otherSideRecord);
+ Records = Records with { Id = 10 };
+ Console.WriteLine(Records);
+ Console.ReadKey();
+ }
+}
+
+
+///
+/// Абстракция которая отвечает за контракт взаимодействия для различных типов
+/// Определение:
+/// Интерфейс - это ссылочный тип данных, представляющий контракт взаимодействия (поведение).
+/// Этот контракт гласит о том что должен содержать class или struct.
+/// Формирует общий признак для разнородных объектов
+///
+public interface IInterTest
+{
+ ///
+ /// Декларация - метод без реализации по умолчанию
+ ///
+ ///
+ void Build(int build = 0);
+ ///
+ /// После C# 8.0 можно указывать реализацию метода в интерфейсе
+ ///
+ void Relocate()
+ {
+ Console.WriteLine("-> IInterTest: Relocate");
+ }
+ ///
+ /// Cигнатура - операция без реализации - абстрактный метод
+ ///
+ abstract void Reload();
+ ///
+ /// Делегат - ссылочный тип
+ ///
+ delegate void Destiny();
+ ///
+ /// Cвойство - ссылочный тип
+ ///
+ string Name { get; set; }
+ ///
+ /// Cвойство - ссылочный тип
+ ///
+ object ID { get; set; }
+
+}
+
+///
+/// Абстрактный класс
+/// Определение:
+/// Абстрактный класс - это ссылочный тип данных, для описания общности сущностей, которые не имеют конкретного воплощения
+///
+public abstract class AbstrTest
+{
+ ///
+ /// Поле
+ ///
+ public int key = 100;
+ ///
+ /// Свойство
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Конструктор без параметров
+ ///
+ public AbstrTest()
+ {
+ key = 110;
+ Name = "Fire";
+ Console.WriteLine($"->AbstrTest {Name} {key}");
+ }
+
+ ///
+ /// Конструктор с параметрами
+ ///
+ /// ключ
+ public AbstrTest(int key)
+ {
+ this.key = key;
+ Name = "Fire";
+ Console.WriteLine($"->AbstrTest {Name} {key}");
+ }
+
+ ///
+ /// Метод - это фиксированная операция с реализацией по умолчанию
+ ///
+ public void Move()
+ {
+ Console.WriteLine("Move Abstr");
+ }
+
+ ///
+ /// Виртуальный метод - операция с реализацией по умолчанию
+ ///
+ public virtual void Resize()
+ {
+ Console.WriteLine("Resize Abstr");
+ }
+
+ ///
+ /// Абстрактный метод - сигнатура - операция без реализации
+ ///
+ public abstract void Open();
+}
+
+///
+/// Определение:
+/// Структура - это значимый тип данных, ссылка на структуру хранится в куче, значение в стеке
+/// Тот же класс, меняется тип данных
+///
+public struct TestStruct : IInterTest
+{
+ ///
+ /// Свойство имени
+ ///
+ public string Name { get; set; }
+ ///
+ /// Свойство идентификатора
+ ///
+ public object ID { get; set; }
+
+ ///
+ /// Конструктор без параметров
+ ///
+ public TestStruct()
+ {
+ Name = "Base";
+ ID = (object)0;
+ }
+
+ ///
+ /// Метод с реализацией с параметрами
+ ///
+ /// #
+ public void Build(int build = 0)
+ {
+ Console.WriteLine($"Build TestStruct {build}");
+ }
+
+ ///
+ /// Метод с реализацией без параметров
+ ///
+ public void Reload()
+ {
+ Console.WriteLine("Reload TestStruct");
+ }
+}
+
+///
+/// Реализация поведения класса
+///
+public class ClassMain : AbstrTest, IInterTest
+{
+ ///
+ /// Свойство
+ ///
+ public int countBuild { get; set; }
+ ///
+ /// Свойство от интерфейса
+ ///
+ public string Name { get; set; }
+ ///
+ /// Свойство от интерфейса
+ ///
+ public object ID { get; set; }
+
+ ///
+ /// Конструтор + реализация поведения конструктора абстрактного класса
+ ///
+ public ClassMain() : base (0)
+ {
+ TestStruct testStruct = new TestStruct();
+ Console.WriteLine($"TestStruct: {testStruct.Name}, {testStruct.ID}");
+ Name = "Base";
+ ID = (object)0;
+ Move();
+ Build();
+ Reload();
+ Resize();
+ Open();
+ }
+
+ ///
+ /// Конструтор c параметрами + реализация поведения конструктора абстрактного класса
+ ///
+ /// #
+ /// #
+ /// #
+ public ClassMain(int build, string name, object id) : base(build)
+ {
+ countBuild = build;
+ Name = name;
+ ID = id;
+ Move();
+ Build(build);
+ Reload();
+ Resize();
+ Open();
+ }
+
+ ///
+ /// Виртуальный метод
+ ///
+ public virtual void GG()
+ {
+ Console.WriteLine("GG Virtual Method Class");
+ }
+
+ ///
+ /// Метод с параметрами
+ ///
+ /// #
+ public void Build(int build = 0)
+ {
+ Console.WriteLine($"Build Interface Class {build}");
+ }
+
+ ///
+ /// Метод без параметров обязательный к реализации от интерфейса
+ ///
+ public void Reload()
+ {
+ Console.WriteLine("Reload Interface Abstract Method Class");
+ }
+
+ ///
+ /// Реализация virtual метода абстрактного класса
+ ///
+ public override void Resize()
+ {
+ base.Resize();
+ countBuild--;
+ Console.WriteLine("Resize Class");
+ }
+
+ ///
+ /// Переопределение сигнатуры абстрактного класса
+ ///
+ public override void Open()
+ {
+ Console.WriteLine("Open Abstract Method Class");
+ }
+
+ ///
+ /// Реализация деструктора класса
+ ///
+ ~ClassMain()
+ {
+ Console.WriteLine("###Destroy ClassMain");
+ }
+}
+
+///
+/// Реализация наследования (3 принцип ООП)
+/// Определение:
+/// Наследование - это возможность создания новых абстракций на основе существующих.
+/// Наследование является ключевой функцией объектно-ориентированных языков программирования.
+/// Оно позволяет определить базовый класс для определенных функций (доступа к данным или действий),
+/// а затем создавать производные классы, которые наследуют или переопределяют функции базового класса.
+///
+public class Nasled : ClassMain
+{
+ ///
+ /// Необязательное перепределение виртуального метода главного класса
+ ///
+ public override void GG()
+ {
+ base.GG();
+ }
+}
+
+
+///
+/// Определение:
+/// Records - это ссылочный тип, некая модификация возможностей классов
+/// Ключевая особенность - может представлять неизменяемый тип данных (immutable)
+/// Также имеет особенность в виде встроенного JSON представления при выводе в строку
+/// Имеет возможность управлять своим деконструктором
+///
+public record class Records
+{
+ ///
+ /// Свойство идентификатора
+ ///
+ public int Id { get; init; }
+
+ ///
+ /// Свойство имени
+ ///
+ public string Name { get; init; }
+
+ ///
+ /// Конструктор с параметрами
+ ///
+ /// идентификатор
+ /// имя
+ public Records(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ Console.WriteLine("Construct");
+ }
+
+ public class GlobalInfo
+ {
+ public int Id;
+ public string Name;
+ public int Ida;
+ public string Names;
+ }
+
+ ///
+ /// Деконструктор
+ ///
+ /// имя
+ /// идентификатор
+ public void Deconstruct(out string name, out int id)
+ {
+ name = Name;
+ id = Id;
+ Console.WriteLine("Destruct");
+ }
+}
+
+public record class Person
+{
+ public int Id { get; init; }
+ public string Name { get; init; }
+
+ ///
+ /// Деконструктор
+ ///
+ /// имя
+ /// идентификатор
+ public void Deconstruct(out string name, out int id)
+ {
+ name = Name;
+ id = Id;
+ Console.WriteLine("Destruct Person");
+ }
+}
+
+public record class Job
+{
+ public int Ida { get; init; }
+ public string Names { get; init; }
+
+ ///
+ /// Деконструктор
+ ///
+ /// имя
+ /// идентификатор
+ public void Deconstruct(out string name, out int id)
+ {
+ name = Names;
+ id = Ida;
+ Console.WriteLine("Destruct Job");
+ }
+}
\ No newline at end of file
diff --git a/Patterns/BaseTests/000_TestsMain.cs b/Patterns/BaseTests/000_TestsMain.cs
new file mode 100644
index 0000000..0f420c7
--- /dev/null
+++ b/Patterns/BaseTests/000_TestsMain.cs
@@ -0,0 +1,31 @@
+using Base;
+
+namespace BaseTests;
+
+///
+///
+/// :
+/// -
+///
+/// -
+///
+[TestClass]
+public class TestsMain
+{
+ ///
+ ///
+ ///
+ [TestMethod]
+ public void TestMethod1()
+ {
+ // arrange
+ int expected = 3;
+
+ // act
+ var classMain = new ClassMain(4, "Unit", 10);
+ int actual = classMain.countBuild;
+
+ // assert
+ Assert.AreEqual(expected, actual, 0.001, "BuildCount not correctly"); //
+ }
+}
\ No newline at end of file
diff --git a/Patterns/BaseTests/001_TestInitAndCleanUp.cs b/Patterns/BaseTests/001_TestInitAndCleanUp.cs
new file mode 100644
index 0000000..4920420
--- /dev/null
+++ b/Patterns/BaseTests/001_TestInitAndCleanUp.cs
@@ -0,0 +1,38 @@
+using System.Diagnostics;
+
+namespace Base.Tests;
+
+[TestClass]
+public class TestInitAndCleanUp
+{
+ private ClassMain main;
+ private string Name;
+
+ ///
+ /// Запускается перед каждым тестируемым методом
+ ///
+ [TestInitialize]
+ public void TestInitialize()
+ {
+ Debug.WriteLine("Test Initialize");
+ main = new ClassMain();
+ main.Name = "Nikolay";
+ }
+
+ ///
+ /// Запускается после каждого завершения тестирования метода
+ ///
+ [TestCleanup]
+ public void MainCleanUp()
+ {
+ Debug.WriteLine("Test CleanUp");
+ Name = string.Empty;
+ }
+
+ [TestMethod]
+ public void AddName()
+ {
+ Name = "Nikolay";
+ Assert.AreEqual(Name, main.Name);
+ }
+}
diff --git a/Patterns/BaseTests/002_ClassInitAndCleanUp.cs b/Patterns/BaseTests/002_ClassInitAndCleanUp.cs
new file mode 100644
index 0000000..345d72e
--- /dev/null
+++ b/Patterns/BaseTests/002_ClassInitAndCleanUp.cs
@@ -0,0 +1,41 @@
+
+using System.Diagnostics;
+using System.Xml.Linq;
+
+namespace Base.Tests;
+
+[TestClass]
+public class ClassInitAndCleanUp
+{
+ private static ClassMain main;
+
+ ///
+ /// Запускается один раз перед тем как запустится один Unit Test
+ /// Метод должен быть открытым, статическим и принимать параметр типа контекста
+ ///
+ ///
+ [ClassInitialize]
+ public static void ClassInitialize(TestContext context)
+ {
+ main = new ClassMain();
+ main.Name = "Test";
+ }
+
+ ///
+ /// Запускается после последнего тестируемого метода
+ /// Метод должен быть открытым, статическим и возвращать void
+ ///
+ [ClassCleanup]
+ public static void MainCleanUp()
+ {
+ Debug.WriteLine("Test CleanUp");
+ main.Name = string.Empty;
+ }
+
+ [TestMethod]
+ public void AddName()
+ {
+ var Name = "Test";
+ Assert.AreEqual(Name, main.Name);
+ }
+}
diff --git a/Patterns/BaseTests/003_AssemblyInit.cs b/Patterns/BaseTests/003_AssemblyInit.cs
new file mode 100644
index 0000000..6714a99
--- /dev/null
+++ b/Patterns/BaseTests/003_AssemblyInit.cs
@@ -0,0 +1,26 @@
+namespace Base.Tests;
+
+[TestClass]
+public class AssemblyInit
+{
+ ///
+ /// Код выполняется один раз на всю сборку
+ /// Используется во всех Unit тестах во всех тестовых вкладках
+ ///
+ ///
+ [AssemblyInitialize]
+ public static void TestMethodInit(TestContext testContext)
+ {
+ Console.WriteLine("Test AssemblyInitialize: " + testContext.TestName);
+ }
+
+ ///
+ /// Код выполняется один раз на всю сборку
+ /// Используется во всех Unit тестах во всех тестовых вкладках
+ ///
+ [AssemblyCleanup]
+ public static void TestMethodGlobalCleanUp()
+ {
+ Console.WriteLine("Test AssemblyCleanup");
+ }
+}
diff --git a/Patterns/BaseTests/004_AssertMethods.cs b/Patterns/BaseTests/004_AssertMethods.cs
new file mode 100644
index 0000000..0e499f6
--- /dev/null
+++ b/Patterns/BaseTests/004_AssertMethods.cs
@@ -0,0 +1,65 @@
+namespace Base.Tests;
+
+[TestClass]
+public class AssertMethods
+{
+ [TestMethod]
+ public void IsSqrtTest()
+ {
+ // arrange
+ const double input = 4;
+ const double expected = 2;
+
+ // act
+ var actual = AssertMsTest.GetSqrt(input);
+
+ // assert - сравнивает два значения
+ Assert.AreEqual(expected, actual, $"Sqrt of {input} should have been {expected}");
+ }
+
+ [TestMethod]
+ public void DeltaTest()
+ {
+ const double expected = 3.1;
+ const double delta = 0.07;
+
+ // 3.1622776601683795
+ // 0.062..
+ double actual = AssertMsTest.GetSqrt(10);
+
+ // Проверка значений на равенство с учётом прогрешлоости delta
+ Assert.AreEqual(expected, actual, delta, $"Sqrt of {actual} should have been {expected}");
+ }
+
+ [TestMethod]
+ public void StringAreEqualTest()
+ {
+ // arrange
+ const string expected = "hello";
+ const string input = "HELLO";
+
+ // act and assert
+ // третий параметр игнорирование регистра
+ Assert.AreEqual(expected, input, true);
+ }
+
+ [TestMethod]
+ public void StringAreSameTest()
+ {
+ string a = "Hello";
+ string b = "Hello";
+
+ // проверка равенства ссылок
+ Assert.AreSame(a, b);
+ }
+
+ [TestMethod]
+ public void IntegerAreSameTest()
+ {
+ int a = 10;
+ int b = 10;
+
+ // проверка равенства ссылок
+ Assert.AreSame(a, b);
+ }
+}
diff --git a/Patterns/BaseTests/005_CollectionAssertMethods.cs b/Patterns/BaseTests/005_CollectionAssertMethods.cs
new file mode 100644
index 0000000..50988f5
--- /dev/null
+++ b/Patterns/BaseTests/005_CollectionAssertMethods.cs
@@ -0,0 +1,65 @@
+namespace Base.Tests;
+
+///
+/// Проверяет результат работы с коллекциями
+///
+[TestClass]
+public class CollectionAssertMethods
+{
+ public static List employees;
+
+ [ClassInitialize]
+ public static void InitializeCurrentTest(TestContext context)
+ {
+ employees = new List();
+
+ employees.Add("Nikolay");
+ employees.Add("Oleg");
+ }
+
+ ///
+ /// Проверка значений коллекции на наличие в ней
+ ///
+ [TestMethod]
+ public void AllItemAreNotNullTest()
+ {
+ CollectionAssert.AllItemsAreNotNull(employees, "Not null failed");
+ }
+
+ ///
+ /// Проверка значения коллекции на уникальность
+ ///
+ [TestMethod]
+ public void AllItemsAreUniqueTest()
+ {
+ CollectionAssert.AllItemsAreUnique(employees, "Uniqueness failed");
+ }
+
+ ///
+ /// Проверяет каждый элемент списка на равенство с входящим списком
+ ///
+ [TestMethod]
+ public void AreEqualTest()
+ {
+ var currList = new List();
+
+ currList.Add("Nikolay");
+ currList.Add("Oleg");
+
+ CollectionAssert.AreEqual(currList, employees);
+ }
+
+ ///
+ /// Проверяем наличии одного List в другом
+ ///
+ [TestMethod]
+ public void SubsetTest()
+ {
+ var subsetList = new List();
+
+ subsetList.Add(employees[1]);
+ //subsetList.Add("Mig"); //ошибка так как этот элемент не входит в employees
+
+ CollectionAssert.IsSubsetOf(subsetList, employees, "not elements subsetList to employees");
+ }
+}
diff --git a/Patterns/BaseTests/006_StringAssetMethods.cs b/Patterns/BaseTests/006_StringAssetMethods.cs
new file mode 100644
index 0000000..b1006a8
--- /dev/null
+++ b/Patterns/BaseTests/006_StringAssetMethods.cs
@@ -0,0 +1,44 @@
+using System.Text.RegularExpressions;
+
+namespace Base.Tests;
+
+[TestClass]
+public class StringAssetMethods
+{
+ ///
+ /// Проверка подстроки в строке
+ ///
+ [TestMethod]
+ public void StringContainsTest()
+ {
+ StringAssert.Contains("Assert samples", "sam");
+ }
+
+ ///
+ /// ПРоверка с использованием регулярного выражения
+ ///
+ [TestMethod]
+ public void StringMathesTest()
+ {
+ // проверяет наличие трёх цифр подряд
+ StringAssert.Matches("123", new Regex(@"\d{3}"));
+ }
+
+ ///
+ /// Проверка начала строки на соответствие условию
+ ///
+ [TestMethod]
+ public void StringStartsWithTest()
+ {
+ StringAssert.StartsWith("Hello London", "H");
+ }
+
+ ///
+ /// Проверка конца строки на соответствие условию
+ ///
+ [TestMethod]
+ public void StringEndWithTest()
+ {
+ StringAssert.EndsWith("Hello Moscow", "w");
+ }
+}
diff --git a/Patterns/BaseTests/007_ExpectingExceptions.cs b/Patterns/BaseTests/007_ExpectingExceptions.cs
new file mode 100644
index 0000000..67c1d88
--- /dev/null
+++ b/Patterns/BaseTests/007_ExpectingExceptions.cs
@@ -0,0 +1,27 @@
+namespace Base.Tests;
+
+[TestClass]
+public class ExpectingExceptions
+{
+ ///
+ /// Проверка метода на возврат исключения
+ ///
+ [ExpectedException(typeof(ArgumentNullException), "Exception was not throw")]
+ [TestMethod]
+ public void AssertMsTestExceptionTest()
+ {
+ var ms = new AssertMsTest();
+ ms.SayHello(null);
+ }
+
+ [TestMethod]
+ public void AssertMsTestReturnTest()
+ {
+ var name = "Hi! Nikolay";
+
+ var ms = new AssertMsTest();
+ var actual = ms.SayHello("Nikolay");
+
+ Assert.AreEqual(name, actual, $"name: {name} act: {actual}");
+ }
+}
diff --git a/Patterns/BaseTests/Base.Tests.csproj b/Patterns/BaseTests/Base.Tests.csproj
new file mode 100644
index 0000000..76e1ecd
--- /dev/null
+++ b/Patterns/BaseTests/Base.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Patterns/BaseTests/Usings.cs b/Patterns/BaseTests/Usings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/Patterns/BaseTests/Usings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file
diff --git a/Patterns/Bridge/Bridge.csproj b/Patterns/Bridge/Bridge.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Bridge/Bridge.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Bridge/Program.cs b/Patterns/Bridge/Program.cs
new file mode 100644
index 0000000..a4de93c
--- /dev/null
+++ b/Patterns/Bridge/Program.cs
@@ -0,0 +1,96 @@
+/* Мост
+ Разделяет абстракцию и реализацию так,
+ чтобы они могли изменяться независимо друг от друга
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var programmer_1 = new FreelancerProgger(new CPPLang());
+ programmer_1.DoWork();
+ programmer_1.EarnMoney();
+ var programmer_2 = new FreelancerProgger(new CSharpLang());
+ programmer_2.DoWork();
+ programmer_2.EarnMoney();
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Поведение языка
+///
+interface ILanguage
+{
+ void Build();
+ void Execute();
+}
+
+class CPPLang : ILanguage
+{
+ public void Build()
+ {
+ Console.WriteLine("C++ compile");
+ }
+
+ public void Execute()
+ {
+ Console.WriteLine("C++ Start");
+ }
+}
+
+class CSharpLang : ILanguage
+{
+ public void Build()
+ {
+ Console.WriteLine("C# compile");
+ }
+
+ public void Execute()
+ {
+ Console.WriteLine("C# Start");
+ }
+}
+
+abstract class Programmer
+{
+ protected ILanguage language;
+ public ILanguage Language
+ {
+ set { language = value; }
+ }
+
+ public Programmer(ILanguage language)
+ {
+ Language = language;
+ }
+
+ public virtual void DoWork()
+ {
+ language.Build();
+ language.Execute();
+ }
+
+ public abstract void EarnMoney();
+}
+
+class FreelancerProgger : Programmer
+{
+ public FreelancerProgger(ILanguage language) : base(language) { }
+
+ public override void EarnMoney()
+ {
+ Console.WriteLine("Получаем оплату за заказ");
+ }
+}
+
+class CorporateProgger : Programmer
+{
+ public CorporateProgger(ILanguage language) : base(language) { }
+
+ public override void EarnMoney()
+ {
+ Console.WriteLine("Получаем оплату в конце месяца");
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Builder/Builder.csproj b/Patterns/Builder/Builder.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Builder/Builder.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Builder/Program.cs b/Patterns/Builder/Program.cs
new file mode 100644
index 0000000..2b61f7a
--- /dev/null
+++ b/Patterns/Builder/Program.cs
@@ -0,0 +1,120 @@
+/* Строитель
+ Разделяет создание сложного объекта
+ и его инициализацию так, что одинаковый
+ процесс построения может может создавать
+ объекты с разным состоянием
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var rx = new Baker();
+ var bread = rx.Bake(new RBuilderBread());
+
+ Console.WriteLine(bread.ToString());
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Мука
+///
+class Floor
+{
+ ///
+ /// Сорт муки
+ ///
+ public string Sort { get; set; }
+}
+
+///
+/// Соль
+///
+class Salt
+{
+ ///
+ /// Масса
+ ///
+ public double Mass { get; set; }
+}
+
+///
+/// Пищевые добавки
+///
+class Additives
+{
+ ///
+ /// Список пищевых добавок
+ ///
+ public string[] Names { get; set; }
+}
+
+///
+/// Xлеб
+///
+class Bread
+{
+ public Floor Floor { get; set; }
+ public Salt Salt { get; set; }
+ public Additives Additives { get; set; }
+
+ public override string ToString()
+ {
+ return $"[F: {Floor.Sort}]---[S: {Salt.Mass}]---[A: {Additives.Names[0]}]";
+ }
+}
+
+///
+/// Строитель хлеба
+///
+abstract class BreadBuilder
+{
+ public Bread Bread { get; set; }
+ public void CreateBread()
+ {
+ Bread = new Bread();
+ }
+
+ public abstract void SetFloor();
+ public abstract void SetSalt();
+ public abstract void SetAdditives();
+}
+
+///
+/// Пекарь
+///
+class Baker
+{
+ public Bread Bake(BreadBuilder breadBuilder)
+ {
+ breadBuilder.CreateBread();
+ breadBuilder.SetFloor();
+ breadBuilder.SetSalt();
+ breadBuilder.SetAdditives();
+ return breadBuilder.Bread;
+ }
+}
+
+
+///
+/// Для ржаного хлеба строитель
+///
+class RBuilderBread : BreadBuilder
+{
+ public override void SetAdditives()
+ {
+ Bread.Additives = new Additives() { Names = new[] { "E222", "E297" } };
+ }
+
+ public override void SetFloor()
+ {
+ Bread.Floor = new Floor() { Sort = "R class" };
+ }
+
+ public override void SetSalt()
+ {
+ Bread.Salt = new Salt() { Mass = 3.44 };
+ }
+}
diff --git a/Patterns/ChainOfResponsibility/ChainOfResponsibility.csproj b/Patterns/ChainOfResponsibility/ChainOfResponsibility.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/ChainOfResponsibility/ChainOfResponsibility.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/ChainOfResponsibility/Program.cs b/Patterns/ChainOfResponsibility/Program.cs
new file mode 100644
index 0000000..1eb7422
--- /dev/null
+++ b/Patterns/ChainOfResponsibility/Program.cs
@@ -0,0 +1,165 @@
+/* Цепочка обязанностей
+ Избегает связывание отправителя запроса
+ с его получателем, давая возможность обработать
+ запрос более чем одному объекту. Связывает
+ объекты-получатели и передаёт запрос по цепочке
+ пока объект не обработает его.
+ */
+class Program
+{
+ public static void GiveCommand(IWorker worker, string command)
+ {
+ var str = worker.Execute(command);
+ if(string.IsNullOrEmpty(str)) Console.WriteLine(command + " - никто не выполнил команду");
+ else Console.WriteLine(str);
+ }
+
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ Handler h1 = new ConcreateHandler1();
+ Handler h2 = new ConcreateHandler2();
+ h1.Successor = h2;
+ h1.HandleRequest(2); //От первого до второго объекта обработка
+ Console.WriteLine("Please press Enter...");
+ Console.ReadKey();
+ #endregion
+ #region Пример №2 - этапы строительства дома
+ var designer = new Designer();
+ var programmer = new Programmer();
+ var finishworker = new FinishWorker();
+ designer.SetNetWorker(finishworker).SetNetWorker(programmer);
+
+ GiveCommand(designer, "Спроектировать веранду");
+ GiveCommand(designer, "Сделать машину времени");
+ GiveCommand(designer, "Уволить работников");
+ GiveCommand(designer, "Курить");
+ #endregion
+ }
+}
+
+///
+/// Передатчик
+///
+abstract class Handler
+{
+ public Handler Successor { get; set; }
+ public abstract void HandleRequest(int condition);
+}
+
+///
+/// Обработчик запроса №1
+///
+class ConcreateHandler1 : Handler
+{
+ ///
+ /// Обработка запроса
+ ///
+ /// состояние
+ public override void HandleRequest(int condition)
+ {
+ Console.WriteLine("1");
+ if(condition == 1) return; //завершаем выполнение
+ else if(Successor != null)
+ Successor.HandleRequest(condition); //передача запроса дальше по цепи
+ }
+}
+
+///
+/// Обработчик запроса №2
+///
+class ConcreateHandler2 : Handler
+{
+ ///
+ /// Обработка запроса
+ ///
+ /// состояние
+ public override void HandleRequest(int condition)
+ {
+ Console.WriteLine("2");
+ if (condition == 2) return; //завершаем выполнение
+ else if (Successor != null) //передача запроса дальше по цепи
+ Successor.HandleRequest(condition);
+ }
+}
+
+///
+/// Поведение рабочего
+///
+interface IWorker
+{
+ ///
+ /// Передача обязанностей следующему рабочему
+ ///
+ /// следующий рабочий
+ IWorker SetNetWorker(IWorker worker);
+
+ ///
+ /// Рабочий принимает команду на исполнение
+ ///
+ /// команда
+ /// Резульат принятия
+ string Execute(string command);
+}
+
+///
+/// Абстрактный рабочий, базовое описание структуры каждого
+///
+abstract class AbsWorker : IWorker
+{
+ private IWorker nextWorker;
+ public AbsWorker() => nextWorker = null;
+
+ ///
+ /// Изменяемый процесс обработки команды в классах наследниках
+ /// У каждого рабочего свой процесс выполнени
+ ///
+ /// команда
+ /// Результат
+ public virtual string Execute(string command)
+ {
+ if (nextWorker == null) return string.Empty;
+ return nextWorker.Execute(command);
+ }
+
+ ///
+ /// Передача обязанностей другому рабочему
+ ///
+ /// Другой рабочий
+ /// Другой рабочий
+ public IWorker SetNetWorker(IWorker worker)
+ {
+ nextWorker = worker;
+ return worker;
+ }
+}
+
+class Designer : AbsWorker
+{
+ public override string Execute(string command)
+ {
+ if (command == "Спроектировать веранду")
+ return "Проектировщик выполнил команду: " + command;
+ else return base.Execute(command); //если не может выполнить передаёт следующему в цепочке
+ }
+}
+
+class Programmer: AbsWorker
+{
+ public override string Execute(string command)
+ {
+ if(command == "Сделать машину времени")
+ return "Программист выполнил команду: " + command;
+ else return base.Execute(command);
+ }
+}
+
+class FinishWorker : AbsWorker
+{
+ public override string Execute(string command)
+ {
+ if (command == "Уволить работников")
+ return "Начальник выполнил команду: " + command;
+ else return base.Execute(command);
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Command/Command.csproj b/Patterns/Command/Command.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Command/Command.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Command/Program.cs b/Patterns/Command/Program.cs
new file mode 100644
index 0000000..9ee07e3
--- /dev/null
+++ b/Patterns/Command/Program.cs
@@ -0,0 +1,225 @@
+/* Команда
+ Инкапсулирует запрос в виде объекта
+ позволяя передавать их клиентам в
+ качестве параметров, ставить в очередь,
+ логировать, а также поддерживать отмену
+ операций
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var initCommand = new Invoker(new ConcreteCommand(new Receiver()));
+ initCommand.Run();
+ initCommand.Cancel();
+ Console.WriteLine("Please press Enter...");
+ Console.ReadKey();
+ #endregion
+ #region Пример №2 - пульт управления конвеерной установкой
+ var conveyor = new Conveyor(); // создаём конвеер
+ var multipult = new Multipult(); // создаём пульт управления конвеером
+ multipult.SetCommand(0, new ConveyorWorkCommand(conveyor));
+ multipult.SetCommand(1, new ConveyorAjustCommand(conveyor));
+
+ multipult.PressOn(0);
+ multipult.PressOn(1);
+ multipult.PressCansel();
+ multipult.PressCansel();
+ #endregion
+ }
+}
+
+///
+/// Описания общего поведения объекта
+///
+abstract class Command
+{
+ public abstract void Execute();
+ public abstract void Undo();
+}
+
+///
+/// Описание процесса создания команды
+///
+class ConcreteCommand : Command
+{
+ Receiver receiver;
+
+ public ConcreteCommand(Receiver receiver)
+ {
+ this.receiver = receiver;
+ }
+
+ ///
+ /// Инициализация команды
+ /// *вызывает его получателя
+ ///
+ public override void Execute()
+ {
+ receiver.Operation();
+ }
+
+ ///
+ /// Остановка команды
+ ///
+ public override void Undo()
+ {
+ Console.WriteLine("Stop");
+ }
+}
+
+///
+/// Описание возможностей получателя команды
+///
+class Receiver
+{
+ ///
+ /// Обработка получателем команды
+ ///
+ public void Operation()
+ {
+ Console.WriteLine("Processing...");
+ }
+}
+
+///
+/// Описание инициатора команды
+///
+class Invoker
+{
+ Command command;
+
+ ///
+ /// Принимает в себя команду
+ ///
+ /// #
+ public Invoker(Command command)
+ {
+ this.command = command;
+ }
+
+ ///
+ /// Запускает команду
+ ///
+ public void Run()
+ {
+ command.Execute();
+ }
+
+ ///
+ /// Отменяет выполнение команды
+ ///
+ public void Cancel()
+ {
+ command.Undo();
+ }
+}
+
+///
+/// Поведение команды
+///
+interface ICommand
+{
+ void Positive();
+ void Negative();
+}
+
+///
+/// Класс конвеера
+///
+class Conveyor
+{
+ public void On() => Console.WriteLine("Включение конвеера");
+
+ public void Off() => Console.WriteLine("Выключение конвеера");
+
+ public void SpeedIncrease() => Console.WriteLine("Скорость конвеера увеличена");
+
+ public void SpeedDecrease() => Console.WriteLine("Скорость конвеера снижена");
+}
+
+///
+/// Класс управления работой конвеера
+///
+class ConveyorWorkCommand : ICommand
+{
+ public Conveyor conveer;
+
+ ///
+ /// Передача типа конвеера в конструторе
+ ///
+ /// тип
+ public ConveyorWorkCommand(Conveyor conveer) => this.conveer = conveer;
+
+ public void Negative() => conveer.Off();
+
+ public void Positive() => conveer.On();
+}
+
+///
+/// Класс регулировки конвеера
+///
+class ConveyorAjustCommand : ICommand
+{
+ public Conveyor conveer;
+
+ ///
+ /// Передача типа конвеера в конструторе
+ ///
+ /// тип
+ public ConveyorAjustCommand(Conveyor conveer) => this.conveer = conveer;
+
+ public void Negative() => conveer.SpeedDecrease();
+
+ public void Positive() => conveer.SpeedIncrease();
+}
+
+
+///
+/// Пульт управления конвеером
+///
+class Multipult
+{
+ ///
+ /// Все возможные команды
+ ///
+ private List commands;
+
+ ///
+ /// История выполненных команд для возможной их отмены
+ ///
+ private Stack history;
+
+ public Multipult()
+ {
+ commands = new List() { null, null };
+ history = new Stack();
+ }
+
+ ///
+ /// Устанавлием список команд по индексу кнопки
+ ///
+ public void SetCommand(int btn, ICommand command) => commands[btn] = command;
+
+ ///
+ /// Вызывает команду из списка по указанному индексу
+ /// и запишет в историю команд выполненную команду
+ ///
+ /// идекс кнопки
+ public void PressOn(int btn)
+ {
+ commands[btn].Positive();
+ history.Push(commands[btn]);
+ }
+
+ ///
+ /// Извлекает команду из истории и отменяет её
+ ///
+ public void PressCansel()
+ {
+ if(history.Count == 0) return;
+ var oldC = history.Pop();
+ oldC.Negative();
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Composite/Composite.csproj b/Patterns/Composite/Composite.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Composite/Composite.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Composite/Program.cs b/Patterns/Composite/Program.cs
new file mode 100644
index 0000000..6d65b38
--- /dev/null
+++ b/Patterns/Composite/Program.cs
@@ -0,0 +1,129 @@
+/* Компоновщик
+ Компонует объекты в древовидную структуру по принципу "часть-целое",
+ представляя их в виде иерархии. Позволяет
+ клиенту одинаково обращаться как к отдельному,
+ так и к целому поддереву
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var paths = new Paths(new Dictionary());
+ paths.components.Add(1, new Directory("C"));
+ paths.components[1].Add(new Folder("SYSTEM"));
+ paths.components[1].Add(new Folder("DATA"));
+ paths.components[1].Add(new File("test.txt"));
+ paths.components.Add(0, new Directory("F"));
+ paths.components[0].Add(new File("resize.cs"));
+ paths.Print();
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Абстракция компонента файловой системы (дерева) - пути до файла
+///
+abstract class Component
+{
+ protected string name;
+
+ public Component(string name)
+ {
+ this.name = name;
+ }
+
+ public virtual void Add(Component component) { }
+ public abstract void Remove(Component component);
+ public abstract void Print();
+}
+
+class Paths : Component
+{
+ public Dictionary components;
+
+ public Paths(Dictionary components) : base ("")
+ {
+ this.components = components;
+ }
+
+ public override void Print()
+ {
+ foreach (var component in components)
+ {
+ component.Value.Print();
+ Console.WriteLine();
+ }
+ }
+
+ public override void Remove(Component component)
+ {
+ Console.WriteLine("Delete Path" + this.name);
+ }
+}
+
+class Directory : Component
+{
+ public List components = new();
+
+ public Directory(string name)
+ : base(name)
+ {
+ }
+
+ public override void Add(Component component)
+ {
+ components.Add(component);
+ }
+
+ public override void Print()
+ {
+ Console.Write(this.name + ":");
+ foreach (var component in components)
+ {
+ component.Print();
+ }
+ }
+
+ public override void Remove(Component component)
+ {
+ component.Remove(component);
+ }
+}
+
+class Folder : Component
+{
+ public Folder(string name)
+ : base(name)
+ {
+ }
+
+ public override void Print()
+ {
+ Console.Write("\\" + this.name);
+ }
+
+ public override void Remove(Component component)
+ {
+ Console.WriteLine(this.name + " Delete");
+ }
+}
+
+class File : Component
+{
+ public File(string name)
+ : base(name)
+ {
+ }
+
+ public override void Print()
+ {
+ Console.Write("\\" + this.name);
+ }
+
+ public override void Remove(Component component)
+ {
+ Console.WriteLine(this.name + " Delete");
+ }
+}
diff --git a/Patterns/Decorator/Decorator.csproj b/Patterns/Decorator/Decorator.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Decorator/Decorator.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Decorator/Program.cs b/Patterns/Decorator/Program.cs
new file mode 100644
index 0000000..a0b1f82
--- /dev/null
+++ b/Patterns/Decorator/Program.cs
@@ -0,0 +1,62 @@
+/* Декоратор
+ Динамически предоставляет объекту
+ дополнительные возможности. Представляет
+ собой гибкую альтернативу наследованию
+ для расширения функциональности.
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ Pizza r = new RussianPizza();
+ Console.WriteLine(r.GetCost());
+ Pizza i = new TomatoPizza(r);
+ Console.WriteLine(i.GetCost());
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+abstract class Pizza
+{
+ public string Name { get; set; }
+ public Pizza(string name)
+ {
+ Name = name;
+ }
+ public abstract int GetCost();
+}
+
+class RussianPizza : Pizza
+{
+ public RussianPizza() : base("Russian Pizza")
+ {
+ }
+
+ public override int GetCost()
+ {
+ return 1000;
+ }
+}
+
+abstract class PizzaDecorator : Pizza
+{
+ protected Pizza pizza;
+ protected PizzaDecorator(string name, Pizza pizza) : base(name)
+ {
+ this.pizza = pizza;
+ }
+}
+
+class TomatoPizza : PizzaDecorator
+{
+ public TomatoPizza(Pizza pizza) : base(pizza.Name + ", tomato", pizza)
+ {
+ }
+
+ public override int GetCost()
+ {
+ return pizza.GetCost() + 100;
+ }
+}
diff --git a/Patterns/Dict/DictionaryInfo.csproj b/Patterns/Dict/DictionaryInfo.csproj
new file mode 100644
index 0000000..5eb1e84
--- /dev/null
+++ b/Patterns/Dict/DictionaryInfo.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ disable
+
+
+
diff --git a/Patterns/Dict/Program.cs b/Patterns/Dict/Program.cs
new file mode 100644
index 0000000..aca679b
--- /dev/null
+++ b/Patterns/Dict/Program.cs
@@ -0,0 +1,116 @@
+using System.Collections;
+using System.Collections.Concurrent;
+using System.Collections.Specialized;
+using System.Diagnostics;
+
+class Program
+{
+ ///
+ /// Стандартный Dictionary
+ /// Быстрый поиск с помощью ключей, можно добавлять и удалять элементы
+ ///
+ private static readonly Dictionary Dictionary = new();
+
+ ///
+ /// ListDictionary
+ /// Он меньше и быстрее, чем Hashtable если количество элементов равно 10 или меньше
+ ///
+ private static readonly ListDictionary LDictionary = new()
+ {
+ { "key", "value"}
+ };
+
+ ///
+ /// HybridDictionary
+ /// Рекомендуется для случаев, когда количество элементов в словаре неизвестно.
+ /// Он использует улучшенную производительность ListDictionary с небольшими коллекциями
+ /// и предлагает гибкость переключения на Hashtable , которая обрабатывает большие коллекции лучше
+ ///
+ private static readonly HybridDictionary HDictionary = new()
+ {
+ { "key", "value"}
+ };
+
+ ///
+ /// OrderedDictionary
+ /// Он всегда упорядочен при выводе foreach
+ /// Ключ не может быть нулевым , но значение может быть.
+ /// Каждый элемент представляет собой пару ключ/значение, хранящуюся в объекте DictionaryEntry
+ /// Доступ к элементам возможен либо по ключу, либо по индексу.
+ /// [!]
+ /// если элементов больше 20-ти быстрее при цикле for
+ /// если элементов меньше 15-20 быстрее в foreach чем for
+ ///
+ private static readonly OrderedDictionary ODictionary = new()
+ {
+ {"01", "odin"},
+ {"02", "dva"},
+ {"03", "tri"},
+ {"04", "chetiri"},
+ {"06", "pyat"},
+ {"07", "pyat"},
+ {"08", "pyat"},
+ {"09", "pyat"},
+ {"10", "pyat"},
+ {"11", "pyat"},
+ {"12", "pyat"},
+ {"13", "pyat"},
+ {"14", "pyat"},
+ {"15", "pyat"},
+ {"16", "pyat"},
+ {"17", "pyat"},
+ {"18", "pyat"},
+ {"19", "pyat"},
+ {"20", "pyat"},
+ {"21", "pyat"},
+ {"22", "pyat"},
+ {"23", "pyat"},
+ {"24", "pyat"},
+ {"25", "pyat"},
+ {"26", "pyat"},
+ {"27", "pyat"},
+ {"28", "pyat"},
+ {"29", "pyat"},
+ {"30", "pyat"},
+ {"31", "pyat"}
+ };
+
+
+ ///
+ /// SortedDictionary
+ /// Дерево бинарного поиска, в котором все элементы отсортированы на основе ключа
+ /// Быстрее вставляет и удаляет элементы
+ ///
+ private static readonly SortedDictionary SDictionary = new();
+
+ ///
+ /// ConcurrentDictionary
+ /// Потокобезопасная коллекция пар "ключ-значение", доступ к которой могут одновременно получать несколько потоков.
+ /// по умолчанию 4 потока на запись concurrencyLevel = 4
+ /// первоначальное число элементов 31 сapacity = 31
+ /// В отличие от обычного Dictionary, можно производить вставку в ConcurrentDictionary или удаление из него прямо во время перечисления
+ ///
+ private static readonly ConcurrentDictionary СoncurrentDictionary = new();
+
+ static void Main()
+ {
+ Stopwatch stopwatch = new Stopwatch();
+ stopwatch.Start();
+ for(int i = 0; i < ODictionary.Count; i++)
+ {
+ string val = (string)ODictionary[i];
+ Console.WriteLine(val);
+ }
+ stopwatch.Stop();
+ Console.WriteLine("[for][el > 20]: " + stopwatch.Elapsed);
+ stopwatch.Reset();
+ stopwatch.Start();
+ foreach (DictionaryEntry item in ODictionary)
+ {
+ Console.WriteLine(item.Value);
+ }
+ stopwatch.Stop();
+ Console.WriteLine("[foreach][el > 20]: " + stopwatch.Elapsed);
+ Console.ReadKey();
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Facade/Facade.csproj b/Patterns/Facade/Facade.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Facade/Facade.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Facade/Program.cs b/Patterns/Facade/Program.cs
new file mode 100644
index 0000000..11cad77
--- /dev/null
+++ b/Patterns/Facade/Program.cs
@@ -0,0 +1,55 @@
+/* Фасад
+ Предоставляет единый интерфейс к группе
+ интерфейсов подсистемы. Определяет высокоуровневый
+ интерфейс, делая систему проще для использования.
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var facade = new Facade(new A(), new B());
+ facade.Start();
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+class Facade
+{
+ ILogic logic1;
+ ILogic logic2;
+ public Facade(ILogic logic1, ILogic logic2)
+ {
+ this.logic1 = logic1;
+ this.logic2 = logic2;
+ }
+
+ public void Start()
+ {
+ logic1.Process();
+ logic2.Process();
+ }
+}
+
+interface ILogic
+{
+ void Process();
+}
+
+
+class A : ILogic
+{
+ public void Process()
+ {
+ Console.WriteLine("Some Process " + GetType().Name);
+ }
+}
+
+class B : ILogic
+{
+ public void Process()
+ {
+ Console.WriteLine("Some Process " + GetType().Name);
+ }
+}
\ No newline at end of file
diff --git a/Patterns/FactoryMethod/FactoryMethod.csproj b/Patterns/FactoryMethod/FactoryMethod.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/FactoryMethod/FactoryMethod.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/FactoryMethod/Program.cs b/Patterns/FactoryMethod/Program.cs
new file mode 100644
index 0000000..7c42e32
--- /dev/null
+++ b/Patterns/FactoryMethod/Program.cs
@@ -0,0 +1,120 @@
+/* Фабричный метод
+ Определяет интерфейс для создания объекта,
+ но позволяет подклассам решать, какой класс создавать.
+ Позволяет делегировать создание класса
+ объектам класса.
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var ltd = new WoodDeveloper();
+ ltd.Create();
+
+ var rss = new OfficeDeveloper();
+ rss.Create();
+
+ Creator ltdEx = new Creator();
+ var a1 = ltdEx.FactoryMethod();
+ a1.Create();
+ Creator rssEx = new Creator();
+ var a2 = rssEx.FactoryMethod();
+ a2.Create();
+
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// *** представления через обобщения (нельзя инициализировать через параметризированный конструктор)
+///
+/// обобщающий тип
+class Creator where T : Developer, new()
+{
+ public T FactoryMethod() { return new T(); }
+}
+
+///
+/// Cтроительная компания - базовая логика
+///
+abstract class Developer
+{
+ protected string Name { get; set; }
+
+ public Developer(string name)
+ {
+ Name = name;
+ }
+
+ ///
+ /// Фабричный метод
+ ///
+ /// House
+ public abstract House Create();
+}
+
+class WoodDeveloper : Developer
+{
+ public WoodDeveloper() : base("Wood Develop LTD")
+ {
+ }
+
+ public override House Create()
+ {
+ return new PanelHouse();
+ }
+}
+
+class OfficeDeveloper : Developer
+{
+ public OfficeDeveloper() : base("Office Develop RSS")
+ {
+ }
+
+ public override House Create()
+ {
+ return new OfficeHouse();
+ }
+}
+
+///
+/// Общая логика операций над строением
+///
+abstract class House
+{
+ public abstract void Build();
+}
+
+///
+/// Панельный дом
+///
+class PanelHouse : House
+{
+ public PanelHouse()
+ {
+ Build();
+ }
+
+ public override void Build()
+ {
+ Console.WriteLine("Build Panel House");
+ }
+}
+
+///
+/// Офисное здание
+///
+class OfficeHouse : House
+{
+ public OfficeHouse()
+ {
+ Build();
+ }
+
+ public override void Build()
+ {
+ Console.WriteLine("Build Office House");
+ }
+}
\ No newline at end of file
diff --git a/Patterns/FluentBuilder/FluentBuilder.csproj b/Patterns/FluentBuilder/FluentBuilder.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/FluentBuilder/FluentBuilder.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/FluentBuilder/Program.cs b/Patterns/FluentBuilder/Program.cs
new file mode 100644
index 0000000..a8c2c69
--- /dev/null
+++ b/Patterns/FluentBuilder/Program.cs
@@ -0,0 +1,68 @@
+/* Гибкий(плавный, текучий) строитель (интерфейс)
+ Позволяет упростить процесс создания сложных
+ объектов с помощью методов-цепочек, которые
+ наделяют объект каким-то определенным качеством
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ User user = new User().Create().SetName("Alex").SetPassword("admin");
+ Console.WriteLine(user);
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Шаблон пользователя
+///
+class User
+{
+ public string Name { get; set; }
+ public string Password { get; set; }
+
+ public UserBuilder Create()
+ {
+ return new UserBuilder();
+ }
+
+ public override string ToString()
+ {
+ return $"Name {Name}, Password {Password}";
+ }
+}
+
+///
+/// Шаблон гибкого строителя конфигурации пользователя
+///
+class UserBuilder
+{
+ private User CurrentUser { get; set; }
+ public UserBuilder()
+ {
+ CurrentUser = new User();
+ }
+
+ public UserBuilder SetName(string name)
+ {
+ CurrentUser.Name = name;
+ return this;
+ }
+
+ public UserBuilder SetPassword(string password)
+ {
+ CurrentUser.Password = password;
+ return this;
+ }
+
+ ///
+ /// преобразуем тип Builder в тип User для которого он использовался
+ ///
+ /// строитель
+ public static implicit operator User(UserBuilder builder)
+ {
+ return builder.CurrentUser;
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Flyweight/Flyweight.csproj b/Patterns/Flyweight/Flyweight.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Flyweight/Flyweight.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Flyweight/Program.cs b/Patterns/Flyweight/Program.cs
new file mode 100644
index 0000000..b9ab274
--- /dev/null
+++ b/Patterns/Flyweight/Program.cs
@@ -0,0 +1,97 @@
+/* Приспособленец
+ Благодаря совместному использованию,
+ поддерживает эффективную работу
+ с большим количеством объектов.
+ (для оптимизации работы с памятью)
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ double longtitude = 22.33;
+ double latitude = 55.11;
+
+ HouseFactory houseFactory = new HouseFactory();
+ for (int i = 0; i < 10; i++)
+ {
+ House panelH = houseFactory.GetHouse("Panel");
+ if(panelH != null)
+ panelH.Build(longtitude, latitude);
+ longtitude += 0.1;
+ latitude += 0.1;
+ }
+
+ for (int i = 0; i < 10; i++)
+ {
+ House officeH = houseFactory.GetHouse("Office");
+ if (officeH != null)
+ officeH.Build(longtitude, latitude);
+ longtitude += 0.1;
+ latitude += 0.1;
+ }
+
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+abstract class House
+{
+ ///
+ /// Кол-во этажей - внутреннее состояние
+ ///
+ protected int stages;
+
+ ///
+ /// Внешнее состояние действия
+ ///
+ ///
+ ///
+ public abstract void Build(double latitude, double longitude);
+}
+
+class PanelHouse : House
+{
+ public PanelHouse()
+ {
+ stages = 5;
+ }
+
+ public override void Build(double latitude, double longitude)
+ {
+ Console.WriteLine($"PanelHouse Build stages-{stages} {latitude}, {longitude}");
+ }
+}
+
+class OfficeHouse : House
+{
+ public OfficeHouse()
+ {
+ stages = 50;
+ }
+
+ public override void Build(double latitude, double longitude)
+ {
+ Console.WriteLine($"OfficeHouse Build stages-{stages} {latitude}, {longitude}");
+ }
+}
+
+class HouseFactory
+{
+ Dictionary houses = new Dictionary();
+
+ public HouseFactory()
+ {
+ houses.Add("Panel", new PanelHouse());
+ houses.Add("Office", new OfficeHouse());
+ }
+
+ public House GetHouse(string key)
+ {
+ if (houses.ContainsKey(key))
+ return houses[key];
+ else
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Interpreter/Interpreter.csproj b/Patterns/Interpreter/Interpreter.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Interpreter/Interpreter.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Interpreter/Program.cs b/Patterns/Interpreter/Program.cs
new file mode 100644
index 0000000..67abd0a
--- /dev/null
+++ b/Patterns/Interpreter/Program.cs
@@ -0,0 +1,148 @@
+/* Интерпретатор
+ Получая формальный язык, определяет
+ представление его грамматики и интерпретатор,
+ использующий это представление для обработки
+ выражений языка (Применяется для часто повторяющихся операций)
+ */
+class Program
+{
+ public static void Main(string[] args)
+ {
+ #region Пример №1 - базовое
+ var context = new Context();
+ //создаём переменные
+ int x = 5;
+ int y = 8;
+ int z = 2;
+ int k = 10;
+ //задаём переменные в контекст
+ context.SetVariable("x", x);
+ context.SetVariable("y", y);
+ context.SetVariable("z", z);
+ context.SetVariable("k", k);
+ //(x + y - z) * k
+ var expressionAdd = new AddExpression(new NumberExpression("x"),
+ new NumberExpression("y"));
+ var expressionSub = new SubstructExpression(expressionAdd,
+ new NumberExpression("z"));
+ var expressionPow = new PowExpression(expressionSub, new NumberExpression("k"));
+ Console.WriteLine(expressionPow.Interpret(context));
+ Console.WriteLine("Please press Enter...");
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Агрегатор выражений
+///
+class Context
+{
+ Dictionary variables;
+
+ public Context()
+ {
+ variables = new Dictionary();
+ }
+
+ public int GetVariable(string name)
+ {
+ if(variables.ContainsKey(name))
+ return variables[name];
+ else
+ return -1;
+ }
+
+ public void SetVariable(string name, int value)
+ {
+ if(variables.ContainsKey(name))
+ variables[name] = value;
+ else
+ variables.Add(name, value);
+ }
+}
+
+///
+/// Поведение интерпретатора
+///
+interface IExpression
+{
+ int Interpret(Context context);
+}
+
+///
+/// Терминальное выражение
+///
+class NumberExpression : IExpression
+{
+ string Name { get; set; }
+ public NumberExpression(string name)
+ {
+ Name = name;
+ }
+
+ public int Interpret(Context context)
+ {
+ return context.GetVariable(Name);
+ }
+}
+
+///
+/// Нетерминальное выражение для сложения
+///
+class AddExpression : IExpression
+{
+ IExpression LeftExpression { get; set; }
+ IExpression RightExpression { get; set; }
+
+ public AddExpression(IExpression left, IExpression right)
+ {
+ LeftExpression = left;
+ RightExpression = right;
+ }
+
+ public int Interpret(Context context)
+ {
+ return LeftExpression.Interpret(context) + RightExpression.Interpret(context);
+ }
+}
+
+///
+/// Нетерминальное выражение для умножения
+///
+class PowExpression : IExpression
+{
+ IExpression LeftExpression { get; set; }
+ IExpression RightExpression { get; set; }
+
+ public PowExpression(IExpression left, IExpression right)
+ {
+ LeftExpression = left;
+ RightExpression = right;
+ }
+
+ public int Interpret(Context context)
+ {
+ return LeftExpression.Interpret(context) * RightExpression.Interpret(context);
+ }
+}
+
+///
+/// Нетерминальное выражение для вычитания
+///
+class SubstructExpression : IExpression
+{
+ IExpression LeftExpression { get; set; }
+ IExpression RightExpression { get; set; }
+
+ public SubstructExpression(IExpression left, IExpression right)
+ {
+ LeftExpression = left;
+ RightExpression = right;
+ }
+
+ public int Interpret(Context context)
+ {
+ return LeftExpression.Interpret(context) - RightExpression.Interpret(context);
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Iterator/Iterator.csproj b/Patterns/Iterator/Iterator.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Iterator/Iterator.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Iterator/Program.cs b/Patterns/Iterator/Program.cs
new file mode 100644
index 0000000..9bfa1e8
--- /dev/null
+++ b/Patterns/Iterator/Program.cs
@@ -0,0 +1,263 @@
+/* Итератор
+ Предоставляет способ последовательного
+ доступа к множеству, независимо от его
+ внутреннего устройства
+ */
+class Program
+{
+ public static void Main(string[] args)
+ {
+ #region Пример №1 - базовое
+ Library library = new Library();
+ Reader reader = new Reader();
+ reader.SetBooks(library);
+ Console.ReadKey();
+ #endregion
+ #region Пример №2 - пример работы стека
+ DataStack stack = new DataStack();
+ for (int i = 0; i < 5; i++)
+ stack.Push(i);
+
+ DataStack stackCopy = new DataStack(stack);
+
+ Console.WriteLine(stack == stackCopy); //true
+
+ stackCopy.Push(10);
+
+ Console.WriteLine(stack == stackCopy); //false
+ #endregion
+ }
+}
+
+///
+/// Читатель
+///
+class Reader
+{
+ public void SetBooks(Library library)
+ {
+ IBookIterator iterator = library.CreateNumerator();
+ while(iterator.HasNext())
+ {
+ Book book = iterator.Next();
+ Console.WriteLine(book.Name);
+ }
+ }
+}
+
+///
+/// Поведение поиска библиотеки
+///
+interface IBookIterator
+{
+ bool HasNext();
+ Book Next();
+}
+
+///
+/// Поведение библиотеки
+///
+interface IBookNumerable
+{
+ IBookIterator CreateNumerator();
+ int Count { get; }
+ Book this[int index] { get; }
+}
+
+///
+/// Класс книги
+///
+class Book
+{
+ public string Name { get; set; }
+}
+
+///
+/// Класс библиотеки книг
+///
+class Library : IBookNumerable
+{
+ private Book[] Books { get; set; }
+
+ public Library()
+ {
+ Books = new Book[]
+ {
+ new Book(){ Name = "James"},
+ new Book(){ Name = "Karl"},
+ new Book(){ Name = "Rogan"}
+ };
+ }
+
+ ///
+ /// Вызов книги
+ ///
+ /// индекс в библиотеке
+ /// Book
+ public Book this[int index] => Books[index];
+
+ ///
+ /// Количество книг в библиотеке
+ ///
+ public int Count => Books.Length;
+
+ ///
+ /// Перейти к следующей библиотеке
+ ///
+ /// IBookIterator(LibraryNumenator)
+ public IBookIterator CreateNumerator() => new LibraryNumenator(this);
+}
+
+class LibraryNumenator : IBookIterator
+{
+ IBookNumerable Aggregate { get; set; }
+ int index = 0;
+
+ ///
+ /// Передача коллекции книг в Library
+ ///
+ ///
+ public LibraryNumenator(IBookNumerable bookNumerable)
+ {
+ Aggregate = bookNumerable;
+ }
+
+ public bool HasNext() => index < Aggregate.Count;
+
+ public Book Next() => Aggregate[index++];
+}
+
+///
+/// Класс стека данных
+///
+public class DataStack
+{
+ private int[] items = new int[10];
+ ///
+ /// Длинна массива данных в этом стеке
+ ///
+ private int lenght;
+
+ public DataStack() => lenght = -1;
+
+ ///
+ /// Для копирования экземпляра класса
+ ///
+ /// Экземпляр данного класса
+ public DataStack(DataStack myStack)
+ {
+ this.items = myStack.items;
+ this.lenght = myStack.lenght;
+ }
+
+ ///
+ /// Свойство геттера для поля items
+ ///
+ public int[] Items { get => items; }
+
+ ///
+ /// Свойство геттера для поля lenght
+ ///
+ public int Lenght { get => lenght; }
+
+ ///
+ /// Добавление элементов в массив
+ ///
+ /// значение
+ public void Push(int value) => items[++lenght] = value;
+
+ ///
+ /// Получение последнего элемента
+ ///
+ /// значение
+ public int Pop() => items[lenght--];
+
+ ///
+ /// Переопределение оператора сравнения двух экземпляров данного класса
+ ///
+ ///
+ ///
+ /// bool
+ public static bool operator ==(DataStack left, DataStack right)
+ {
+ StackIterator it1 = new StackIterator(left),
+ it2 = new StackIterator(right);
+
+ while (it1.IsEnd() || it2.IsEnd())
+ {
+ if (it1.Get() != it2.Get()) break;
+ it1++;
+ it2++;
+ }
+
+ return !it1.IsEnd() && !it2.IsEnd();
+ }
+
+ ///
+ /// Переопределение оператора сравнения двух экземпляров данного класса
+ ///
+ ///
+ ///
+ /// bool
+ public static bool operator !=(DataStack left, DataStack right)
+ {
+ StackIterator it1 = new StackIterator(left),
+ it2 = new StackIterator(right);
+
+ while (it1.IsEnd() || it2.IsEnd())
+ {
+ if (it1.Get() != it2.Get()) break;
+ it1++;
+ it2++;
+ }
+
+ return !it1.IsEnd() && !it2.IsEnd();
+ }
+}
+
+///
+/// Перечислитель
+///
+class StackIterator
+{
+ private DataStack stack;
+ private int index;
+
+ ///
+ /// Инициализируем поля перечислителя
+ ///
+ /// данные
+ public StackIterator(DataStack dataStack)
+ {
+ this.stack = dataStack;
+ this.index = 0;
+ }
+
+ ///
+ /// Переопределение опреатора инкрементирования
+ ///
+ /// новый переданный экземпляр класса
+ /// экземпляр класса с инкрементированым значением index
+ public static StackIterator operator ++(StackIterator s)
+ {
+ s.index++;
+ return s;
+ }
+
+ ///
+ /// Возвращает значение элемента поля стека
+ /// через его свойство по текущему индексу
+ ///
+ ///
+ public int Get()
+ {
+ if(index < stack.Lenght) return stack.Items[index];
+ return 0;
+ }
+
+ ///
+ /// Возвращет true при достижении предельного размера стека
+ ///
+ /// bool
+ public bool IsEnd() => index != stack.Lenght + 1;
+}
\ No newline at end of file
diff --git a/Patterns/LetCode.Tests/LetCode.Tests.csproj b/Patterns/LetCode.Tests/LetCode.Tests.csproj
new file mode 100644
index 0000000..a54203b
--- /dev/null
+++ b/Patterns/LetCode.Tests/LetCode.Tests.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Patterns/LetCode.Tests/Tests.cs b/Patterns/LetCode.Tests/Tests.cs
new file mode 100644
index 0000000..7277e03
--- /dev/null
+++ b/Patterns/LetCode.Tests/Tests.cs
@@ -0,0 +1,65 @@
+namespace LetCode.Tests
+{
+ [TestClass]
+ public class Tests
+ {
+ ///
+ /// target
+ ///
+ [TestMethod]
+ public void TwoSumTest()
+ {
+ // arrange
+ int[] input = { 1, 2, 3 };
+ int[] expected = { 0, 2 };
+
+ // act
+ var actual = LetCodeTasks.TwoSum(input, 4);
+
+ // arrange
+ CollectionAssert.AreEqual(expected, actual, $"actual: {string.Join(',', actual)}, expected: {string.Join(',', expected)}");
+ }
+
+ [TestMethod]
+ public void IsPalindromeTest()
+ {
+ // arrange
+ int input = 99;
+ bool expected = true;
+
+ // act
+ var actual = LetCodeTasks.IsPalindrome(input);
+
+ // arrange
+ Assert.AreEqual(expected, actual, $"actual: {actual}, expected: {expected}");
+ }
+
+ [TestMethod]
+ public void RomanToIntTest()
+ {
+ // arrange
+ string input = "MCMXCIV";
+ int expected = 1994;
+
+ // act
+ var actual = LetCodeTasks.RomanToInt(input);
+
+ // arrange
+ Assert.AreEqual(expected, actual, $"actual: {actual}, expected: {expected}");
+ }
+
+ [TestMethod]
+ public void LongestCommonPrefixTest()
+ {
+ // arrange
+ string[] input = { "XXVIII", "XX", "XXII" };
+ string expected = "XX";
+
+ // act
+ var actual = LetCodeTasks.LongestCommonPrefix(input);
+
+ // arrange
+ Assert.AreEqual(expected, actual, $"actual: {actual}, expected: {expected}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Patterns/LetCode.Tests/Usings.cs b/Patterns/LetCode.Tests/Usings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/Patterns/LetCode.Tests/Usings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
\ No newline at end of file
diff --git a/Patterns/LetCode/LetCode.csproj b/Patterns/LetCode/LetCode.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/LetCode/LetCode.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/LetCode/Program.cs b/Patterns/LetCode/Program.cs
new file mode 100644
index 0000000..80ad718
--- /dev/null
+++ b/Patterns/LetCode/Program.cs
@@ -0,0 +1,160 @@
+public static class LetCodeTasks
+{
+ ///
+ /// Какие числа массива дают в сумме указанное число
+ ///
+ /// Массив чисел
+ /// Искомая сумма
+ /// Массив индексов чисел
+ public static int[] TwoSum(int[] nums, int target)
+ {
+ int countNew = 0;
+ int[] weeks = { };
+ for (int k = 0; k < nums.Length-1; k++)
+ {
+ for(int i = 1; i < nums.Length; i++)
+ {
+ int a1 = nums[k];
+ int a2 = nums[i];
+ if (a1 + a2 == target)
+ {
+ if(k != i && k < i)
+ {
+ countNew++;
+ Array.Resize(ref weeks, weeks.Length + 2);
+ weeks[weeks.Length - 2] = k;
+ weeks[weeks.Length - 1] = i;
+ }
+ }
+ }
+ }
+ return weeks;
+ }
+
+ ///
+ /// Проверяет число на верность свойствам полиндрома
+ ///
+ /// Число
+ /// Полиндром или нет
+ public static bool IsPalindrome(int x)
+ {
+ if(x.ToString().Length > 3)
+ {
+ for (int i = 0; i < x.ToString().Length; i++)
+ {
+ if (x.ToString()[i] != x.ToString()[x.ToString().Length - (i + 1)])
+ return false;
+ }
+ }
+ if(x >= 0 && x.ToString()[0] == x.ToString()[x.ToString().Length-1])
+ return true;
+ return false;
+ }
+
+ ///
+ /// Переводит римские цифры в реальное число
+ ///
+ /// Римский символ
+ /// Число
+ public static int RomanToInt(string s)
+ {
+ var mapNumbers = new Dictionary()
+ {
+ { 1, 'I' }, { 5, 'V' }, { 10, 'X' }, { 50, 'L' }, { 100, 'C' }, { 500, 'D' }, { 1000, 'M' }
+ };
+ char symTmp = ' ';
+ int[] sumArray = { };
+ for (int i = 0; i < s.Length; i++)
+ {
+ foreach (var number in mapNumbers.Values)
+ {
+ if(number == s[i])
+ {
+ int numberRes = 0;
+ switch($"{symTmp}{number}")
+ {
+ case "IV":
+ numberRes = 4;
+ Array.Resize(ref sumArray, sumArray.Length - 1);
+ break;
+ case "IX":
+ numberRes = 9;
+ Array.Resize(ref sumArray, sumArray.Length - 1);
+ break;
+ case "XL":
+ numberRes = 40;
+ Array.Resize(ref sumArray, sumArray.Length - 1);
+ break;
+ case "XC":
+ numberRes = 90;
+ Array.Resize(ref sumArray, sumArray.Length - 1);
+ break;
+ case "CD":
+ numberRes = 400;
+ Array.Resize(ref sumArray, sumArray.Length - 1);
+ break;
+ case "CM":
+ numberRes = 900;
+ Array.Resize(ref sumArray, sumArray.Length - 1);
+ break;
+ }
+ if(numberRes == 0)
+ numberRes = mapNumbers.Where(x => x.Value == number).FirstOrDefault().Key;
+ Array.Resize(ref sumArray, sumArray.Length + 1);
+ sumArray[sumArray.Length - 1] = numberRes;
+ symTmp = number;
+ }
+ }
+ }
+ return sumArray.Sum();
+ }
+
+ ///
+ /// Вычисляет совпадение частей слов в массиве слов
+ ///
+ /// Массив слов
+ /// Подстрока обобщающая все слова
+ public static string LongestCommonPrefix(string[] strs)
+ {
+ if (strs.Length == 0)
+ return "";
+ if(strs.Length == 1)
+ return strs[0];
+ string prefix = string.Empty;
+ int[] leghts = { };
+ int tmpIndex = 0;
+ for (int i = 1; i < strs.Length; i++)
+ {
+ char[] word1 = strs[i-1].ToCharArray();
+ char[] word2 = strs[i].ToCharArray();
+ tmpIndex = 0;
+ for (int j = 0; j < word1.Length; j++)
+ {
+ if (word2.Length >= j + 1 && word1[j] == word2[j])
+ {
+ tmpIndex++;
+ if (prefix.Length < j + 1)
+ prefix += word1[j];
+ }
+ else
+ {
+ if (tmpIndex == 0)
+ return "";
+ break;
+ }
+ }
+ Array.Resize(ref leghts, leghts.Length + 1);
+ leghts[leghts.Length - 1] = tmpIndex;
+ }
+ if (prefix.Length > 0)
+ prefix = prefix.Substring(0, leghts.Min());
+ else
+ return "";
+ return prefix;
+ }
+
+ static void Main()
+ {
+ Console.ReadKey();
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Mediator/Mediator.csproj b/Patterns/Mediator/Mediator.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Mediator/Mediator.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Mediator/Program.cs b/Patterns/Mediator/Program.cs
new file mode 100644
index 0000000..1b443e8
--- /dev/null
+++ b/Patterns/Mediator/Program.cs
@@ -0,0 +1,112 @@
+/* Посредник
+ Определяет объект инкапсулирующий способ
+ взаимодействия объектов. Обеспечивает слабую связь,
+ избавляя их от необходимости ссылаться друг на друга
+ и даёт возможность независимо изменять их взаимодействие.
+ */
+class Program
+{
+ public static void Main(string[] args)
+ {
+ #region Пример №1 - базовое
+ ManagerMediator mediator = new ManagerMediator();
+ Colleague customer = new CustomerCollegue(mediator);
+ Colleague programmer = new ProgrammerCollegue(mediator);
+ Colleague tester = new TesterCollegue(mediator);
+ mediator.Customer = customer;
+ mediator.Programmer = programmer;
+ mediator.Tester = tester;
+ customer.Send("Есть заказ! Нужно сделать REST API");
+ programmer.Send("REST API готов, нужно протестировать swagger");
+ tester.Send("Тест прошёл успешно, документация отличная!");
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Интерфейс для взаимодействия с посредником
+///
+abstract class Mediator
+{
+ public abstract void Send(string message, Colleague colleague);
+}
+
+///
+/// Интерфейс для взаимодействия с коллегами
+///
+abstract class Colleague
+{
+ Mediator Mediator { get; set; }
+
+ public Colleague(Mediator mediator)
+ {
+ Mediator = mediator;
+ }
+
+ public virtual void Send(string message)
+ {
+ Mediator.Send(message, this);
+ }
+
+ public abstract void Notify(string message);
+}
+
+///
+/// Непосредственный заказчик
+///
+class CustomerCollegue : Colleague
+{
+ public CustomerCollegue(Mediator mediator) : base(mediator) {}
+
+ public override void Notify(string message)
+ {
+ Console.WriteLine($"Сообщение заказчику: {message}");
+ }
+}
+
+///
+/// Программист
+///
+class ProgrammerCollegue : Colleague
+{
+ public ProgrammerCollegue(Mediator mediator) : base(mediator) { }
+
+ public override void Notify(string message)
+ {
+ Console.WriteLine($"Сообщение программисту: {message}");
+ }
+}
+
+///
+/// Тестировщик
+///
+class TesterCollegue : Colleague
+{
+ public TesterCollegue(Mediator mediator) : base(mediator) { }
+
+ public override void Notify(string message)
+ {
+ Console.WriteLine($"Сообщение тестировщику: {message}");
+ }
+}
+
+///
+/// Посредник
+///
+class ManagerMediator : Mediator
+{
+ public Colleague Customer { get; set; }
+ public Colleague Programmer { get; set; }
+ public Colleague Tester { get; set; }
+
+ public override void Send(string message, Colleague colleague)
+ {
+ if(Customer == colleague) //если отправитель заказчик значит есть новый заказ
+ Programmer.Notify(message); //отправляем сообщение программисту - сделать заказ
+ else if(Programmer == colleague) //если отправитель программист
+ Tester.Notify(message); //отправляем сообщение тестировщику
+ else if(Tester == colleague) //если отправитель тестировщик
+ Customer.Notify(message); //значит оповещаем заказчика
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Memento/Memento.csproj b/Patterns/Memento/Memento.csproj
new file mode 100644
index 0000000..5eb1e84
--- /dev/null
+++ b/Patterns/Memento/Memento.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ disable
+
+
+
diff --git a/Patterns/Memento/Program.cs b/Patterns/Memento/Program.cs
new file mode 100644
index 0000000..b2f6dcd
--- /dev/null
+++ b/Patterns/Memento/Program.cs
@@ -0,0 +1,119 @@
+/* Хранитель + Одиночка
+ Не нарушая инкапсуляцию, определяет
+ и сохраняет внутреннее состояние объекта и
+ позволяет позже восстановить объект в этом
+ состоянии
+ */
+class Program
+{
+ public static void Main(string[] args)
+ {
+ #region Пример №1 - базовое
+ using (var hero = new Hero())
+ {
+ hero.Shoot();
+ }
+ using (var heroMan = new Hero())
+ {
+ heroMan.RestoreState(GameHistory.Instance.History.Pop());
+ heroMan.Shoot();
+ }
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Класс героя
+///
+class Hero : IDisposable
+{
+ ///
+ /// Количество патронов
+ ///
+ private int patrons = 10;
+
+ ///
+ /// Выстрел
+ ///
+ public void Shoot()
+ {
+ if(patrons > 0)
+ {
+ patrons--;
+ Console.WriteLine($"Осталось {patrons} патронов...");
+ }
+ else
+ Console.WriteLine("Нет патронов");
+ }
+
+ ///
+ /// Сохранение состояния
+ ///
+ ///
+ public HeroMemento SaveState()
+ {
+ Console.WriteLine($"Сохранено - {patrons}");
+ return new HeroMemento(patrons);
+ }
+
+ ///
+ /// Восстановление состояния
+ ///
+ /// Хранитель состояния
+ public void RestoreState(HeroMemento memento)
+ {
+ patrons = memento.Patrons;
+ Console.WriteLine($"Загружено - {patrons}");
+ }
+
+ ///
+ /// Удаление из памяти + сохранение в истории последнего состояния
+ ///
+ public void Dispose()
+ {
+ GameHistory.Instance.History.Push(SaveState());
+ }
+}
+
+///
+/// Memento - Хранитель состояния
+///
+class HeroMemento
+{
+ public int Patrons { get; private set; }
+
+ public HeroMemento(int patrons)
+ {
+ Patrons = patrons;
+ }
+}
+
+///
+/// Caretaker - смотритель состояния
+///
+class GameHistory
+{
+ private static GameHistory instance;
+ public Stack History { get; set; }
+
+ private GameHistory()
+ {
+ History = new Stack();
+ }
+
+ public static GameHistory Instance
+ {
+ get
+ {
+ if(instance == null)
+ instance = new GameHistory();
+ return instance;
+ }
+ }
+
+ public void Clear()
+ {
+ History.Clear();
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Observer/Observer.csproj b/Patterns/Observer/Observer.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Observer/Observer.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Observer/Program.cs b/Patterns/Observer/Program.cs
new file mode 100644
index 0000000..d7c283d
--- /dev/null
+++ b/Patterns/Observer/Program.cs
@@ -0,0 +1,103 @@
+/* Наблюдатель
+ Определяет зависимость один ко многим
+ между объектами так, что когда один меняет
+ своё состояние, все зависимые объекты оповещаются
+ и обновляются автоматически
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var concreteObservable = new ConcreteObservable();
+ concreteObservable.AddObserver(new Observer("Job"));
+ concreteObservable.AddObserver(new Observer("Robin"));
+ concreteObservable.AddObserver(new Observer("Jaz"));
+ concreteObservable.AddObserver(new Observer("John"));
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Поведение наблюдателя
+///
+interface IObservable
+{
+ ///
+ /// Добавить наблюдаемого
+ ///
+ /// Наблюдаемый
+ void AddObserver(IObserver observer);
+ ///
+ /// Удалить наблюдаемого
+ ///
+ /// Наблюдаемый
+ void RemoveObserver(IObserver observer);
+ ///
+ /// Оповестить всех наблюдаемых
+ ///
+ void NotifyObservers();
+}
+
+///
+/// Реализация конкретного наблюдателя
+///
+class ConcreteObservable : IObservable
+{
+ ///
+ /// Список наблюдаемых
+ ///
+ private List _observers;
+
+ public ConcreteObservable()
+ {
+ _observers = new List();
+ }
+
+ public void AddObserver(IObserver observer)
+ {
+ Console.WriteLine("Event Add Observer");
+ NotifyObservers();
+ _observers.Add(observer);
+ }
+
+ public void NotifyObservers()
+ {
+ if(_observers.Count == 0) Console.WriteLine("Не кого оповещать...");
+ foreach (var observer in _observers)
+ observer.Update();
+ }
+
+ public void RemoveObserver(IObserver observer)
+ {
+ _observers.Remove(observer);
+ NotifyObservers();
+ }
+}
+
+///
+/// Поведение наблюдаемого
+///
+interface IObserver
+{
+ void Update();
+}
+
+///
+/// Наблюдаемый
+///
+class Observer : IObserver
+{
+ public string Name { get; set; }
+
+ public Observer(string name)
+ {
+ Name = name;
+ }
+
+ public void Update()
+ {
+ Console.WriteLine($"Update {Name}");
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Patterns Programming.sln b/Patterns/Patterns Programming.sln
new file mode 100644
index 0000000..74d697b
--- /dev/null
+++ b/Patterns/Patterns Programming.sln
@@ -0,0 +1,269 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.2.32616.157
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Behavioral(Поведенческие)", "Behavioral(Поведенческие)", "{749199BB-F36F-4019-BFEB-B04475AB5140}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Structural(Структурные)", "Structural(Структурные)", "{3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Creational(Порождающие)", "Creational(Порождающие)", "{6B6B76CA-287A-4FA5-99FE-8098611020F9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Memento", "Memento\Memento.csproj", "{B4BD097B-27B4-4AAE-AC40-E0CA633B2A32}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChainOfResponsibility", "ChainOfResponsibility\ChainOfResponsibility.csproj", "{CFC9F6BF-FC2B-446E-8FB5-92A1E06CAE91}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Observer", "Observer\Observer.csproj", "{72179984-1F4B-4C89-8E29-49D8C8B18A94}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Command", "Command\Command.csproj", "{C4EBB3CE-6BBD-473E-8CAC-012015F8FEA1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "State", "State\State.csproj", "{5EA8980C-B0B1-4C20-93C8-92EFE4B88708}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interpreter", "Interpreter\Interpreter.csproj", "{E470CB5E-7369-44DB-8192-5A2567865A83}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Strategy", "Strategy\Strategy.csproj", "{6566D5A3-F886-4E66-9E98-7FA536D7B4D4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Iterator", "Iterator\Iterator.csproj", "{2BFCAE0E-EBBC-4673-AC56-AA007679A15F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TemplateMethod", "TemplateMethod\TemplateMethod.csproj", "{2411F3F1-D28B-4939-85D9-921847678065}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mediator", "Mediator\Mediator.csproj", "{09C6E1FA-6553-4C92-9D38-613A9A8D155B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Visitor", "Visitor\Visitor.csproj", "{737EB7A2-98B4-473A-81B9-9CAB3BEB69CF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Base Logic(Базовые понятия)", "Base Logic(Базовые понятия)", "{4FF822AA-F380-4D92-86B0-50FE5CE6BCEE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaseInfo", "Base\BaseInfo.csproj", "{3E397CB2-2AAF-4D66-855D-E2BA198C380E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Base.Tests", "BaseTests\Base.Tests.csproj", "{90CB9984-E9D1-4821-BA45-D2C668A81813}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DictionaryInfo", "Dict\DictionaryInfo.csproj", "{279CA287-2FCE-45C7-BBD8-4E3941B09028}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LetCode", "LetCode\LetCode.csproj", "{71DA93E5-2EB8-4C26-9537-3C1F18DFEC15}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Adapter", "Adapter\Adapter.csproj", "{467EF678-626C-4CBB-B608-234CA2DD8613}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Proxy", "Proxy\Proxy.csproj", "{6BED2E46-471C-484E-A7BA-EFD41A981EF3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bridge", "Bridge\Bridge.csproj", "{47297A10-E472-454B-B333-5554789B8D21}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Composite", "Composite\Composite.csproj", "{34A7974D-A37A-4D79-AF2A-5EECC9295884}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Decorator", "Decorator\Decorator.csproj", "{751A645A-8E65-4556-A322-5170CC3CA905}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Facade", "Facade\Facade.csproj", "{770B90B9-DD17-4279-AE68-FCC6E3783D05}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flyweight", "Flyweight\Flyweight.csproj", "{A0DB1337-5532-49C3-99DD-BEBE27F9B382}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbstractFactory", "AbstractFactory\AbstractFactory.csproj", "{28A8AFD1-7FDB-45E4-A349-1BDD1FEB53C2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FactoryMethod", "FactoryMethod\FactoryMethod.csproj", "{206CBCB3-8D1F-47A7-B510-AC9D34C8CBD3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Builder", "Builder\Builder.csproj", "{B4567CE3-9BEC-445E-8830-B4B206FA7641}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentBuilder", "FluentBuilder\FluentBuilder.csproj", "{BA3B2D0E-484B-4075-92F5-D84B10EFDE4D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prototype", "Prototype\Prototype.csproj", "{F92E5A05-034A-43E4-A7DB-0073C3E322EC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Singleton", "Singleton\Singleton.csproj", "{E17B2354-AD60-4083-BA38-6A9BD85F81B3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LetCode.Tests", "LetCode.Tests\LetCode.Tests.csproj", "{34F0E125-BE37-42FF-A679-4EBA9F29D86D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Принципы проектирования", "Принципы проектирования", "{941BD935-75AD-4FEC-8D97-FD5D55905CF1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "1_Принцип единственной обязанности", "1_Принцип единственной обязанности\1_Принцип единственной обязанности.csproj", "{4CEA5C3D-9E87-4AF9-8683-905A46D7006C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "2_Принцип открытости, закрытости", "2_Принцип открытости, закрытости\2_Принцип открытости, закрытости.csproj", "{9CB78E60-6FFB-47C3-9BF3-F20FD7573C80}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "3_Принцип подстановки Барбары Лисков", "3_Принцип подстановки Барбары Лисков\3_Принцип подстановки Барбары Лисков.csproj", "{9A9FCDC5-8E2E-4CD1-9DCB-204A6A166732}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "4_Принцип разделения интерфейсов", "4_Принцип разделения интерфейсов\4_Принцип разделения интерфейсов.csproj", "{0268644C-135F-4217-AC55-B9139E2EA41B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "5_Принцип инверсии зависимостей", "5_Принцип инверсии зависимостей\5_Принцип инверсии зависимостей.csproj", "{C7CF08B8-7D0D-47D0-BA43-2488EF6E16E6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B4BD097B-27B4-4AAE-AC40-E0CA633B2A32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4BD097B-27B4-4AAE-AC40-E0CA633B2A32}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4BD097B-27B4-4AAE-AC40-E0CA633B2A32}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4BD097B-27B4-4AAE-AC40-E0CA633B2A32}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CFC9F6BF-FC2B-446E-8FB5-92A1E06CAE91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CFC9F6BF-FC2B-446E-8FB5-92A1E06CAE91}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CFC9F6BF-FC2B-446E-8FB5-92A1E06CAE91}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CFC9F6BF-FC2B-446E-8FB5-92A1E06CAE91}.Release|Any CPU.Build.0 = Release|Any CPU
+ {72179984-1F4B-4C89-8E29-49D8C8B18A94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72179984-1F4B-4C89-8E29-49D8C8B18A94}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72179984-1F4B-4C89-8E29-49D8C8B18A94}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72179984-1F4B-4C89-8E29-49D8C8B18A94}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C4EBB3CE-6BBD-473E-8CAC-012015F8FEA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C4EBB3CE-6BBD-473E-8CAC-012015F8FEA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C4EBB3CE-6BBD-473E-8CAC-012015F8FEA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C4EBB3CE-6BBD-473E-8CAC-012015F8FEA1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5EA8980C-B0B1-4C20-93C8-92EFE4B88708}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5EA8980C-B0B1-4C20-93C8-92EFE4B88708}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5EA8980C-B0B1-4C20-93C8-92EFE4B88708}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5EA8980C-B0B1-4C20-93C8-92EFE4B88708}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E470CB5E-7369-44DB-8192-5A2567865A83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E470CB5E-7369-44DB-8192-5A2567865A83}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E470CB5E-7369-44DB-8192-5A2567865A83}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E470CB5E-7369-44DB-8192-5A2567865A83}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6566D5A3-F886-4E66-9E98-7FA536D7B4D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6566D5A3-F886-4E66-9E98-7FA536D7B4D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6566D5A3-F886-4E66-9E98-7FA536D7B4D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6566D5A3-F886-4E66-9E98-7FA536D7B4D4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2BFCAE0E-EBBC-4673-AC56-AA007679A15F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2BFCAE0E-EBBC-4673-AC56-AA007679A15F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2BFCAE0E-EBBC-4673-AC56-AA007679A15F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2BFCAE0E-EBBC-4673-AC56-AA007679A15F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2411F3F1-D28B-4939-85D9-921847678065}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2411F3F1-D28B-4939-85D9-921847678065}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2411F3F1-D28B-4939-85D9-921847678065}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2411F3F1-D28B-4939-85D9-921847678065}.Release|Any CPU.Build.0 = Release|Any CPU
+ {09C6E1FA-6553-4C92-9D38-613A9A8D155B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {09C6E1FA-6553-4C92-9D38-613A9A8D155B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {09C6E1FA-6553-4C92-9D38-613A9A8D155B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {09C6E1FA-6553-4C92-9D38-613A9A8D155B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {737EB7A2-98B4-473A-81B9-9CAB3BEB69CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {737EB7A2-98B4-473A-81B9-9CAB3BEB69CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {737EB7A2-98B4-473A-81B9-9CAB3BEB69CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {737EB7A2-98B4-473A-81B9-9CAB3BEB69CF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3E397CB2-2AAF-4D66-855D-E2BA198C380E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3E397CB2-2AAF-4D66-855D-E2BA198C380E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3E397CB2-2AAF-4D66-855D-E2BA198C380E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3E397CB2-2AAF-4D66-855D-E2BA198C380E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90CB9984-E9D1-4821-BA45-D2C668A81813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90CB9984-E9D1-4821-BA45-D2C668A81813}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90CB9984-E9D1-4821-BA45-D2C668A81813}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90CB9984-E9D1-4821-BA45-D2C668A81813}.Release|Any CPU.Build.0 = Release|Any CPU
+ {279CA287-2FCE-45C7-BBD8-4E3941B09028}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {279CA287-2FCE-45C7-BBD8-4E3941B09028}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {279CA287-2FCE-45C7-BBD8-4E3941B09028}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {279CA287-2FCE-45C7-BBD8-4E3941B09028}.Release|Any CPU.Build.0 = Release|Any CPU
+ {71DA93E5-2EB8-4C26-9537-3C1F18DFEC15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {71DA93E5-2EB8-4C26-9537-3C1F18DFEC15}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {71DA93E5-2EB8-4C26-9537-3C1F18DFEC15}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {71DA93E5-2EB8-4C26-9537-3C1F18DFEC15}.Release|Any CPU.Build.0 = Release|Any CPU
+ {467EF678-626C-4CBB-B608-234CA2DD8613}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {467EF678-626C-4CBB-B608-234CA2DD8613}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {467EF678-626C-4CBB-B608-234CA2DD8613}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {467EF678-626C-4CBB-B608-234CA2DD8613}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6BED2E46-471C-484E-A7BA-EFD41A981EF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6BED2E46-471C-484E-A7BA-EFD41A981EF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6BED2E46-471C-484E-A7BA-EFD41A981EF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6BED2E46-471C-484E-A7BA-EFD41A981EF3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47297A10-E472-454B-B333-5554789B8D21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47297A10-E472-454B-B333-5554789B8D21}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47297A10-E472-454B-B333-5554789B8D21}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47297A10-E472-454B-B333-5554789B8D21}.Release|Any CPU.Build.0 = Release|Any CPU
+ {34A7974D-A37A-4D79-AF2A-5EECC9295884}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {34A7974D-A37A-4D79-AF2A-5EECC9295884}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {34A7974D-A37A-4D79-AF2A-5EECC9295884}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {34A7974D-A37A-4D79-AF2A-5EECC9295884}.Release|Any CPU.Build.0 = Release|Any CPU
+ {751A645A-8E65-4556-A322-5170CC3CA905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {751A645A-8E65-4556-A322-5170CC3CA905}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {751A645A-8E65-4556-A322-5170CC3CA905}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {751A645A-8E65-4556-A322-5170CC3CA905}.Release|Any CPU.Build.0 = Release|Any CPU
+ {770B90B9-DD17-4279-AE68-FCC6E3783D05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {770B90B9-DD17-4279-AE68-FCC6E3783D05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {770B90B9-DD17-4279-AE68-FCC6E3783D05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {770B90B9-DD17-4279-AE68-FCC6E3783D05}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A0DB1337-5532-49C3-99DD-BEBE27F9B382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A0DB1337-5532-49C3-99DD-BEBE27F9B382}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A0DB1337-5532-49C3-99DD-BEBE27F9B382}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A0DB1337-5532-49C3-99DD-BEBE27F9B382}.Release|Any CPU.Build.0 = Release|Any CPU
+ {28A8AFD1-7FDB-45E4-A349-1BDD1FEB53C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {28A8AFD1-7FDB-45E4-A349-1BDD1FEB53C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {28A8AFD1-7FDB-45E4-A349-1BDD1FEB53C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {28A8AFD1-7FDB-45E4-A349-1BDD1FEB53C2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {206CBCB3-8D1F-47A7-B510-AC9D34C8CBD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {206CBCB3-8D1F-47A7-B510-AC9D34C8CBD3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {206CBCB3-8D1F-47A7-B510-AC9D34C8CBD3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {206CBCB3-8D1F-47A7-B510-AC9D34C8CBD3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B4567CE3-9BEC-445E-8830-B4B206FA7641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4567CE3-9BEC-445E-8830-B4B206FA7641}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4567CE3-9BEC-445E-8830-B4B206FA7641}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4567CE3-9BEC-445E-8830-B4B206FA7641}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BA3B2D0E-484B-4075-92F5-D84B10EFDE4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BA3B2D0E-484B-4075-92F5-D84B10EFDE4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BA3B2D0E-484B-4075-92F5-D84B10EFDE4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BA3B2D0E-484B-4075-92F5-D84B10EFDE4D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F92E5A05-034A-43E4-A7DB-0073C3E322EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F92E5A05-034A-43E4-A7DB-0073C3E322EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F92E5A05-034A-43E4-A7DB-0073C3E322EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F92E5A05-034A-43E4-A7DB-0073C3E322EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E17B2354-AD60-4083-BA38-6A9BD85F81B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E17B2354-AD60-4083-BA38-6A9BD85F81B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E17B2354-AD60-4083-BA38-6A9BD85F81B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E17B2354-AD60-4083-BA38-6A9BD85F81B3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {34F0E125-BE37-42FF-A679-4EBA9F29D86D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {34F0E125-BE37-42FF-A679-4EBA9F29D86D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {34F0E125-BE37-42FF-A679-4EBA9F29D86D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {34F0E125-BE37-42FF-A679-4EBA9F29D86D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4CEA5C3D-9E87-4AF9-8683-905A46D7006C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4CEA5C3D-9E87-4AF9-8683-905A46D7006C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4CEA5C3D-9E87-4AF9-8683-905A46D7006C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4CEA5C3D-9E87-4AF9-8683-905A46D7006C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9CB78E60-6FFB-47C3-9BF3-F20FD7573C80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9CB78E60-6FFB-47C3-9BF3-F20FD7573C80}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9CB78E60-6FFB-47C3-9BF3-F20FD7573C80}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9CB78E60-6FFB-47C3-9BF3-F20FD7573C80}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A9FCDC5-8E2E-4CD1-9DCB-204A6A166732}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A9FCDC5-8E2E-4CD1-9DCB-204A6A166732}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A9FCDC5-8E2E-4CD1-9DCB-204A6A166732}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A9FCDC5-8E2E-4CD1-9DCB-204A6A166732}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0268644C-135F-4217-AC55-B9139E2EA41B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0268644C-135F-4217-AC55-B9139E2EA41B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0268644C-135F-4217-AC55-B9139E2EA41B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0268644C-135F-4217-AC55-B9139E2EA41B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C7CF08B8-7D0D-47D0-BA43-2488EF6E16E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C7CF08B8-7D0D-47D0-BA43-2488EF6E16E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C7CF08B8-7D0D-47D0-BA43-2488EF6E16E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C7CF08B8-7D0D-47D0-BA43-2488EF6E16E6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {B4BD097B-27B4-4AAE-AC40-E0CA633B2A32} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {CFC9F6BF-FC2B-446E-8FB5-92A1E06CAE91} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {72179984-1F4B-4C89-8E29-49D8C8B18A94} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {C4EBB3CE-6BBD-473E-8CAC-012015F8FEA1} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {5EA8980C-B0B1-4C20-93C8-92EFE4B88708} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {E470CB5E-7369-44DB-8192-5A2567865A83} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {6566D5A3-F886-4E66-9E98-7FA536D7B4D4} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {2BFCAE0E-EBBC-4673-AC56-AA007679A15F} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {2411F3F1-D28B-4939-85D9-921847678065} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {09C6E1FA-6553-4C92-9D38-613A9A8D155B} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {737EB7A2-98B4-473A-81B9-9CAB3BEB69CF} = {749199BB-F36F-4019-BFEB-B04475AB5140}
+ {3E397CB2-2AAF-4D66-855D-E2BA198C380E} = {4FF822AA-F380-4D92-86B0-50FE5CE6BCEE}
+ {90CB9984-E9D1-4821-BA45-D2C668A81813} = {4FF822AA-F380-4D92-86B0-50FE5CE6BCEE}
+ {279CA287-2FCE-45C7-BBD8-4E3941B09028} = {4FF822AA-F380-4D92-86B0-50FE5CE6BCEE}
+ {71DA93E5-2EB8-4C26-9537-3C1F18DFEC15} = {4FF822AA-F380-4D92-86B0-50FE5CE6BCEE}
+ {467EF678-626C-4CBB-B608-234CA2DD8613} = {3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}
+ {6BED2E46-471C-484E-A7BA-EFD41A981EF3} = {3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}
+ {47297A10-E472-454B-B333-5554789B8D21} = {3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}
+ {34A7974D-A37A-4D79-AF2A-5EECC9295884} = {3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}
+ {751A645A-8E65-4556-A322-5170CC3CA905} = {3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}
+ {770B90B9-DD17-4279-AE68-FCC6E3783D05} = {3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}
+ {A0DB1337-5532-49C3-99DD-BEBE27F9B382} = {3E3D01F2-BFF2-417A-BEAD-0E0AD3547A8D}
+ {28A8AFD1-7FDB-45E4-A349-1BDD1FEB53C2} = {6B6B76CA-287A-4FA5-99FE-8098611020F9}
+ {206CBCB3-8D1F-47A7-B510-AC9D34C8CBD3} = {6B6B76CA-287A-4FA5-99FE-8098611020F9}
+ {B4567CE3-9BEC-445E-8830-B4B206FA7641} = {6B6B76CA-287A-4FA5-99FE-8098611020F9}
+ {BA3B2D0E-484B-4075-92F5-D84B10EFDE4D} = {6B6B76CA-287A-4FA5-99FE-8098611020F9}
+ {F92E5A05-034A-43E4-A7DB-0073C3E322EC} = {6B6B76CA-287A-4FA5-99FE-8098611020F9}
+ {E17B2354-AD60-4083-BA38-6A9BD85F81B3} = {6B6B76CA-287A-4FA5-99FE-8098611020F9}
+ {34F0E125-BE37-42FF-A679-4EBA9F29D86D} = {4FF822AA-F380-4D92-86B0-50FE5CE6BCEE}
+ {4CEA5C3D-9E87-4AF9-8683-905A46D7006C} = {941BD935-75AD-4FEC-8D97-FD5D55905CF1}
+ {9CB78E60-6FFB-47C3-9BF3-F20FD7573C80} = {941BD935-75AD-4FEC-8D97-FD5D55905CF1}
+ {9A9FCDC5-8E2E-4CD1-9DCB-204A6A166732} = {941BD935-75AD-4FEC-8D97-FD5D55905CF1}
+ {0268644C-135F-4217-AC55-B9139E2EA41B} = {941BD935-75AD-4FEC-8D97-FD5D55905CF1}
+ {C7CF08B8-7D0D-47D0-BA43-2488EF6E16E6} = {941BD935-75AD-4FEC-8D97-FD5D55905CF1}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {6A7DE462-3436-49E8-A6F0-59158DFB417F}
+ EndGlobalSection
+EndGlobal
diff --git a/Patterns/Prototype/Program.cs b/Patterns/Prototype/Program.cs
new file mode 100644
index 0000000..85c2c74
--- /dev/null
+++ b/Patterns/Prototype/Program.cs
@@ -0,0 +1,132 @@
+/* Прототип
+ Определяет несколько видов объектов,
+ чтобы при создании использовать объект-прототип
+ и создаёт новые объекты, копируя прототип
+ (техника клонирования объектов)
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ IFigure cube = new Cube(10, 10);
+ IFigure cloneCube = cube.Clone();
+ IFigure cloneMemberCube = cube.CloneMember();
+ cube.GetInfo();
+ cloneCube.GetInfo();
+ cloneMemberCube.GetInfo();
+ #endregion
+
+ #region Пример №2
+ IEntity entity = new Predator(10, 1000);
+ var clone = entity.CloneEntity();
+ entity.GetInfo();
+ clone.GetInfo();
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Поведение фигуры
+///
+interface IFigure
+{
+ IFigure Clone();
+ IFigure? CloneMember();
+ void GetInfo();
+}
+
+///
+/// Шаблон куба
+///
+class Cube : IFigure
+{
+ int Width { get; set; }
+ int Height { get; set; }
+
+ public Cube(int width, int heght)
+ {
+ Width = width;
+ Height = heght;
+ }
+
+ public IFigure Clone()
+ {
+ return new Cube(Width, Height);
+ }
+
+ public IFigure? CloneMember()
+ {
+ return this.MemberwiseClone() as IFigure;
+ }
+
+ public void GetInfo()
+ {
+ Console.WriteLine($"Cube {Width}/{Height}");
+ }
+}
+
+///
+/// Треугольник
+///
+class Rect : IFigure
+{
+ int Width { get; set; }
+ int Height { get; set; }
+
+ public Rect(int width, int heght)
+ {
+ Width = width;
+ Height = heght;
+ }
+
+ public IFigure Clone()
+ {
+ return new Rect(Width, Height);
+ }
+
+ public IFigure? CloneMember()
+ {
+ return this.MemberwiseClone() as IFigure;
+ }
+
+ public void GetInfo()
+ {
+ Console.WriteLine($"Rect {Width}/{Height}");
+ }
+}
+
+///
+/// Поведение сущности
+///
+interface IEntity
+{
+ IEntity CloneEntity();
+ void GetInfo();
+}
+
+abstract record Animal(int Paws, int Weight) : IEntity
+{
+ public abstract IEntity CloneEntity();
+ public abstract void GetInfo();
+}
+
+record Predator(int Paws, int Weight) : Animal(Paws, Weight)
+{
+ public override IEntity CloneEntity()
+ => this with { };
+
+ public override void GetInfo()
+ => Console.WriteLine($"Predator w={Weight} p={Paws}");
+}
+
+record Person(int IQ) : IEntity
+{
+ public IEntity CloneEntity()
+ => this with { };
+
+ public void GetInfo()
+ => Console.WriteLine($"Peaple with IQ={IQ}");
+}
+
diff --git a/Patterns/Prototype/Prototype.csproj b/Patterns/Prototype/Prototype.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Prototype/Prototype.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Proxy/Program.cs b/Patterns/Proxy/Program.cs
new file mode 100644
index 0000000..71d2a38
--- /dev/null
+++ b/Patterns/Proxy/Program.cs
@@ -0,0 +1,94 @@
+using Microsoft.EntityFrameworkCore;
+/* Заместитель
+ Предоставляет объект-заместитель другого объекта
+ для контроля доступа к нему
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ using (IBook book = new BookStoreProxy())
+ {
+ //читаем первую страницу
+ Page page1 = book.GetPage(1);
+ Console.WriteLine(page1.Text);
+ //читаем первую страницу
+ Page page2 = book.GetPage(2);
+ Console.WriteLine(page1.Text);
+ //возвращаемся на первую страницу
+ page1 = book.GetPage(1);
+ Console.WriteLine(page1.Text);
+ }
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// отдельная страница книги
+///
+/// Идентификатор
+/// Номер
+/// Содержимое
+record Page(int Id, int Number, string Text);
+
+class PageContext : DbContext
+{
+ public DbSet Pages { get; set; }
+}
+
+interface IBook : IDisposable
+{
+ Page GetPage(int number);
+}
+
+class BookStore : IBook
+{
+ PageContext db;
+
+ public BookStore()
+ {
+ db = new PageContext();
+ }
+
+ public void Dispose()
+ {
+ db.Dispose();
+ }
+
+ public Page GetPage(int number)
+ {
+ return db.Pages.FirstOrDefault(p => p.Number == number);
+ }
+}
+
+class BookStoreProxy : IBook
+{
+ List Pages;
+ BookStore bookStore;
+
+ public BookStoreProxy()
+ {
+ Pages = new List();
+ }
+
+ public void Dispose()
+ {
+ if (bookStore != null)
+ bookStore.Dispose();
+ }
+
+ public Page GetPage(int number)
+ {
+ Page page = Pages.FirstOrDefault(p => p.Number == number);
+ if(page == null)
+ {
+ if(bookStore == null)
+ bookStore = new BookStore();
+ page = bookStore.GetPage(number);
+ Pages.Add(page);
+ }
+ return page;
+ }
+}
diff --git a/Patterns/Proxy/Proxy.csproj b/Patterns/Proxy/Proxy.csproj
new file mode 100644
index 0000000..fed8150
--- /dev/null
+++ b/Patterns/Proxy/Proxy.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Patterns/Singleton/Program.cs b/Patterns/Singleton/Program.cs
new file mode 100644
index 0000000..7bf5224
--- /dev/null
+++ b/Patterns/Singleton/Program.cs
@@ -0,0 +1,44 @@
+/* Одиночка
+ Гарантирует что класс имеет только
+ один экземпляр и представляет глобальную
+ точку доступа к нему
+ */
+
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ (new Thread(() =>
+ {
+ Console.WriteLine(GameHistory.Instance.History[1]);
+ })).Start();
+ Console.WriteLine(GameHistory.Instance.History[0]);
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+class GameHistory
+{
+ private static object syncRoot = new();
+ private static GameHistory _instance;
+ public static GameHistory Instance
+ {
+ get
+ {
+ lock(syncRoot)
+ {
+ if(_instance == null)
+ _instance = new GameHistory();
+ }
+ return _instance;
+ }
+ }
+ public string[] History { get; set; }
+ private GameHistory()
+ {
+ History = new[] { "One History",
+ "Two History"};
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Singleton/Singleton.csproj b/Patterns/Singleton/Singleton.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Singleton/Singleton.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/State/Program.cs b/Patterns/State/Program.cs
new file mode 100644
index 0000000..28ae1b7
--- /dev/null
+++ b/Patterns/State/Program.cs
@@ -0,0 +1,76 @@
+/* Состояние
+ Позволяет объекту изменять
+ своё поведение в зависимости от
+ внутреннего состояния
+ */
+class Program
+{
+ static void Main()
+ {
+ #region Пример №1 - базовое
+ var contextA = new Context(new StateA());
+ var contextB = new Context(new StateB());
+ contextA.Request();
+ contextB.Request();
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Абстракция состояния
+///
+abstract class State
+{
+ public abstract void Handle(Context context);
+}
+
+///
+/// Реализация состояния A
+///
+class StateA : State
+{
+ public StateA()
+ {
+ Console.WriteLine("State-A Create...");
+ }
+
+ public override void Handle(Context context)
+ {
+ context.State = new StateB();
+ }
+}
+
+///
+/// Реализация состояния B
+///
+class StateB : State
+{
+ public StateB()
+ {
+ Console.WriteLine("State-B Create...");
+ }
+
+ public override void Handle(Context context)
+ {
+ context.State = new StateA();
+ }
+}
+
+///
+/// Контекст со своим состоянием
+///
+class Context
+{
+ public State State { get; set; }
+
+ public Context(State state)
+ {
+ State = state;
+ }
+
+ public void Request()
+ {
+ State.Handle(this);
+ }
+}
\ No newline at end of file
diff --git a/Patterns/State/State.csproj b/Patterns/State/State.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/State/State.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Strategy/ILogReader.cs b/Patterns/Strategy/ILogReader.cs
new file mode 100644
index 0000000..3818115
--- /dev/null
+++ b/Patterns/Strategy/ILogReader.cs
@@ -0,0 +1,6 @@
+namespace Strategy;
+
+internal interface ILogReader
+{
+ List Read();
+}
diff --git a/Patterns/Strategy/LogEntry.cs b/Patterns/Strategy/LogEntry.cs
new file mode 100644
index 0000000..2db0304
--- /dev/null
+++ b/Patterns/Strategy/LogEntry.cs
@@ -0,0 +1,15 @@
+namespace Strategy;
+
+public enum LogType
+{
+ Debug,
+ Warning,
+ Fatal
+}
+
+public struct LogEntry
+{
+ public DateTime DateTime { get; set; }
+ public LogType LogType { get; set; }
+ public string Message { get; set; }
+}
diff --git a/Patterns/Strategy/LogFileReader.cs b/Patterns/Strategy/LogFileReader.cs
new file mode 100644
index 0000000..649fcc3
--- /dev/null
+++ b/Patterns/Strategy/LogFileReader.cs
@@ -0,0 +1,17 @@
+namespace Strategy;
+
+public class LogFileReader : ILogReader
+{
+ public List Read()
+ {
+ return new List()
+ {
+ new LogEntry()
+ {
+ DateTime = DateTime.Now,
+ LogType = LogType.Debug,
+ Message = GetType().Name
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Strategy/LogProcessor.cs b/Patterns/Strategy/LogProcessor.cs
new file mode 100644
index 0000000..3f43f0e
--- /dev/null
+++ b/Patterns/Strategy/LogProcessor.cs
@@ -0,0 +1,21 @@
+namespace Strategy;
+
+public class LogProcessor
+{
+ private readonly Func> _logimporter;
+
+ public LogProcessor(Func> logImporter)
+ {
+ _logimporter = logImporter;
+ }
+
+ public void ProcessLogs()
+ {
+ foreach (var logEntry in _logimporter.Invoke())
+ {
+ Console.WriteLine(logEntry.DateTime);
+ Console.WriteLine(logEntry.LogType);
+ Console.WriteLine(logEntry.Message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Strategy/Program.cs b/Patterns/Strategy/Program.cs
new file mode 100644
index 0000000..9488144
--- /dev/null
+++ b/Patterns/Strategy/Program.cs
@@ -0,0 +1,218 @@
+/* Стратегия
+ Определяет группу алгоритмов,
+ инкапсулирует их и делает взаимозаменяемыми.
+ Позволяет изменять алгоритм независимо от клиентов,
+ его использующих.
+ */
+/*
+ * На чем строилось:
+ * СЕРГЕЙ ТЕПЛЯКОВ - Паттерны проектирования на платформе .Net
+ * ШЕВЧУК, АХРИМЕНКО, КАСЬЯНОВ - Приемы объектно-ориентированного проектирования
+ *
+ * ПАТТЕРНЫ ПОВЕДЕНИЯ
+ * Паттерн №1: Стратегия
+ *
+ * - является более контекстно зависимой операцией
+ *
+ * Причины применения:
+ * 1.необходимость инкапсуляции поведения или алгоритма
+ * 2.необходимость замены поведения или алгоритма во время исполнения
+ *
+ * Другими словами, стратегия обеспечивает точку расширения системы
+ * в определенной плоскости: класс-контекст (LogProcessor) принимает экземпляр стратегии (LogFileReader)
+ * и не знает, какой вариант стратегии он собирается использовать.
+ *
+ * Особенность:
+ * Передача интерфейса ILogReader классу LogProcessor увеличивает гибкость,
+ * но в то же время повышает сложность.
+ * Теперь клиентам класса LogProcessor нужно решить, какую реализацию использовать,
+ * или переложить эту ответственность на вызывающий код.
+ */
+
+/*
+ * ВМЕСТО
+ * классической стратегии на основе наследования
+ * можно использовать стратегию на основе делегатов
+ *
+ * ПРИМЕР: Стратегия сортировки
+ */
+
+/*
+ * ВАЖНО: Гибкость не бывает бесплатной, поэтому выделять стратегии стоит тогда,
+ * когда действительно нужна замена поведения во время исполнения.
+ */
+using Strategy;
+
+class Program
+{
+ #region Пример №3 - Сomparer
+ public static void SortListId(List list)
+ {
+ list.Sort(new EmployeeByIdComparer()); //используем функтор
+ }
+
+ public static void SortListName(List list)
+ {
+ list.Sort((x, y) => x.Name.CompareTo(y.Name)); //используем делегат
+ }
+ #endregion
+
+ public static void Main(string[] args)
+ {
+ #region Пример №1 - базовое
+ var car = new Car(new PetrolMove());
+ car.Move();
+ car.Movable = new ElectronicMove();
+ car.Move();
+ Console.ReadKey();
+ #endregion
+ #region Пример №2 - ILogReader
+ LogFileReader logFileReader = new LogFileReader();
+ //создали делегат который принимает в себя метод,
+ //в результате выполнения которого возвращается List
+ Func> _import = () => logFileReader.Read();
+ LogProcessor processor = new LogProcessor(_import);
+ processor.ProcessLogs();
+ #endregion
+ #region Пример №3 - Сomparer
+ List employees = new List
+ {
+ new Employee
+ {
+ Id = 8,
+ Name = "asmus"
+ },
+ new Employee
+ {
+ Id = 1,
+ Name = "robin"
+ },
+ new Employee
+ {
+ Id = 2,
+ Name = "satan"
+ },
+ new Employee
+ {
+ Id = 5,
+ Name = "dastin"
+ }
+ };
+ SortListId(employees); //отсортировали по id через функтор
+ SortListName(employees); //отсортировали по Name через делегат
+ Console.WriteLine();
+ var comparer = new EmployeeByIdComparer();
+ var set = new SortedSet(comparer); //конструктор принимает IComparable
+ //нет конструктора, принимающего делегат Comparison
+ //можно создать небольшой адаптерный фабричный класс
+ var comparer_factory = ComparerFactory.Create((x, y) => x.Id.CompareTo(y.Id));
+ //он помещает сюда фабрику
+ var set_factory = new SortedSet(comparer_factory);
+ #endregion
+ }
+}
+
+///
+/// Поведение движения
+///
+interface IMovable
+{
+ void Move();
+}
+
+///
+/// Бензиновый двигатель
+///
+class PetrolMove : IMovable
+{
+ public void Move()
+ {
+ Console.WriteLine("Движение на бензине");
+ }
+}
+
+///
+/// Электродвигатель
+///
+class ElectronicMove : IMovable
+{
+ public void Move()
+ {
+ Console.WriteLine("Движение на электричестве");
+ }
+}
+
+///
+/// Автомобиль
+///
+class Car
+{
+ ///
+ /// Cпособ передвижения автомобиля
+ ///
+ public IMovable Movable { private get; set; }
+
+ public Car(IMovable movable)
+ {
+ Movable = movable;
+ }
+
+ public void Move()
+ {
+ Movable.Move();
+ }
+}
+
+
+class Employee
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public override string ToString()
+ {
+ return string.Format($"ID={Id}, Name={Name}");
+ }
+}
+
+///
+/// Реализует интерфейс сортировки
+/// Добавлет возможность сортировки по ID по возрастающей
+///
+class EmployeeByIdComparer : IComparer
+{
+ int IComparer.Compare(Employee? x, Employee? y)
+ {
+ if (x is Employee xx && y is Employee yy)
+ return xx.Id.CompareTo(yy.Id);
+ else
+ return 0;
+ }
+}
+
+///
+/// Фабричный шаблон для создания экземпляров IComparer
+///
+class ComparerFactory
+{
+ public static IComparer Create(Comparison comparer)
+ {
+ return new DelegateComparer(comparer);
+ }
+
+ private class DelegateComparer : IComparer
+ {
+ private readonly Comparison _comparer;
+
+ public DelegateComparer(Comparison comparer)
+ {
+ _comparer = comparer;
+ }
+
+ public int Compare(T? x, T? y)
+ {
+ if (x == null || y == null)
+ return 0;
+ return _comparer(x, y);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Strategy/Strategy.csproj b/Patterns/Strategy/Strategy.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Strategy/Strategy.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Strategy/WindowsEventLogReader.cs b/Patterns/Strategy/WindowsEventLogReader.cs
new file mode 100644
index 0000000..1ebe975
--- /dev/null
+++ b/Patterns/Strategy/WindowsEventLogReader.cs
@@ -0,0 +1,17 @@
+namespace Strategy;
+
+public class WindowsEventLogReader : ILogReader
+{
+ public List Read()
+ {
+ return new List()
+ {
+ new LogEntry()
+ {
+ DateTime = DateTime.Now,
+ Message = GetType().Name,
+ LogType = LogType.Debug
+ }
+ };
+ }
+}
diff --git a/Patterns/TemplateMethod/Program.cs b/Patterns/TemplateMethod/Program.cs
new file mode 100644
index 0000000..d6dfb74
--- /dev/null
+++ b/Patterns/TemplateMethod/Program.cs
@@ -0,0 +1,115 @@
+/* Шаблонный метод
+ Определяет алгоритм, некоторые этапы которого
+ делегируются подклассам. Позволяет подклассам
+ переопределить эти этапы, не меняя структуру алгоритма.
+ */
+class Program
+{
+ public static void Main(string[] args)
+ {
+ #region Пример №1 - базовое
+ new School().Learn();
+ new University().Learn();
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Представление образовательного процесса
+///
+abstract class Education
+{
+ ///
+ /// Обучение
+ ///
+ public virtual void Learn()
+ {
+ Enter();
+ Study();
+ PassExams();
+ GetDocument();
+ }
+
+ ///
+ /// Получение документа об окончании образования
+ ///
+ protected abstract void GetDocument();
+ ///
+ /// Cдача экзаменов в учебном заведении
+ ///
+ protected abstract void PassExams();
+ ///
+ /// Обучение в учебном заведении
+ ///
+ protected abstract void Study();
+ ///
+ /// Поступление в учебное заведение
+ ///
+ protected abstract void Enter();
+}
+
+///
+/// Школа реализовывающее процесс образования со своими дополнениями
+///
+class School : Education
+{
+ protected override void Enter()
+ {
+ Console.WriteLine("Поступил в школу");
+ }
+
+ protected override void GetDocument()
+ {
+ Console.WriteLine("Получил аттестат");
+ }
+
+ protected override void PassExams()
+ {
+ Console.WriteLine("Сдал ЕГЭ и ОГЭ");
+ }
+
+ public void ExtraExams()
+ {
+ Console.WriteLine("Ходил на олимпиады");
+ }
+
+ protected override void Study()
+ {
+ Console.WriteLine("Обучился 11 классов");
+ }
+
+ public override void Learn()
+ {
+ base.Learn();
+ ExtraExams();
+ }
+}
+
+///
+/// Университет реализовывающий процесса образования
+///
+class University : Education
+{
+ protected override void Enter()
+ {
+ Console.WriteLine("Поступил в университет");
+ }
+
+ protected override void GetDocument()
+ {
+ Console.WriteLine("Получил диплом");
+ }
+
+ protected override void PassExams()
+ {
+ Console.WriteLine("Сдал экзамены и зачёты");
+ }
+
+ protected override void Study()
+ {
+ Console.WriteLine("Ходил на пары");
+ Console.WriteLine("Ходил на лекции");
+ Console.WriteLine("Сдавал лабораторные работы");
+ }
+}
\ No newline at end of file
diff --git a/Patterns/TemplateMethod/TemplateMethod.csproj b/Patterns/TemplateMethod/TemplateMethod.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/TemplateMethod/TemplateMethod.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Patterns/Visitor/Program.cs b/Patterns/Visitor/Program.cs
new file mode 100644
index 0000000..322c1b2
--- /dev/null
+++ b/Patterns/Visitor/Program.cs
@@ -0,0 +1,138 @@
+/* Посетитель
+ Представляет собой операцию, которая
+ будет выполнена над объектами группы классов.
+ Даёт возможность определить новую операцию
+ без изменения кода классов, над которыми
+ эта операция производитcя.
+ */
+class Program
+{
+ public static void Main(string[] args)
+ {
+ #region Пример №1 - базовое
+ var bank = new Bank();
+ bank.Add(new Person(Name: "Joshua", Number: 1997));
+ bank.Add(new Company(Name: "Microsoft", Number: 1904));
+ bank.Accept(new HtmlVisitor());
+ bank.Accept(new XmlVisitor());
+ Console.ReadKey();
+ #endregion
+ }
+}
+
+///
+/// Поведение посетителя
+/// отделяет логику сериализации от классов в которых она применима
+///
+interface IVisitor
+{
+ void VisitPersonAcc(Person person);
+ void VisitCompanyAcc(Company company);
+}
+
+///
+/// Поведение аккаунта
+///
+interface IAccaunt
+{
+ void Accept(IVisitor visitor);
+}
+
+///
+/// Шаблон банка
+///
+class Bank
+{
+ List Accaunts;
+
+ public Bank()
+ {
+ Accaunts = new List();
+ }
+
+ ///
+ /// Добавить аккаунт
+ ///
+ /// аккаунт
+ public void Add(IAccaunt accaunt)
+ {
+ Accaunts.Add(accaunt);
+ }
+
+ ///
+ /// Удаллить аккаунт
+ ///
+ /// аккаунт
+ public void Remove(IAccaunt accaunt)
+ {
+ Accaunts.Remove(accaunt);
+ }
+
+ ///
+ /// Получить доступ к своему аккаунту
+ ///
+ /// пользователь
+ public void Accept(IVisitor visitor)
+ {
+ foreach (var accaunt in Accaunts)
+ accaunt.Accept(visitor);
+ }
+}
+
+///
+/// Пользователь
+///
+/// Имя
+/// Номер
+record Person(string Name, int Number) : IAccaunt
+{
+ public void Accept(IVisitor visitor)
+ {
+ visitor.VisitPersonAcc(this);
+ }
+}
+
+///
+/// Компания
+///
+/// Имя
+/// Номер
+record Company(string Name, int Number) : IAccaunt
+{
+ public void Accept(IVisitor visitor)
+ {
+ visitor.VisitCompanyAcc(this);
+ }
+}
+
+///
+/// HTML сериализатор
+///
+class HtmlVisitor : IVisitor
+{
+ public void VisitCompanyAcc(Company company)
+ {
+ Console.WriteLine($"[HTML] {company}");
+ }
+
+ public void VisitPersonAcc(Person person)
+ {
+ Console.WriteLine($"[HTML] {person}");
+ }
+}
+
+///
+/// XML сериализатор
+///
+class XmlVisitor : IVisitor
+{
+ public void VisitCompanyAcc(Company company)
+ {
+ Console.WriteLine($"[XML] {company}");
+ }
+
+ public void VisitPersonAcc(Person person)
+ {
+ Console.WriteLine($"[XML] {person}");
+ }
+}
\ No newline at end of file
diff --git a/Patterns/Visitor/Visitor.csproj b/Patterns/Visitor/Visitor.csproj
new file mode 100644
index 0000000..74abf5c
--- /dev/null
+++ b/Patterns/Visitor/Visitor.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..67c65c6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
🔱 Шаблоны проектирования 🔱
+
+
+## Описание содержимого 💼
+
+- ⌛ Определения: **class, abstract class, struct, interface, record**
+- ⌛ Разбор: **принципы SOLID, наследование, типы Dictionary, Unit тестирование**
+- ⌛ Бонус: **решение [LetCode](https://leetcode.com/) задач**
+- 😈 Такие паттерны как:
+>
+🌐 Behavioral - Поведенческие [11]🌐
+
+
+
+ Паттерн |
+ Краткое определение |
+
+
+
+
+ 💢 ChainOfResponsibility - Цепочка обязанностей |
+ 🔎 Избегает связывание отправителя запроса с его получателем, давая возможность обработать запрос более чем одному объекту. |
+
+
+ 💢 Command - Команда |
+ 🔎 Инкапсулирует запрос в виде объекта позволяя передавать их клиентам в качестве параметров, ставить в очередь, логировать, а также поддерживать отмену операций. |
+
+
+ 💢 Interpreter - Интерпретатор |
+ 🔎 Получая формальный язык, определяет представление его грамматики и интерпретатор, использующий это представление для обработки выражений языка. |
+
+
+ 💢 Iterator - Итератор |
+ 🔎 Предоставляет способ последовательного доступа к множеству, независимо от его внутреннего устройства. |
+
+
+ 💢 Mediator - Посредник |
+ 🔎 Определяет объект инкапсулирующий способ взаимодействия объектов. Обеспечивает слабую связь, избавляя их от необходимости ссылаться друг на друга и даёт возможность независимо изменять их взаимодействие. |
+
+
+ 💢 Memento - Хранитель |
+ 🔎 Не нарушая инкапсуляцию, определяет и сохраняет внутреннее состояние объекта и позволяет позже восстановить объект в этом состоянии. |
+
+
+ 💢 Observer - Наблюдатель |
+ 🔎 Определяет зависимость один ко многим между объектами так, что когда один меняет своё состояние, все зависимые объекты оповещаются и обновляются автоматически. |
+
+
+ 💢 State - Состояние |
+ 🔎 Позволяет объекту изменять своё поведение в зависимости от внутреннего состояния. |
+
+
+ 💢 Strategy - Стратегия |
+ 🔎 Определяет группу алгоритмов, инкапсулирует их и делает взаимозаменяемыми. Позволяет изменять алгоритм независимо от клиентов, его использующих. |
+
+
+ 💢 TemplateMethod - Шаблонный метод |
+ 🔎 Определяет алгоритм, некоторые этапы которого делегируются подклассам. Позволяет подклассам переопределить эти этапы, не меняя структуру алгоритма. |
+
+
+ 💢 Visitor - Посетитель |
+ 🔎 Представляет собой операцию, которая будет выполнена над объектами группы классов. Даёт возможность определить новую операцию без изменения кода классов, над которыми эта операция производитcя. |
+
+
+
+
+💡 Creational - Порождающие [6]💡
+
+
+
+ Паттерн |
+ Краткое определение |
+
+
+
+
+ 💢 AbstractFactory - Абстрактная фабрика |
+ 🔎 Предоставляет интерфейс для создания групп связанных или зависимых объектов, не указывая их конкретный класс. |
+
+
+ 💢 Builder - Строитель |
+ 🔎 Разделяет создание сложного объекта и его инициализацию так, что одинаковый процесс построения может может создавать объекты с разным состоянием. |
+
+
+ 💢 FactoryMethod - Фабричный метод |
+ 🔎 Определяет интерфейс для создания объекта, но позволяет подклассам решать, какой класс создавать. Позволяет делегировать создание класса объектам класса. |
+
+
+ 💢 FluentBuilder - Гибкий(плавный, текучий) строитель |
+ 🔎 Позволяет упростить процесс создания сложных объектов с помощью методов-цепочек, которые наделяют объект каким-то определенным качеством. |
+
+
+ 💢 Prototype - Прототип |
+ 🔎 Определяет несколько видов объектов, чтобы при создании использовать объект-прототип и создаёт новые объекты, копируя прототип (техника клонирования объектов). |
+
+
+ 💢 Singleton - Одиночка |
+ 🔎 Гарантирует что класс имеет только один экземпляр и представляет глобальную точку доступа к нему. |
+
+
+
+
+🏩 Structural - Структурные [7]🏩
+
+
+
+ Паттерн |
+ Краткое определение |
+
+
+
+
+ 💢 Adapter - Адаптер |
+ 🔎 Конвенртирует интерфейс класса в другой интерфейс, ожидаемый клиентом. Позволяет классам с разными интерфейсами работать вместе. |
+
+
+ 💢 Bridge - Мост |
+ 🔎 Разделяет абстракцию и реализацию так, чтобы они могли изменяться независимо друг от друга. |
+
+
+ 💢 Composite - Компоновщик |
+ 🔎 Компонует объекты в древовидную структуру по принципу "часть-целое", представляя их в виде иерархии. Позволяет клиенту одинаково обращаться как к отдельному, так и к целому поддереву. |
+
+
+ 💢 Decorator - Декоратор |
+ 🔎 Динамически предоставляет объекту дополнительные возможности. Представляет собой гибкую альтернативу наследованию для расширения функциональности. |
+
+
+ 💢 Facade - Фасад |
+ 🔎 Предоставляет единый интерфейс к группе интерфейсов подсистемы. Определяет высокоуровневый интерфейс, делая систему проще для использования. |
+
+
+ 💢 Flyweight - Приспособленец |
+ 🔎 Благодаря совместному использованию, поддерживает эффективную работу с большим количеством объектов. (для оптимизации работы с памятью) |
+
+
+ 💢 Proxy - Заместитель |
+ 🔎 Предоставляет объект-заместитель другого объекта для контроля доступа к нему. |
+
+
+
\ No newline at end of file