1.0
Main
This commit is contained in:
commit
3a28caed27
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -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
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.vs
|
||||||
|
Patterns/bin
|
||||||
|
Patterns/obj
|
121
LICENSE
Normal file
121
LICENSE
Normal file
@ -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.
|
11
Patterns/1_Принцип единственной обязанности/1_Принцип единственной обязанности.csproj
Normal file
11
Patterns/1_Принцип единственной обязанности/1_Принцип единственной обязанности.csproj
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<RootNamespace>_1_Принцип_единственной_обязанности</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
71
Patterns/1_Принцип единственной обязанности/Program.cs
Normal file
71
Patterns/1_Принцип единственной обязанности/Program.cs
Normal file
@ -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) -
|
||||||
|
* принцип ООП, обозначающий, что каждый объект должен иметь одну ответственность и эта
|
||||||
|
* ответственность должна быть полностью инкапсулирована в класс.
|
||||||
|
* Все его поведения должны быть направлены исключительно на обеспечение этой отвественности.
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// К примеру: Разработать класс который будет работать с изображениями
|
||||||
|
/// </summary>
|
||||||
|
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); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EMail сервис
|
||||||
|
/// Если отваливается модуль отправки Email
|
||||||
|
/// мы чиним только его, нам не требуется разбирать класс Image
|
||||||
|
/// </summary>
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<RootNamespace>_2_Принцип_открытости__закрытости</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
55
Patterns/2_Принцип открытости, закрытости/Program.cs
Normal file
55
Patterns/2_Принцип открытости, закрытости/Program.cs
Normal file
@ -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(""));
|
||||||
|
}
|
||||||
|
}
|
11
Patterns/3_Принцип подстановки Барбары Лисков/3_Принцип подстановки Барбары Лисков.csproj
Normal file
11
Patterns/3_Принцип подстановки Барбары Лисков/3_Принцип подстановки Барбары Лисков.csproj
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<RootNamespace>_3_Принцип_подстановки_Барбары_Лисков</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
127
Patterns/3_Принцип подстановки Барбары Лисков/Program.cs
Normal file
127
Patterns/3_Принцип подстановки Барбары Лисков/Program.cs
Normal file
@ -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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон летающей птицы
|
||||||
|
/// </summary>
|
||||||
|
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) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Полёт птицы
|
||||||
|
/// </summary>
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Движение птицы
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Move()
|
||||||
|
{
|
||||||
|
Fly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон бегущей птицы
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон отображеня движения
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<RootNamespace>_4_Принцип_разделения_интерфейсов</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
48
Patterns/4_Принцип разделения интерфейсов/Program.cs
Normal file
48
Patterns/4_Принцип разделения интерфейсов/Program.cs
Normal file
@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<RootNamespace>_5_Принцип_инверсии_зависимостей</RootNamespace>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
107
Patterns/5_Принцип инверсии зависимостей/Program.cs
Normal file
107
Patterns/5_Принцип инверсии зависимостей/Program.cs
Normal file
@ -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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение поиска в хранилищах информации
|
||||||
|
/// </summary>
|
||||||
|
public interface IFindStorage
|
||||||
|
{
|
||||||
|
List<Person> FindAll(Predicate<Person> predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон списка пользователей
|
||||||
|
/// </summary>
|
||||||
|
public class ListStorage : IFindStorage
|
||||||
|
{
|
||||||
|
private List<Person> storage;
|
||||||
|
public ListStorage()
|
||||||
|
{
|
||||||
|
storage = new List<Person>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Person> GetPersons() => storage;
|
||||||
|
|
||||||
|
public void Add(Person p) => storage.Add(p);
|
||||||
|
|
||||||
|
public List<Person> FindAll(Predicate<Person> predicate)
|
||||||
|
{
|
||||||
|
return storage.Where(e => predicate(e)).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон словаря пользователей
|
||||||
|
/// </summary>
|
||||||
|
public class DictionaryStorage : IFindStorage
|
||||||
|
{
|
||||||
|
private Dictionary<string, Person> storage;
|
||||||
|
public DictionaryStorage()
|
||||||
|
{
|
||||||
|
storage = new Dictionary<string, Person>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, Person> GetPersons() => storage;
|
||||||
|
|
||||||
|
public void Add(string key, Person p) => storage.Add(key, p);
|
||||||
|
|
||||||
|
public List<Person> FindAll(Predicate<Person> predicate)
|
||||||
|
{
|
||||||
|
return storage.Where(e => predicate(e.Value)).Select(e => e.Value).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Щаблон поисковика
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/AbstractFactory/AbstractFactory.csproj
Normal file
10
Patterns/AbstractFactory/AbstractFactory.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
148
Patterns/AbstractFactory/Program.cs
Normal file
148
Patterns/AbstractFactory/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Оружие базовая логика
|
||||||
|
/// </summary>
|
||||||
|
abstract class Weapon
|
||||||
|
{
|
||||||
|
public abstract void Hit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Движение базовая логика
|
||||||
|
/// </summary>
|
||||||
|
abstract class Movement
|
||||||
|
{
|
||||||
|
public abstract void Move();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Огнестрел
|
||||||
|
/// </summary>
|
||||||
|
class Gun : Weapon
|
||||||
|
{
|
||||||
|
public override void Hit()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hit Gun");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Арбалет
|
||||||
|
/// </summary>
|
||||||
|
class Arbalet : Weapon
|
||||||
|
{
|
||||||
|
public override void Hit()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hit Arbalet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Герой летает
|
||||||
|
/// </summary>
|
||||||
|
class Fly : Movement
|
||||||
|
{
|
||||||
|
public override void Move()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hero Fly");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Герой бежит
|
||||||
|
/// </summary>
|
||||||
|
class Run : Movement
|
||||||
|
{
|
||||||
|
public override void Move()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hero Run");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Супергерой
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстракция фабрика героев
|
||||||
|
/// </summary>
|
||||||
|
abstract class HeroFactory
|
||||||
|
{
|
||||||
|
public abstract Weapon CreateWeapon();
|
||||||
|
public abstract Movement CreateMovement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Эльфы
|
||||||
|
/// </summary>
|
||||||
|
class ElfFactory : HeroFactory
|
||||||
|
{
|
||||||
|
public override Movement CreateMovement()
|
||||||
|
{
|
||||||
|
return new Fly();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Weapon CreateWeapon()
|
||||||
|
{
|
||||||
|
return new Arbalet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Солдаты
|
||||||
|
/// </summary>
|
||||||
|
class SoldierFactory : HeroFactory
|
||||||
|
{
|
||||||
|
public override Movement CreateMovement()
|
||||||
|
{
|
||||||
|
return new Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Weapon CreateWeapon()
|
||||||
|
{
|
||||||
|
return new Gun();
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Adapter/Adapter.csproj
Normal file
10
Patterns/Adapter/Adapter.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
78
Patterns/Adapter/Program.cs
Normal file
78
Patterns/Adapter/Program.cs
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон автомобиля
|
||||||
|
/// </summary>
|
||||||
|
class Auto : ITransport
|
||||||
|
{
|
||||||
|
public void Drive()
|
||||||
|
{
|
||||||
|
Console.WriteLine(GetType().Name + " Move");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон верблюда
|
||||||
|
/// </summary>
|
||||||
|
class Camel
|
||||||
|
{
|
||||||
|
public void Move()
|
||||||
|
{
|
||||||
|
Console.WriteLine(GetType().Name + " Move");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон движения верблюда
|
||||||
|
/// </summary>
|
||||||
|
class CamelToTransport : ITransport
|
||||||
|
{
|
||||||
|
Camel camel;
|
||||||
|
|
||||||
|
public CamelToTransport(Camel camel)
|
||||||
|
{
|
||||||
|
this.camel = camel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Drive()
|
||||||
|
{
|
||||||
|
camel.Move();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон путешественника
|
||||||
|
/// </summary>
|
||||||
|
class Driver
|
||||||
|
{
|
||||||
|
public void Travel(ITransport transport)
|
||||||
|
{
|
||||||
|
transport.Drive();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
6
Patterns/Base.UserLibrary.Tests/TestData.xml
Normal file
6
Patterns/Base.UserLibrary.Tests/TestData.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserDetails>
|
||||||
|
<User userId="Ivan" email="aspkx@mail.ru" />
|
||||||
|
<User userId="Nikolay" email="aspkx@mail.ru" />
|
||||||
|
<User userId="Oleg" email="aspkx@mail.ru" />
|
||||||
|
</UserDetails>
|
31
Patterns/Base.UserLibrary.Tests/UnitTest1.cs
Normal file
31
Patterns/Base.UserLibrary.Tests/UnitTest1.cs
Normal file
@ -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();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DataSource - îïðåäåëåíèå èñòî÷íèêà äàííûõ
|
||||||
|
/// 1 ïàðàìåòð - èìÿ ïðîâàéäåðà
|
||||||
|
/// 2 ïàðàìåòð - ñòðîêà ïîäêëþ÷åíèÿ èëè ïóòü ê ôàéëó
|
||||||
|
/// 3 ïàðàìåòð - èìÿ òàáëèöû èëè ýëåìåíòà XML
|
||||||
|
/// 4 ïàðàìåòð - êàê ïðîèñõîäèò äîñòóï ê çàïèñÿì èç èñòî÷íèêà äàííûõ
|
||||||
|
/// </summary>
|
||||||
|
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML",
|
||||||
|
"TestData.xml",
|
||||||
|
"User",
|
||||||
|
DataAccessMethod.Sequential)]
|
||||||
|
[TestMethod]
|
||||||
|
public void AddDataTest()
|
||||||
|
{
|
||||||
|
string userId = Convert.ToString(TestContextInstance.DataRow["Row1"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
Patterns/Base.UserLibrary.Tests/Usings.cs
Normal file
1
Patterns/Base.UserLibrary.Tests/Usings.cs
Normal file
@ -0,0 +1 @@
|
|||||||
|
global using Microsoft.VisualStudio.TestTools.UnitTesting;
|
28
Patterns/Base.cs
Normal file
28
Patterns/Base.cs
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
26
Patterns/Base/AssertMsTest.cs
Normal file
26
Patterns/Base/AssertMsTest.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
namespace Base;
|
||||||
|
|
||||||
|
public class AssertMsTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получить квадратный корень
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Значение</param>
|
||||||
|
/// <returns>double</returns>
|
||||||
|
public static double GetSqrt(double value)
|
||||||
|
{
|
||||||
|
return Math.Sqrt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить приветствие
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Имя</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="ArgumentNullException">пустое имя</exception>
|
||||||
|
public string SayHello(string name)
|
||||||
|
{
|
||||||
|
if (name == null) throw new ArgumentNullException("Parameter name can not be null");
|
||||||
|
return "Hi! " + name;
|
||||||
|
}
|
||||||
|
}
|
14
Patterns/Base/BaseInfo.csproj
Normal file
14
Patterns/Base/BaseInfo.csproj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
17
Patterns/Base/Extension.cs
Normal file
17
Patterns/Base/Extension.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Base
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тестовый класс статических реализаций
|
||||||
|
/// </summary>
|
||||||
|
internal static class Extension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Тестовый статический метод
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="classMain">Представитель определённого поведения</param>
|
||||||
|
public static void ResizeExt(this IInterTest classMain)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Resize Class Extension");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
410
Patterns/Base/Program.cs
Normal file
410
Patterns/Base/Program.cs
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using static Base.Records;
|
||||||
|
|
||||||
|
namespace Base;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Важно: ссылочные типы лежат в куче, значимые - ссылка в куче, значение в стеке
|
||||||
|
/// ***
|
||||||
|
/// Шаблон, по которому определяется форма объекта
|
||||||
|
/// Определение:
|
||||||
|
/// Класс - это ссылочный тип данных, шаблон по которому определяется объект, информацию о себе хранит в куче.
|
||||||
|
/// </summary>
|
||||||
|
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<Records>(json);
|
||||||
|
Console.WriteLine(otherSideRecord);
|
||||||
|
Records = Records with { Id = 10 };
|
||||||
|
Console.WriteLine(Records);
|
||||||
|
Console.ReadKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстракция которая отвечает за контракт взаимодействия для различных типов
|
||||||
|
/// Определение:
|
||||||
|
/// Интерфейс - это ссылочный тип данных, представляющий контракт взаимодействия (поведение).
|
||||||
|
/// Этот контракт гласит о том что должен содержать class или struct.
|
||||||
|
/// Формирует общий признак для разнородных объектов
|
||||||
|
/// </summary>
|
||||||
|
public interface IInterTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Декларация - метод без реализации по умолчанию
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="build"></param>
|
||||||
|
void Build(int build = 0);
|
||||||
|
/// <summary>
|
||||||
|
/// После C# 8.0 можно указывать реализацию метода в интерфейсе
|
||||||
|
/// </summary>
|
||||||
|
void Relocate()
|
||||||
|
{
|
||||||
|
Console.WriteLine("-> IInterTest: Relocate");
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Cигнатура - операция без реализации - абстрактный метод
|
||||||
|
/// </summary>
|
||||||
|
abstract void Reload();
|
||||||
|
/// <summary>
|
||||||
|
/// Делегат - ссылочный тип
|
||||||
|
/// </summary>
|
||||||
|
delegate void Destiny();
|
||||||
|
/// <summary>
|
||||||
|
/// Cвойство - ссылочный тип
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Cвойство - ссылочный тип
|
||||||
|
/// </summary>
|
||||||
|
object ID { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстрактный класс
|
||||||
|
/// Определение:
|
||||||
|
/// Абстрактный класс - это ссылочный тип данных, для описания общности сущностей, которые не имеют конкретного воплощения
|
||||||
|
/// </summary>
|
||||||
|
public abstract class AbstrTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Поле
|
||||||
|
/// </summary>
|
||||||
|
public int key = 100;
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор без параметров
|
||||||
|
/// </summary>
|
||||||
|
public AbstrTest()
|
||||||
|
{
|
||||||
|
key = 110;
|
||||||
|
Name = "Fire";
|
||||||
|
Console.WriteLine($"->AbstrTest {Name} {key}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор с параметрами
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">ключ</param>
|
||||||
|
public AbstrTest(int key)
|
||||||
|
{
|
||||||
|
this.key = key;
|
||||||
|
Name = "Fire";
|
||||||
|
Console.WriteLine($"->AbstrTest {Name} {key}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод - это фиксированная операция с реализацией по умолчанию
|
||||||
|
/// </summary>
|
||||||
|
public void Move()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Move Abstr");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Виртуальный метод - операция с реализацией по умолчанию
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Resize()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Resize Abstr");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстрактный метод - сигнатура - операция без реализации
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Определение:
|
||||||
|
/// Структура - это значимый тип данных, ссылка на структуру хранится в куче, значение в стеке
|
||||||
|
/// Тот же класс, меняется тип данных
|
||||||
|
/// </summary>
|
||||||
|
public struct TestStruct : IInterTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство имени
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство идентификатора
|
||||||
|
/// </summary>
|
||||||
|
public object ID { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор без параметров
|
||||||
|
/// </summary>
|
||||||
|
public TestStruct()
|
||||||
|
{
|
||||||
|
Name = "Base";
|
||||||
|
ID = (object)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод с реализацией с параметрами
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="build">#</param>
|
||||||
|
public void Build(int build = 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Build TestStruct {build}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод с реализацией без параметров
|
||||||
|
/// </summary>
|
||||||
|
public void Reload()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Reload TestStruct");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация поведения класса
|
||||||
|
/// </summary>
|
||||||
|
public class ClassMain : AbstrTest, IInterTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство
|
||||||
|
/// </summary>
|
||||||
|
public int countBuild { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство от интерфейса
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство от интерфейса
|
||||||
|
/// </summary>
|
||||||
|
public object ID { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструтор + реализация поведения конструктора абстрактного класса
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструтор c параметрами + реализация поведения конструктора абстрактного класса
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="build">#</param>
|
||||||
|
/// <param name="name">#</param>
|
||||||
|
/// <param name="id">#</param>
|
||||||
|
public ClassMain(int build, string name, object id) : base(build)
|
||||||
|
{
|
||||||
|
countBuild = build;
|
||||||
|
Name = name;
|
||||||
|
ID = id;
|
||||||
|
Move();
|
||||||
|
Build(build);
|
||||||
|
Reload();
|
||||||
|
Resize();
|
||||||
|
Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Виртуальный метод
|
||||||
|
/// </summary>
|
||||||
|
public virtual void GG()
|
||||||
|
{
|
||||||
|
Console.WriteLine("GG Virtual Method Class");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод с параметрами
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="build">#</param>
|
||||||
|
public void Build(int build = 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Build Interface Class {build}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Метод без параметров обязательный к реализации от интерфейса
|
||||||
|
/// </summary>
|
||||||
|
public void Reload()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Reload Interface Abstract Method Class");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация virtual метода абстрактного класса
|
||||||
|
/// </summary>
|
||||||
|
public override void Resize()
|
||||||
|
{
|
||||||
|
base.Resize();
|
||||||
|
countBuild--;
|
||||||
|
Console.WriteLine("Resize Class");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Переопределение сигнатуры абстрактного класса
|
||||||
|
/// </summary>
|
||||||
|
public override void Open()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Open Abstract Method Class");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация деструктора класса
|
||||||
|
/// </summary>
|
||||||
|
~ClassMain()
|
||||||
|
{
|
||||||
|
Console.WriteLine("###Destroy ClassMain");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация наследования (3 принцип ООП)
|
||||||
|
/// Определение:
|
||||||
|
/// Наследование - это возможность создания новых абстракций на основе существующих.
|
||||||
|
/// Наследование является ключевой функцией объектно-ориентированных языков программирования.
|
||||||
|
/// Оно позволяет определить базовый класс для определенных функций (доступа к данным или действий),
|
||||||
|
/// а затем создавать производные классы, которые наследуют или переопределяют функции базового класса.
|
||||||
|
/// </summary>
|
||||||
|
public class Nasled : ClassMain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Необязательное перепределение виртуального метода главного класса
|
||||||
|
/// </summary>
|
||||||
|
public override void GG()
|
||||||
|
{
|
||||||
|
base.GG();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Определение:
|
||||||
|
/// Records - это ссылочный тип, некая модификация возможностей классов
|
||||||
|
/// Ключевая особенность - может представлять неизменяемый тип данных (immutable)
|
||||||
|
/// Также имеет особенность в виде встроенного JSON представления при выводе в строку
|
||||||
|
/// Имеет возможность управлять своим деконструктором
|
||||||
|
/// </summary>
|
||||||
|
public record class Records
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство идентификатора
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство имени
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструктор с параметрами
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">идентификатор</param>
|
||||||
|
/// <param name="name">имя</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Деконструктор
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">имя</param>
|
||||||
|
/// <param name="id">идентификатор</param>
|
||||||
|
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; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Деконструктор
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">имя</param>
|
||||||
|
/// <param name="id">идентификатор</param>
|
||||||
|
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; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Деконструктор
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">имя</param>
|
||||||
|
/// <param name="id">идентификатор</param>
|
||||||
|
public void Deconstruct(out string name, out int id)
|
||||||
|
{
|
||||||
|
name = Names;
|
||||||
|
id = Ida;
|
||||||
|
Console.WriteLine("Destruct Job");
|
||||||
|
}
|
||||||
|
}
|
31
Patterns/BaseTests/000_TestsMain.cs
Normal file
31
Patterns/BaseTests/000_TestsMain.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Base;
|
||||||
|
|
||||||
|
namespace BaseTests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Модульный тест
|
||||||
|
/// Конфигурирование:
|
||||||
|
/// Чтобы добавить возможность вызывать методы какого-либо проекта
|
||||||
|
/// Нажимаем правой кнопкой на зависимости в данном проекте
|
||||||
|
/// Выбираем пункт - добавить ссылку на проект
|
||||||
|
/// </summary>
|
||||||
|
[TestClass]
|
||||||
|
public class TestsMain
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация тестового метода модульного теста
|
||||||
|
/// </summary>
|
||||||
|
[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"); //сравниваем полученное значение с требуемым
|
||||||
|
}
|
||||||
|
}
|
38
Patterns/BaseTests/001_TestInitAndCleanUp.cs
Normal file
38
Patterns/BaseTests/001_TestInitAndCleanUp.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Base.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class TestInitAndCleanUp
|
||||||
|
{
|
||||||
|
private ClassMain main;
|
||||||
|
private string Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запускается перед каждым тестируемым методом
|
||||||
|
/// </summary>
|
||||||
|
[TestInitialize]
|
||||||
|
public void TestInitialize()
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Test Initialize");
|
||||||
|
main = new ClassMain();
|
||||||
|
main.Name = "Nikolay";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запускается после каждого завершения тестирования метода
|
||||||
|
/// </summary>
|
||||||
|
[TestCleanup]
|
||||||
|
public void MainCleanUp()
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Test CleanUp");
|
||||||
|
Name = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AddName()
|
||||||
|
{
|
||||||
|
Name = "Nikolay";
|
||||||
|
Assert.AreEqual(Name, main.Name);
|
||||||
|
}
|
||||||
|
}
|
41
Patterns/BaseTests/002_ClassInitAndCleanUp.cs
Normal file
41
Patterns/BaseTests/002_ClassInitAndCleanUp.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Base.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ClassInitAndCleanUp
|
||||||
|
{
|
||||||
|
private static ClassMain main;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запускается один раз перед тем как запустится один Unit Test
|
||||||
|
/// Метод должен быть открытым, статическим и принимать параметр типа контекста
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
[ClassInitialize]
|
||||||
|
public static void ClassInitialize(TestContext context)
|
||||||
|
{
|
||||||
|
main = new ClassMain();
|
||||||
|
main.Name = "Test";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запускается после последнего тестируемого метода
|
||||||
|
/// Метод должен быть открытым, статическим и возвращать void
|
||||||
|
/// </summary>
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
26
Patterns/BaseTests/003_AssemblyInit.cs
Normal file
26
Patterns/BaseTests/003_AssemblyInit.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
namespace Base.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class AssemblyInit
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Код выполняется один раз на всю сборку
|
||||||
|
/// Используется во всех Unit тестах во всех тестовых вкладках
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="testContext"></param>
|
||||||
|
[AssemblyInitialize]
|
||||||
|
public static void TestMethodInit(TestContext testContext)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Test AssemblyInitialize: " + testContext.TestName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Код выполняется один раз на всю сборку
|
||||||
|
/// Используется во всех Unit тестах во всех тестовых вкладках
|
||||||
|
/// </summary>
|
||||||
|
[AssemblyCleanup]
|
||||||
|
public static void TestMethodGlobalCleanUp()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Test AssemblyCleanup");
|
||||||
|
}
|
||||||
|
}
|
65
Patterns/BaseTests/004_AssertMethods.cs
Normal file
65
Patterns/BaseTests/004_AssertMethods.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
65
Patterns/BaseTests/005_CollectionAssertMethods.cs
Normal file
65
Patterns/BaseTests/005_CollectionAssertMethods.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
namespace Base.Tests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверяет результат работы с коллекциями
|
||||||
|
/// </summary>
|
||||||
|
[TestClass]
|
||||||
|
public class CollectionAssertMethods
|
||||||
|
{
|
||||||
|
public static List<string> employees;
|
||||||
|
|
||||||
|
[ClassInitialize]
|
||||||
|
public static void InitializeCurrentTest(TestContext context)
|
||||||
|
{
|
||||||
|
employees = new List<string>();
|
||||||
|
|
||||||
|
employees.Add("Nikolay");
|
||||||
|
employees.Add("Oleg");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка значений коллекции на наличие в ней
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void AllItemAreNotNullTest()
|
||||||
|
{
|
||||||
|
CollectionAssert.AllItemsAreNotNull(employees, "Not null failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка значения коллекции на уникальность
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void AllItemsAreUniqueTest()
|
||||||
|
{
|
||||||
|
CollectionAssert.AllItemsAreUnique(employees, "Uniqueness failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверяет каждый элемент списка на равенство с входящим списком
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void AreEqualTest()
|
||||||
|
{
|
||||||
|
var currList = new List<string>();
|
||||||
|
|
||||||
|
currList.Add("Nikolay");
|
||||||
|
currList.Add("Oleg");
|
||||||
|
|
||||||
|
CollectionAssert.AreEqual(currList, employees);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверяем наличии одного List в другом
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void SubsetTest()
|
||||||
|
{
|
||||||
|
var subsetList = new List<string>();
|
||||||
|
|
||||||
|
subsetList.Add(employees[1]);
|
||||||
|
//subsetList.Add("Mig"); //ошибка так как этот элемент не входит в employees
|
||||||
|
|
||||||
|
CollectionAssert.IsSubsetOf(subsetList, employees, "not elements subsetList to employees");
|
||||||
|
}
|
||||||
|
}
|
44
Patterns/BaseTests/006_StringAssetMethods.cs
Normal file
44
Patterns/BaseTests/006_StringAssetMethods.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Base.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class StringAssetMethods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка подстроки в строке
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void StringContainsTest()
|
||||||
|
{
|
||||||
|
StringAssert.Contains("Assert samples", "sam");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ПРоверка с использованием регулярного выражения
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void StringMathesTest()
|
||||||
|
{
|
||||||
|
// проверяет наличие трёх цифр подряд
|
||||||
|
StringAssert.Matches("123", new Regex(@"\d{3}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка начала строки на соответствие условию
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void StringStartsWithTest()
|
||||||
|
{
|
||||||
|
StringAssert.StartsWith("Hello London", "H");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка конца строки на соответствие условию
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void StringEndWithTest()
|
||||||
|
{
|
||||||
|
StringAssert.EndsWith("Hello Moscow", "w");
|
||||||
|
}
|
||||||
|
}
|
27
Patterns/BaseTests/007_ExpectingExceptions.cs
Normal file
27
Patterns/BaseTests/007_ExpectingExceptions.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
namespace Base.Tests;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ExpectingExceptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Проверка метода на возврат исключения
|
||||||
|
/// </summary>
|
||||||
|
[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}");
|
||||||
|
}
|
||||||
|
}
|
22
Patterns/BaseTests/Base.Tests.csproj
Normal file
22
Patterns/BaseTests/Base.Tests.csproj
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Base\BaseInfo.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
1
Patterns/BaseTests/Usings.cs
Normal file
1
Patterns/BaseTests/Usings.cs
Normal file
@ -0,0 +1 @@
|
|||||||
|
global using Microsoft.VisualStudio.TestTools.UnitTesting;
|
10
Patterns/Bridge/Bridge.csproj
Normal file
10
Patterns/Bridge/Bridge.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
96
Patterns/Bridge/Program.cs
Normal file
96
Patterns/Bridge/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение языка
|
||||||
|
/// </summary>
|
||||||
|
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("Получаем оплату в конце месяца");
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Builder/Builder.csproj
Normal file
10
Patterns/Builder/Builder.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
120
Patterns/Builder/Program.cs
Normal file
120
Patterns/Builder/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Мука
|
||||||
|
/// </summary>
|
||||||
|
class Floor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Сорт муки
|
||||||
|
/// </summary>
|
||||||
|
public string Sort { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Соль
|
||||||
|
/// </summary>
|
||||||
|
class Salt
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Масса
|
||||||
|
/// </summary>
|
||||||
|
public double Mass { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пищевые добавки
|
||||||
|
/// </summary>
|
||||||
|
class Additives
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Список пищевых добавок
|
||||||
|
/// </summary>
|
||||||
|
public string[] Names { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Xлеб
|
||||||
|
/// </summary>
|
||||||
|
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]}]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Строитель хлеба
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пекарь
|
||||||
|
/// </summary>
|
||||||
|
class Baker
|
||||||
|
{
|
||||||
|
public Bread Bake(BreadBuilder breadBuilder)
|
||||||
|
{
|
||||||
|
breadBuilder.CreateBread();
|
||||||
|
breadBuilder.SetFloor();
|
||||||
|
breadBuilder.SetSalt();
|
||||||
|
breadBuilder.SetAdditives();
|
||||||
|
return breadBuilder.Bread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Для ржаного хлеба строитель
|
||||||
|
/// </summary>
|
||||||
|
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 };
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/ChainOfResponsibility/ChainOfResponsibility.csproj
Normal file
10
Patterns/ChainOfResponsibility/ChainOfResponsibility.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
165
Patterns/ChainOfResponsibility/Program.cs
Normal file
165
Patterns/ChainOfResponsibility/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Передатчик
|
||||||
|
/// </summary>
|
||||||
|
abstract class Handler
|
||||||
|
{
|
||||||
|
public Handler Successor { get; set; }
|
||||||
|
public abstract void HandleRequest(int condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обработчик запроса №1
|
||||||
|
/// </summary>
|
||||||
|
class ConcreateHandler1 : Handler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обработка запроса
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="condition">состояние</param>
|
||||||
|
public override void HandleRequest(int condition)
|
||||||
|
{
|
||||||
|
Console.WriteLine("1");
|
||||||
|
if(condition == 1) return; //завершаем выполнение
|
||||||
|
else if(Successor != null)
|
||||||
|
Successor.HandleRequest(condition); //передача запроса дальше по цепи
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обработчик запроса №2
|
||||||
|
/// </summary>
|
||||||
|
class ConcreateHandler2 : Handler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обработка запроса
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="condition">состояние</param>
|
||||||
|
public override void HandleRequest(int condition)
|
||||||
|
{
|
||||||
|
Console.WriteLine("2");
|
||||||
|
if (condition == 2) return; //завершаем выполнение
|
||||||
|
else if (Successor != null) //передача запроса дальше по цепи
|
||||||
|
Successor.HandleRequest(condition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение рабочего
|
||||||
|
/// </summary>
|
||||||
|
interface IWorker
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Передача обязанностей следующему рабочему
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="worker">следующий рабочий</param >
|
||||||
|
IWorker SetNetWorker(IWorker worker);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Рабочий принимает команду на исполнение
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">команда</param>
|
||||||
|
/// <returns>Резульат принятия</returns>
|
||||||
|
string Execute(string command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстрактный рабочий, базовое описание структуры каждого
|
||||||
|
/// </summary>
|
||||||
|
abstract class AbsWorker : IWorker
|
||||||
|
{
|
||||||
|
private IWorker nextWorker;
|
||||||
|
public AbsWorker() => nextWorker = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Изменяемый процесс обработки команды в классах наследниках
|
||||||
|
/// У каждого рабочего свой процесс выполнени
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">команда</param>
|
||||||
|
/// <returns>Результат</returns>
|
||||||
|
public virtual string Execute(string command)
|
||||||
|
{
|
||||||
|
if (nextWorker == null) return string.Empty;
|
||||||
|
return nextWorker.Execute(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Передача обязанностей другому рабочему
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="worker">Другой рабочий</param>
|
||||||
|
/// <returns>Другой рабочий</returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Command/Command.csproj
Normal file
10
Patterns/Command/Command.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
225
Patterns/Command/Program.cs
Normal file
225
Patterns/Command/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Описания общего поведения объекта
|
||||||
|
/// </summary>
|
||||||
|
abstract class Command
|
||||||
|
{
|
||||||
|
public abstract void Execute();
|
||||||
|
public abstract void Undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Описание процесса создания команды
|
||||||
|
/// </summary>
|
||||||
|
class ConcreteCommand : Command
|
||||||
|
{
|
||||||
|
Receiver receiver;
|
||||||
|
|
||||||
|
public ConcreteCommand(Receiver receiver)
|
||||||
|
{
|
||||||
|
this.receiver = receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Инициализация команды
|
||||||
|
/// *вызывает его получателя
|
||||||
|
/// </summary>
|
||||||
|
public override void Execute()
|
||||||
|
{
|
||||||
|
receiver.Operation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Остановка команды
|
||||||
|
/// </summary>
|
||||||
|
public override void Undo()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Stop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Описание возможностей получателя команды
|
||||||
|
/// </summary>
|
||||||
|
class Receiver
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обработка получателем команды
|
||||||
|
/// </summary>
|
||||||
|
public void Operation()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Processing...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Описание инициатора команды
|
||||||
|
/// </summary>
|
||||||
|
class Invoker
|
||||||
|
{
|
||||||
|
Command command;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Принимает в себя команду
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">#</param>
|
||||||
|
public Invoker(Command command)
|
||||||
|
{
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запускает команду
|
||||||
|
/// </summary>
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
command.Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Отменяет выполнение команды
|
||||||
|
/// </summary>
|
||||||
|
public void Cancel()
|
||||||
|
{
|
||||||
|
command.Undo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение команды
|
||||||
|
/// </summary>
|
||||||
|
interface ICommand
|
||||||
|
{
|
||||||
|
void Positive();
|
||||||
|
void Negative();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс конвеера
|
||||||
|
/// </summary>
|
||||||
|
class Conveyor
|
||||||
|
{
|
||||||
|
public void On() => Console.WriteLine("Включение конвеера");
|
||||||
|
|
||||||
|
public void Off() => Console.WriteLine("Выключение конвеера");
|
||||||
|
|
||||||
|
public void SpeedIncrease() => Console.WriteLine("Скорость конвеера увеличена");
|
||||||
|
|
||||||
|
public void SpeedDecrease() => Console.WriteLine("Скорость конвеера снижена");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс управления работой конвеера
|
||||||
|
/// </summary>
|
||||||
|
class ConveyorWorkCommand : ICommand
|
||||||
|
{
|
||||||
|
public Conveyor conveer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Передача типа конвеера в конструторе
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conveer">тип</param>
|
||||||
|
public ConveyorWorkCommand(Conveyor conveer) => this.conveer = conveer;
|
||||||
|
|
||||||
|
public void Negative() => conveer.Off();
|
||||||
|
|
||||||
|
public void Positive() => conveer.On();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс регулировки конвеера
|
||||||
|
/// </summary>
|
||||||
|
class ConveyorAjustCommand : ICommand
|
||||||
|
{
|
||||||
|
public Conveyor conveer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Передача типа конвеера в конструторе
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conveer">тип</param>
|
||||||
|
public ConveyorAjustCommand(Conveyor conveer) => this.conveer = conveer;
|
||||||
|
|
||||||
|
public void Negative() => conveer.SpeedDecrease();
|
||||||
|
|
||||||
|
public void Positive() => conveer.SpeedIncrease();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пульт управления конвеером
|
||||||
|
/// </summary>
|
||||||
|
class Multipult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Все возможные команды
|
||||||
|
/// </summary>
|
||||||
|
private List<ICommand> commands;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// История выполненных команд для возможной их отмены
|
||||||
|
/// </summary>
|
||||||
|
private Stack<ICommand> history;
|
||||||
|
|
||||||
|
public Multipult()
|
||||||
|
{
|
||||||
|
commands = new List<ICommand>() { null, null };
|
||||||
|
history = new Stack<ICommand>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Устанавлием список команд по индексу кнопки
|
||||||
|
/// </summary>
|
||||||
|
public void SetCommand(int btn, ICommand command) => commands[btn] = command;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Вызывает команду из списка по указанному индексу
|
||||||
|
/// и запишет в историю команд выполненную команду
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="btn">идекс кнопки</param>
|
||||||
|
public void PressOn(int btn)
|
||||||
|
{
|
||||||
|
commands[btn].Positive();
|
||||||
|
history.Push(commands[btn]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Извлекает команду из истории и отменяет её
|
||||||
|
/// </summary>
|
||||||
|
public void PressCansel()
|
||||||
|
{
|
||||||
|
if(history.Count == 0) return;
|
||||||
|
var oldC = history.Pop();
|
||||||
|
oldC.Negative();
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Composite/Composite.csproj
Normal file
10
Patterns/Composite/Composite.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
129
Patterns/Composite/Program.cs
Normal file
129
Patterns/Composite/Program.cs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/* Компоновщик
|
||||||
|
Компонует объекты в древовидную структуру по принципу "часть-целое",
|
||||||
|
представляя их в виде иерархии. Позволяет
|
||||||
|
клиенту одинаково обращаться как к отдельному,
|
||||||
|
так и к целому поддереву
|
||||||
|
*/
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
#region Пример №1 - базовое
|
||||||
|
var paths = new Paths(new Dictionary<int, Directory>());
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстракция компонента файловой системы (дерева) - пути до файла
|
||||||
|
/// </summary>
|
||||||
|
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<int,Directory> components;
|
||||||
|
|
||||||
|
public Paths(Dictionary<int, Directory> 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<Component> 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");
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Decorator/Decorator.csproj
Normal file
10
Patterns/Decorator/Decorator.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
62
Patterns/Decorator/Program.cs
Normal file
62
Patterns/Decorator/Program.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Dict/DictionaryInfo.csproj
Normal file
10
Patterns/Dict/DictionaryInfo.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
116
Patterns/Dict/Program.cs
Normal file
116
Patterns/Dict/Program.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Стандартный Dictionary
|
||||||
|
/// Быстрый поиск с помощью ключей, можно добавлять и удалять элементы
|
||||||
|
/// </summary>
|
||||||
|
private static readonly Dictionary<string, object> Dictionary = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ListDictionary
|
||||||
|
/// Он меньше и быстрее, чем Hashtable если количество элементов равно 10 или меньше
|
||||||
|
/// </summary>
|
||||||
|
private static readonly ListDictionary LDictionary = new()
|
||||||
|
{
|
||||||
|
{ "key", "value"}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HybridDictionary
|
||||||
|
/// Рекомендуется для случаев, когда количество элементов в словаре неизвестно.
|
||||||
|
/// Он использует улучшенную производительность ListDictionary с небольшими коллекциями
|
||||||
|
/// и предлагает гибкость переключения на Hashtable , которая обрабатывает большие коллекции лучше
|
||||||
|
/// </summary>
|
||||||
|
private static readonly HybridDictionary HDictionary = new()
|
||||||
|
{
|
||||||
|
{ "key", "value"}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OrderedDictionary
|
||||||
|
/// Он всегда упорядочен при выводе foreach
|
||||||
|
/// Ключ не может быть нулевым , но значение может быть.
|
||||||
|
/// Каждый элемент представляет собой пару ключ/значение, хранящуюся в объекте DictionaryEntry
|
||||||
|
/// Доступ к элементам возможен либо по ключу, либо по индексу.
|
||||||
|
/// [!]
|
||||||
|
/// если элементов больше 20-ти быстрее при цикле for
|
||||||
|
/// если элементов меньше 15-20 быстрее в foreach чем for
|
||||||
|
/// </summary>
|
||||||
|
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"}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SortedDictionary
|
||||||
|
/// Дерево бинарного поиска, в котором все элементы отсортированы на основе ключа
|
||||||
|
/// Быстрее вставляет и удаляет элементы
|
||||||
|
/// </summary>
|
||||||
|
private static readonly SortedDictionary<int, string> SDictionary = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ConcurrentDictionary
|
||||||
|
/// Потокобезопасная коллекция пар "ключ-значение", доступ к которой могут одновременно получать несколько потоков.
|
||||||
|
/// по умолчанию 4 потока на запись concurrencyLevel = 4
|
||||||
|
/// первоначальное число элементов 31 сapacity = 31
|
||||||
|
/// В отличие от обычного Dictionary, можно производить вставку в ConcurrentDictionary или удаление из него прямо во время перечисления
|
||||||
|
/// </summary>
|
||||||
|
private static readonly ConcurrentDictionary<int, string> С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();
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Facade/Facade.csproj
Normal file
10
Patterns/Facade/Facade.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
55
Patterns/Facade/Program.cs
Normal file
55
Patterns/Facade/Program.cs
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/FactoryMethod/FactoryMethod.csproj
Normal file
10
Patterns/FactoryMethod/FactoryMethod.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
120
Patterns/FactoryMethod/Program.cs
Normal file
120
Patterns/FactoryMethod/Program.cs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* Фабричный метод
|
||||||
|
Определяет интерфейс для создания объекта,
|
||||||
|
но позволяет подклассам решать, какой класс создавать.
|
||||||
|
Позволяет делегировать создание класса
|
||||||
|
объектам класса.
|
||||||
|
*/
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
#region Пример №1 - базовое
|
||||||
|
var ltd = new WoodDeveloper();
|
||||||
|
ltd.Create();
|
||||||
|
|
||||||
|
var rss = new OfficeDeveloper();
|
||||||
|
rss.Create();
|
||||||
|
|
||||||
|
Creator<WoodDeveloper> ltdEx = new Creator<WoodDeveloper>();
|
||||||
|
var a1 = ltdEx.FactoryMethod();
|
||||||
|
a1.Create();
|
||||||
|
Creator<OfficeDeveloper> rssEx = new Creator<OfficeDeveloper>();
|
||||||
|
var a2 = rssEx.FactoryMethod();
|
||||||
|
a2.Create();
|
||||||
|
|
||||||
|
Console.ReadKey();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// *** представления через обобщения (нельзя инициализировать через параметризированный конструктор)
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">обобщающий тип</typeparam>
|
||||||
|
class Creator<T> where T : Developer, new()
|
||||||
|
{
|
||||||
|
public T FactoryMethod() { return new T(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cтроительная компания - базовая логика
|
||||||
|
/// </summary>
|
||||||
|
abstract class Developer
|
||||||
|
{
|
||||||
|
protected string Name { get; set; }
|
||||||
|
|
||||||
|
public Developer(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Фабричный метод
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>House</returns>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Общая логика операций над строением
|
||||||
|
/// </summary>
|
||||||
|
abstract class House
|
||||||
|
{
|
||||||
|
public abstract void Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Панельный дом
|
||||||
|
/// </summary>
|
||||||
|
class PanelHouse : House
|
||||||
|
{
|
||||||
|
public PanelHouse()
|
||||||
|
{
|
||||||
|
Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Build()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Build Panel House");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Офисное здание
|
||||||
|
/// </summary>
|
||||||
|
class OfficeHouse : House
|
||||||
|
{
|
||||||
|
public OfficeHouse()
|
||||||
|
{
|
||||||
|
Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Build()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Build Office House");
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/FluentBuilder/FluentBuilder.csproj
Normal file
10
Patterns/FluentBuilder/FluentBuilder.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
68
Patterns/FluentBuilder/Program.cs
Normal file
68
Patterns/FluentBuilder/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон пользователя
|
||||||
|
/// </summary>
|
||||||
|
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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон гибкого строителя конфигурации пользователя
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// преобразуем тип Builder в тип User для которого он использовался
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">строитель</param>
|
||||||
|
public static implicit operator User(UserBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.CurrentUser;
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Flyweight/Flyweight.csproj
Normal file
10
Patterns/Flyweight/Flyweight.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
97
Patterns/Flyweight/Program.cs
Normal file
97
Patterns/Flyweight/Program.cs
Normal file
@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Кол-во этажей - внутреннее состояние
|
||||||
|
/// </summary>
|
||||||
|
protected int stages;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Внешнее состояние действия
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="latitude"></param>
|
||||||
|
/// <param name="longitude"></param>
|
||||||
|
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<string, House> houses = new Dictionary<string, House>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Interpreter/Interpreter.csproj
Normal file
10
Patterns/Interpreter/Interpreter.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
148
Patterns/Interpreter/Program.cs
Normal file
148
Patterns/Interpreter/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Агрегатор выражений
|
||||||
|
/// </summary>
|
||||||
|
class Context
|
||||||
|
{
|
||||||
|
Dictionary<string, int> variables;
|
||||||
|
|
||||||
|
public Context()
|
||||||
|
{
|
||||||
|
variables = new Dictionary<string, int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение интерпретатора
|
||||||
|
/// </summary>
|
||||||
|
interface IExpression
|
||||||
|
{
|
||||||
|
int Interpret(Context context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Терминальное выражение
|
||||||
|
/// </summary>
|
||||||
|
class NumberExpression : IExpression
|
||||||
|
{
|
||||||
|
string Name { get; set; }
|
||||||
|
public NumberExpression(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Interpret(Context context)
|
||||||
|
{
|
||||||
|
return context.GetVariable(Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Нетерминальное выражение для сложения
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Нетерминальное выражение для умножения
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Нетерминальное выражение для вычитания
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Iterator/Iterator.csproj
Normal file
10
Patterns/Iterator/Iterator.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
263
Patterns/Iterator/Program.cs
Normal file
263
Patterns/Iterator/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Читатель
|
||||||
|
/// </summary>
|
||||||
|
class Reader
|
||||||
|
{
|
||||||
|
public void SetBooks(Library library)
|
||||||
|
{
|
||||||
|
IBookIterator iterator = library.CreateNumerator();
|
||||||
|
while(iterator.HasNext())
|
||||||
|
{
|
||||||
|
Book book = iterator.Next();
|
||||||
|
Console.WriteLine(book.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение поиска библиотеки
|
||||||
|
/// </summary>
|
||||||
|
interface IBookIterator
|
||||||
|
{
|
||||||
|
bool HasNext();
|
||||||
|
Book Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение библиотеки
|
||||||
|
/// </summary>
|
||||||
|
interface IBookNumerable
|
||||||
|
{
|
||||||
|
IBookIterator CreateNumerator();
|
||||||
|
int Count { get; }
|
||||||
|
Book this[int index] { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс книги
|
||||||
|
/// </summary>
|
||||||
|
class Book
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс библиотеки книг
|
||||||
|
/// </summary>
|
||||||
|
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"}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Вызов книги
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">индекс в библиотеке</param>
|
||||||
|
/// <returns>Book</returns>
|
||||||
|
public Book this[int index] => Books[index];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Количество книг в библиотеке
|
||||||
|
/// </summary>
|
||||||
|
public int Count => Books.Length;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Перейти к следующей библиотеке
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>IBookIterator(LibraryNumenator)</returns>
|
||||||
|
public IBookIterator CreateNumerator() => new LibraryNumenator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LibraryNumenator : IBookIterator
|
||||||
|
{
|
||||||
|
IBookNumerable Aggregate { get; set; }
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Передача коллекции книг в Library
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bookNumerable"></param>
|
||||||
|
public LibraryNumenator(IBookNumerable bookNumerable)
|
||||||
|
{
|
||||||
|
Aggregate = bookNumerable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasNext() => index < Aggregate.Count;
|
||||||
|
|
||||||
|
public Book Next() => Aggregate[index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс стека данных
|
||||||
|
/// </summary>
|
||||||
|
public class DataStack
|
||||||
|
{
|
||||||
|
private int[] items = new int[10];
|
||||||
|
/// <summary>
|
||||||
|
/// Длинна массива данных в этом стеке
|
||||||
|
/// </summary>
|
||||||
|
private int lenght;
|
||||||
|
|
||||||
|
public DataStack() => lenght = -1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Для копирования экземпляра класса
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="myStack">Экземпляр данного класса</param>
|
||||||
|
public DataStack(DataStack myStack)
|
||||||
|
{
|
||||||
|
this.items = myStack.items;
|
||||||
|
this.lenght = myStack.lenght;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство геттера для поля items
|
||||||
|
/// </summary>
|
||||||
|
public int[] Items { get => items; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Свойство геттера для поля lenght
|
||||||
|
/// </summary>
|
||||||
|
public int Lenght { get => lenght; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление элементов в массив
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">значение</param>
|
||||||
|
public void Push(int value) => items[++lenght] = value;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение последнего элемента
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>значение</returns>
|
||||||
|
public int Pop() => items[lenght--];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Переопределение оператора сравнения двух экземпляров данного класса
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left"></param>
|
||||||
|
/// <param name="right"></param>
|
||||||
|
/// <returns>bool</returns>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Переопределение оператора сравнения двух экземпляров данного класса
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left"></param>
|
||||||
|
/// <param name="right"></param>
|
||||||
|
/// <returns>bool</returns>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Перечислитель
|
||||||
|
/// </summary>
|
||||||
|
class StackIterator
|
||||||
|
{
|
||||||
|
private DataStack stack;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Инициализируем поля перечислителя
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataStack">данные</param>
|
||||||
|
public StackIterator(DataStack dataStack)
|
||||||
|
{
|
||||||
|
this.stack = dataStack;
|
||||||
|
this.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Переопределение опреатора инкрементирования
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s">новый переданный экземпляр класса</param>
|
||||||
|
/// <returns>экземпляр класса с инкрементированым значением index</returns>
|
||||||
|
public static StackIterator operator ++(StackIterator s)
|
||||||
|
{
|
||||||
|
s.index++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Возвращает значение элемента поля стека
|
||||||
|
/// через его свойство по текущему индексу
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int Get()
|
||||||
|
{
|
||||||
|
if(index < stack.Lenght) return stack.Items[index];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Возвращет true при достижении предельного размера стека
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>bool</returns>
|
||||||
|
public bool IsEnd() => index != stack.Lenght + 1;
|
||||||
|
}
|
23
Patterns/LetCode.Tests/LetCode.Tests.csproj
Normal file
23
Patterns/LetCode.Tests/LetCode.Tests.csproj
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<IsTestProject>true</IsTestProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LetCode\LetCode.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
65
Patterns/LetCode.Tests/Tests.cs
Normal file
65
Patterns/LetCode.Tests/Tests.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
namespace LetCode.Tests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class Tests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Èíäåêñû ÷èñåë â ìàññèâå îáðàçóþùèõ ÷èñëî target
|
||||||
|
/// </summary>
|
||||||
|
[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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
Patterns/LetCode.Tests/Usings.cs
Normal file
1
Patterns/LetCode.Tests/Usings.cs
Normal file
@ -0,0 +1 @@
|
|||||||
|
global using Microsoft.VisualStudio.TestTools.UnitTesting;
|
10
Patterns/LetCode/LetCode.csproj
Normal file
10
Patterns/LetCode/LetCode.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
160
Patterns/LetCode/Program.cs
Normal file
160
Patterns/LetCode/Program.cs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
public static class LetCodeTasks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Какие числа массива дают в сумме указанное число
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nums">Массив чисел</param>
|
||||||
|
/// <param name="target">Искомая сумма</param>
|
||||||
|
/// <returns>Массив индексов чисел</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проверяет число на верность свойствам полиндрома
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">Число</param>
|
||||||
|
/// <returns>Полиндром или нет</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Переводит римские цифры в реальное число
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s">Римский символ</param>
|
||||||
|
/// <returns>Число</returns>
|
||||||
|
public static int RomanToInt(string s)
|
||||||
|
{
|
||||||
|
var mapNumbers = new Dictionary<int, char>()
|
||||||
|
{
|
||||||
|
{ 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Вычисляет совпадение частей слов в массиве слов
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="strs">Массив слов</param>
|
||||||
|
/// <returns>Подстрока обобщающая все слова</returns>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Mediator/Mediator.csproj
Normal file
10
Patterns/Mediator/Mediator.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
112
Patterns/Mediator/Program.cs
Normal file
112
Patterns/Mediator/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Интерфейс для взаимодействия с посредником
|
||||||
|
/// </summary>
|
||||||
|
abstract class Mediator
|
||||||
|
{
|
||||||
|
public abstract void Send(string message, Colleague colleague);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Интерфейс для взаимодействия с коллегами
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Непосредственный заказчик
|
||||||
|
/// </summary>
|
||||||
|
class CustomerCollegue : Colleague
|
||||||
|
{
|
||||||
|
public CustomerCollegue(Mediator mediator) : base(mediator) {}
|
||||||
|
|
||||||
|
public override void Notify(string message)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Сообщение заказчику: {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Программист
|
||||||
|
/// </summary>
|
||||||
|
class ProgrammerCollegue : Colleague
|
||||||
|
{
|
||||||
|
public ProgrammerCollegue(Mediator mediator) : base(mediator) { }
|
||||||
|
|
||||||
|
public override void Notify(string message)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Сообщение программисту: {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Тестировщик
|
||||||
|
/// </summary>
|
||||||
|
class TesterCollegue : Colleague
|
||||||
|
{
|
||||||
|
public TesterCollegue(Mediator mediator) : base(mediator) { }
|
||||||
|
|
||||||
|
public override void Notify(string message)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Сообщение тестировщику: {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Посредник
|
||||||
|
/// </summary>
|
||||||
|
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); //значит оповещаем заказчика
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Memento/Memento.csproj
Normal file
10
Patterns/Memento/Memento.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
119
Patterns/Memento/Program.cs
Normal file
119
Patterns/Memento/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Класс героя
|
||||||
|
/// </summary>
|
||||||
|
class Hero : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Количество патронов
|
||||||
|
/// </summary>
|
||||||
|
private int patrons = 10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Выстрел
|
||||||
|
/// </summary>
|
||||||
|
public void Shoot()
|
||||||
|
{
|
||||||
|
if(patrons > 0)
|
||||||
|
{
|
||||||
|
patrons--;
|
||||||
|
Console.WriteLine($"Осталось {patrons} патронов...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Console.WriteLine("Нет патронов");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Сохранение состояния
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public HeroMemento SaveState()
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Сохранено - {patrons}");
|
||||||
|
return new HeroMemento(patrons);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Восстановление состояния
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="memento">Хранитель состояния</param>
|
||||||
|
public void RestoreState(HeroMemento memento)
|
||||||
|
{
|
||||||
|
patrons = memento.Patrons;
|
||||||
|
Console.WriteLine($"Загружено - {patrons}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Удаление из памяти + сохранение в истории последнего состояния
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GameHistory.Instance.History.Push(SaveState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Memento - Хранитель состояния
|
||||||
|
/// </summary>
|
||||||
|
class HeroMemento
|
||||||
|
{
|
||||||
|
public int Patrons { get; private set; }
|
||||||
|
|
||||||
|
public HeroMemento(int patrons)
|
||||||
|
{
|
||||||
|
Patrons = patrons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Caretaker - смотритель состояния
|
||||||
|
/// </summary>
|
||||||
|
class GameHistory
|
||||||
|
{
|
||||||
|
private static GameHistory instance;
|
||||||
|
public Stack<HeroMemento> History { get; set; }
|
||||||
|
|
||||||
|
private GameHistory()
|
||||||
|
{
|
||||||
|
History = new Stack<HeroMemento>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameHistory Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(instance == null)
|
||||||
|
instance = new GameHistory();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
History.Clear();
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Observer/Observer.csproj
Normal file
10
Patterns/Observer/Observer.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
103
Patterns/Observer/Program.cs
Normal file
103
Patterns/Observer/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение наблюдателя
|
||||||
|
/// </summary>
|
||||||
|
interface IObservable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Добавить наблюдаемого
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="observer">Наблюдаемый</param>
|
||||||
|
void AddObserver(IObserver observer);
|
||||||
|
/// <summary>
|
||||||
|
/// Удалить наблюдаемого
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="observer">Наблюдаемый</param>
|
||||||
|
void RemoveObserver(IObserver observer);
|
||||||
|
/// <summary>
|
||||||
|
/// Оповестить всех наблюдаемых
|
||||||
|
/// </summary>
|
||||||
|
void NotifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация конкретного наблюдателя
|
||||||
|
/// </summary>
|
||||||
|
class ConcreteObservable : IObservable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Список наблюдаемых
|
||||||
|
/// </summary>
|
||||||
|
private List<IObserver> _observers;
|
||||||
|
|
||||||
|
public ConcreteObservable()
|
||||||
|
{
|
||||||
|
_observers = new List<IObserver>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение наблюдаемого
|
||||||
|
/// </summary>
|
||||||
|
interface IObserver
|
||||||
|
{
|
||||||
|
void Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Наблюдаемый
|
||||||
|
/// </summary>
|
||||||
|
class Observer : IObserver
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public Observer(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Update {Name}");
|
||||||
|
}
|
||||||
|
}
|
269
Patterns/Patterns Programming.sln
Normal file
269
Patterns/Patterns Programming.sln
Normal file
@ -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
|
132
Patterns/Prototype/Program.cs
Normal file
132
Patterns/Prototype/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение фигуры
|
||||||
|
/// </summary>
|
||||||
|
interface IFigure
|
||||||
|
{
|
||||||
|
IFigure Clone();
|
||||||
|
IFigure? CloneMember();
|
||||||
|
void GetInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон куба
|
||||||
|
/// </summary>
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Треугольник
|
||||||
|
/// </summary>
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение сущности
|
||||||
|
/// </summary>
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
|
10
Patterns/Prototype/Prototype.csproj
Normal file
10
Patterns/Prototype/Prototype.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
94
Patterns/Proxy/Program.cs
Normal file
94
Patterns/Proxy/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// отдельная страница книги
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Id">Идентификатор</param>
|
||||||
|
/// <param name="Number">Номер</param>
|
||||||
|
/// <param name="Text">Содержимое</param>
|
||||||
|
record Page(int Id, int Number, string Text);
|
||||||
|
|
||||||
|
class PageContext : DbContext
|
||||||
|
{
|
||||||
|
public DbSet<Page> 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<Page> Pages;
|
||||||
|
BookStore bookStore;
|
||||||
|
|
||||||
|
public BookStoreProxy()
|
||||||
|
{
|
||||||
|
Pages = new List<Page>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
14
Patterns/Proxy/Proxy.csproj
Normal file
14
Patterns/Proxy/Proxy.csproj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
44
Patterns/Singleton/Program.cs
Normal file
44
Patterns/Singleton/Program.cs
Normal file
@ -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"};
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Singleton/Singleton.csproj
Normal file
10
Patterns/Singleton/Singleton.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
76
Patterns/State/Program.cs
Normal file
76
Patterns/State/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Абстракция состояния
|
||||||
|
/// </summary>
|
||||||
|
abstract class State
|
||||||
|
{
|
||||||
|
public abstract void Handle(Context context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация состояния A
|
||||||
|
/// </summary>
|
||||||
|
class StateA : State
|
||||||
|
{
|
||||||
|
public StateA()
|
||||||
|
{
|
||||||
|
Console.WriteLine("State-A Create...");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Handle(Context context)
|
||||||
|
{
|
||||||
|
context.State = new StateB();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализация состояния B
|
||||||
|
/// </summary>
|
||||||
|
class StateB : State
|
||||||
|
{
|
||||||
|
public StateB()
|
||||||
|
{
|
||||||
|
Console.WriteLine("State-B Create...");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Handle(Context context)
|
||||||
|
{
|
||||||
|
context.State = new StateA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Контекст со своим состоянием
|
||||||
|
/// </summary>
|
||||||
|
class Context
|
||||||
|
{
|
||||||
|
public State State { get; set; }
|
||||||
|
|
||||||
|
public Context(State state)
|
||||||
|
{
|
||||||
|
State = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Request()
|
||||||
|
{
|
||||||
|
State.Handle(this);
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/State/State.csproj
Normal file
10
Patterns/State/State.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
6
Patterns/Strategy/ILogReader.cs
Normal file
6
Patterns/Strategy/ILogReader.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Strategy;
|
||||||
|
|
||||||
|
internal interface ILogReader
|
||||||
|
{
|
||||||
|
List<LogEntry> Read();
|
||||||
|
}
|
15
Patterns/Strategy/LogEntry.cs
Normal file
15
Patterns/Strategy/LogEntry.cs
Normal file
@ -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; }
|
||||||
|
}
|
17
Patterns/Strategy/LogFileReader.cs
Normal file
17
Patterns/Strategy/LogFileReader.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Strategy;
|
||||||
|
|
||||||
|
public class LogFileReader : ILogReader
|
||||||
|
{
|
||||||
|
public List<LogEntry> Read()
|
||||||
|
{
|
||||||
|
return new List<LogEntry>()
|
||||||
|
{
|
||||||
|
new LogEntry()
|
||||||
|
{
|
||||||
|
DateTime = DateTime.Now,
|
||||||
|
LogType = LogType.Debug,
|
||||||
|
Message = GetType().Name
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
21
Patterns/Strategy/LogProcessor.cs
Normal file
21
Patterns/Strategy/LogProcessor.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
namespace Strategy;
|
||||||
|
|
||||||
|
public class LogProcessor
|
||||||
|
{
|
||||||
|
private readonly Func<List<LogEntry>> _logimporter;
|
||||||
|
|
||||||
|
public LogProcessor(Func<List<LogEntry>> logImporter)
|
||||||
|
{
|
||||||
|
_logimporter = logImporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProcessLogs()
|
||||||
|
{
|
||||||
|
foreach (var logEntry in _logimporter.Invoke())
|
||||||
|
{
|
||||||
|
Console.WriteLine(logEntry.DateTime);
|
||||||
|
Console.WriteLine(logEntry.LogType);
|
||||||
|
Console.WriteLine(logEntry.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
218
Patterns/Strategy/Program.cs
Normal file
218
Patterns/Strategy/Program.cs
Normal file
@ -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<Employee> list)
|
||||||
|
{
|
||||||
|
list.Sort(new EmployeeByIdComparer()); //используем функтор
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SortListName(List<Employee> 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<LogEntry>
|
||||||
|
Func<List<LogEntry>> _import = () => logFileReader.Read();
|
||||||
|
LogProcessor processor = new LogProcessor(_import);
|
||||||
|
processor.ProcessLogs();
|
||||||
|
#endregion
|
||||||
|
#region Пример №3 - Сomparer
|
||||||
|
List<Employee> employees = new List<Employee>
|
||||||
|
{
|
||||||
|
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<Employee>(comparer); //конструктор принимает IComparable
|
||||||
|
//нет конструктора, принимающего делегат Comparison<T>
|
||||||
|
//можно создать небольшой адаптерный фабричный класс
|
||||||
|
var comparer_factory = ComparerFactory.Create<Employee>((x, y) => x.Id.CompareTo(y.Id));
|
||||||
|
//он помещает сюда фабрику
|
||||||
|
var set_factory = new SortedSet<Employee>(comparer_factory);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение движения
|
||||||
|
/// </summary>
|
||||||
|
interface IMovable
|
||||||
|
{
|
||||||
|
void Move();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Бензиновый двигатель
|
||||||
|
/// </summary>
|
||||||
|
class PetrolMove : IMovable
|
||||||
|
{
|
||||||
|
public void Move()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Движение на бензине");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Электродвигатель
|
||||||
|
/// </summary>
|
||||||
|
class ElectronicMove : IMovable
|
||||||
|
{
|
||||||
|
public void Move()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Движение на электричестве");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Автомобиль
|
||||||
|
/// </summary>
|
||||||
|
class Car
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Cпособ передвижения автомобиля
|
||||||
|
/// </summary>
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Реализует интерфейс сортировки
|
||||||
|
/// Добавлет возможность сортировки по ID по возрастающей
|
||||||
|
/// </summary>
|
||||||
|
class EmployeeByIdComparer : IComparer<Employee>
|
||||||
|
{
|
||||||
|
int IComparer<Employee>.Compare(Employee? x, Employee? y)
|
||||||
|
{
|
||||||
|
if (x is Employee xx && y is Employee yy)
|
||||||
|
return xx.Id.CompareTo(yy.Id);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Фабричный шаблон для создания экземпляров IComparer
|
||||||
|
/// </summary>
|
||||||
|
class ComparerFactory
|
||||||
|
{
|
||||||
|
public static IComparer<T> Create<T>(Comparison<T> comparer)
|
||||||
|
{
|
||||||
|
return new DelegateComparer<T>(comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DelegateComparer<T> : IComparer<T>
|
||||||
|
{
|
||||||
|
private readonly Comparison<T> _comparer;
|
||||||
|
|
||||||
|
public DelegateComparer(Comparison<T> comparer)
|
||||||
|
{
|
||||||
|
_comparer = comparer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Compare(T? x, T? y)
|
||||||
|
{
|
||||||
|
if (x == null || y == null)
|
||||||
|
return 0;
|
||||||
|
return _comparer(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Strategy/Strategy.csproj
Normal file
10
Patterns/Strategy/Strategy.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
17
Patterns/Strategy/WindowsEventLogReader.cs
Normal file
17
Patterns/Strategy/WindowsEventLogReader.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Strategy;
|
||||||
|
|
||||||
|
public class WindowsEventLogReader : ILogReader
|
||||||
|
{
|
||||||
|
public List<LogEntry> Read()
|
||||||
|
{
|
||||||
|
return new List<LogEntry>()
|
||||||
|
{
|
||||||
|
new LogEntry()
|
||||||
|
{
|
||||||
|
DateTime = DateTime.Now,
|
||||||
|
Message = GetType().Name,
|
||||||
|
LogType = LogType.Debug
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
115
Patterns/TemplateMethod/Program.cs
Normal file
115
Patterns/TemplateMethod/Program.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/* Шаблонный метод
|
||||||
|
Определяет алгоритм, некоторые этапы которого
|
||||||
|
делегируются подклассам. Позволяет подклассам
|
||||||
|
переопределить эти этапы, не меняя структуру алгоритма.
|
||||||
|
*/
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
#region Пример №1 - базовое
|
||||||
|
new School().Learn();
|
||||||
|
new University().Learn();
|
||||||
|
Console.ReadKey();
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Представление образовательного процесса
|
||||||
|
/// </summary>
|
||||||
|
abstract class Education
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обучение
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Learn()
|
||||||
|
{
|
||||||
|
Enter();
|
||||||
|
Study();
|
||||||
|
PassExams();
|
||||||
|
GetDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение документа об окончании образования
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void GetDocument();
|
||||||
|
/// <summary>
|
||||||
|
/// Cдача экзаменов в учебном заведении
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void PassExams();
|
||||||
|
/// <summary>
|
||||||
|
/// Обучение в учебном заведении
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void Study();
|
||||||
|
/// <summary>
|
||||||
|
/// Поступление в учебное заведение
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void Enter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Школа реализовывающее процесс образования со своими дополнениями
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Университет реализовывающий процесса образования
|
||||||
|
/// </summary>
|
||||||
|
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("Сдавал лабораторные работы");
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/TemplateMethod/TemplateMethod.csproj
Normal file
10
Patterns/TemplateMethod/TemplateMethod.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
138
Patterns/Visitor/Program.cs
Normal file
138
Patterns/Visitor/Program.cs
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение посетителя
|
||||||
|
/// отделяет логику сериализации от классов в которых она применима
|
||||||
|
/// </summary>
|
||||||
|
interface IVisitor
|
||||||
|
{
|
||||||
|
void VisitPersonAcc(Person person);
|
||||||
|
void VisitCompanyAcc(Company company);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Поведение аккаунта
|
||||||
|
/// </summary>
|
||||||
|
interface IAccaunt
|
||||||
|
{
|
||||||
|
void Accept(IVisitor visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Шаблон банка
|
||||||
|
/// </summary>
|
||||||
|
class Bank
|
||||||
|
{
|
||||||
|
List<IAccaunt> Accaunts;
|
||||||
|
|
||||||
|
public Bank()
|
||||||
|
{
|
||||||
|
Accaunts = new List<IAccaunt>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавить аккаунт
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="accaunt">аккаунт</param>
|
||||||
|
public void Add(IAccaunt accaunt)
|
||||||
|
{
|
||||||
|
Accaunts.Add(accaunt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Удаллить аккаунт
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="accaunt">аккаунт</param>
|
||||||
|
public void Remove(IAccaunt accaunt)
|
||||||
|
{
|
||||||
|
Accaunts.Remove(accaunt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить доступ к своему аккаунту
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="visitor">пользователь</param>
|
||||||
|
public void Accept(IVisitor visitor)
|
||||||
|
{
|
||||||
|
foreach (var accaunt in Accaunts)
|
||||||
|
accaunt.Accept(visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пользователь
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Name">Имя</param>
|
||||||
|
/// <param name="Number">Номер</param>
|
||||||
|
record Person(string Name, int Number) : IAccaunt
|
||||||
|
{
|
||||||
|
public void Accept(IVisitor visitor)
|
||||||
|
{
|
||||||
|
visitor.VisitPersonAcc(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Компания
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Name">Имя</param>
|
||||||
|
/// <param name="Number">Номер</param>
|
||||||
|
record Company(string Name, int Number) : IAccaunt
|
||||||
|
{
|
||||||
|
public void Accept(IVisitor visitor)
|
||||||
|
{
|
||||||
|
visitor.VisitCompanyAcc(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HTML сериализатор
|
||||||
|
/// </summary>
|
||||||
|
class HtmlVisitor : IVisitor
|
||||||
|
{
|
||||||
|
public void VisitCompanyAcc(Company company)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[HTML] {company}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void VisitPersonAcc(Person person)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[HTML] {person}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// XML сериализатор
|
||||||
|
/// </summary>
|
||||||
|
class XmlVisitor : IVisitor
|
||||||
|
{
|
||||||
|
public void VisitCompanyAcc(Company company)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[XML] {company}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void VisitPersonAcc(Person person)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"[XML] {person}");
|
||||||
|
}
|
||||||
|
}
|
10
Patterns/Visitor/Visitor.csproj
Normal file
10
Patterns/Visitor/Visitor.csproj
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
156
README.md
Normal file
156
README.md
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
<p align="center">
|
||||||
|
<!-- <p align="center">
|
||||||
|
<img src="/" width="100%" alt="Banner">
|
||||||
|
<a></a> -->
|
||||||
|
<!-- </p> -->
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://git.io/typing-svg"><img src="https://readme-typing-svg.demolab.com?font=Fira+Code&pause=1000¢er=true&vCenter=true&width=435&lines=%D0%9F%D0%BE%D0%B2%D1%82%D0%BE%D1%80%D0%B5%D0%BD%D0%B8%D0%B5+-+%D0%BC%D0%B0%D1%82%D1%8C+%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D1%8F" alt="Typing SVG" /></a>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://sites.google.com/view/dvurechensky" target="_blank"><img alt="Static Badge" src="https://img.shields.io/badge/Dvurechensky-N-blue"></a>
|
||||||
|
<img src="https://img.shields.io/badge/Csharp-VS2022-blue?logo=csharp&logoColor=FFFF00">
|
||||||
|
</p>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<h1 align="center">🔱 Шаблоны проектирования 🔱<h1>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Описание содержимого 💼
|
||||||
|
|
||||||
|
- ⌛ Определения: **class, abstract class, struct, interface, record**
|
||||||
|
- ⌛ Разбор: **принципы SOLID, наследование, типы Dictionary, Unit тестирование**
|
||||||
|
- ⌛ Бонус: **решение [LetCode](https://leetcode.com/) задач**
|
||||||
|
- 😈 Такие паттерны как:
|
||||||
|
>
|
||||||
|
<h1 align="center">🌐 Behavioral - Поведенческие [11]🌐<h1><br>
|
||||||
|
<table align="center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Паттерн</th>
|
||||||
|
<th>Краткое определение</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/ChainOfResponsibility/Program.cs">ChainOfResponsibility</a> - Цепочка обязанностей</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Избегает связывание отправителя запроса с его получателем, давая возможность обработать запрос более чем одному объекту.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Command/Program.cs">Command</a> - Команда</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Инкапсулирует запрос в виде объекта позволяя передавать их клиентам в качестве параметров, ставить в очередь, логировать, а также поддерживать отмену операций.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Interpreter/Program.cs">Interpreter</a> - Интерпретатор</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Получая формальный язык, определяет представление его грамматики и интерпретатор, использующий это представление для обработки выражений языка.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Iterator/Program.cs">Iterator</a> - Итератор</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Предоставляет способ последовательного доступа к множеству, независимо от его внутреннего устройства.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Mediator/Program.cs">Mediator</a> - Посредник</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Определяет объект инкапсулирующий способ взаимодействия объектов. Обеспечивает слабую связь, избавляя их от необходимости ссылаться друг на друга и даёт возможность независимо изменять их взаимодействие.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Memento/Program.cs">Memento</a> - Хранитель</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Не нарушая инкапсуляцию, определяет и сохраняет внутреннее состояние объекта и позволяет позже восстановить объект в этом состоянии.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Observer/Program.cs">Observer</a> - Наблюдатель</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Определяет зависимость один ко многим между объектами так, что когда один меняет своё состояние, все зависимые объекты оповещаются и обновляются автоматически.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/State/Program.cs">State</a> - Состояние</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Позволяет объекту изменять своё поведение в зависимости от внутреннего состояния.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Strategy/Program.cs">Strategy</a> - Стратегия</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Определяет группу алгоритмов, инкапсулирует их и делает взаимозаменяемыми. Позволяет изменять алгоритм независимо от клиентов, его использующих.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/TemplateMethod/Program.cs">TemplateMethod</a> - Шаблонный метод</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Определяет алгоритм, некоторые этапы которого делегируются подклассам. Позволяет подклассам переопределить эти этапы, не меняя структуру алгоритма.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Visitor/Program.cs">Visitor</a> - Посетитель</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Представляет собой операцию, которая будет выполнена над объектами группы классов. Даёт возможность определить новую операцию без изменения кода классов, над которыми эта операция производитcя.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<h1 align="center">💡 Creational - Порождающие [6]💡<h1><br>
|
||||||
|
<table align="center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Паттерн</th>
|
||||||
|
<th>Краткое определение</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/AbstractFactory/Program.cs">AbstractFactory</a> - Абстрактная фабрика</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Предоставляет интерфейс для создания групп связанных или зависимых объектов, не указывая их конкретный класс.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Builder/Program.cs">Builder</a> - Строитель</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Разделяет создание сложного объекта и его инициализацию так, что одинаковый процесс построения может может создавать объекты с разным состоянием.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/FactoryMethod/Program.cs">FactoryMethod</a> - Фабричный метод</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Определяет интерфейс для создания объекта, но позволяет подклассам решать, какой класс создавать. Позволяет делегировать создание класса объектам класса.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/FluentBuilder/Program.cs">FluentBuilder</a> - Гибкий(плавный, текучий) строитель</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Позволяет упростить процесс создания сложных объектов с помощью методов-цепочек, которые наделяют объект каким-то определенным качеством.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Prototype/Program.cs">Prototype</a> - Прототип</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Определяет несколько видов объектов, чтобы при создании использовать объект-прототип и создаёт новые объекты, копируя прототип (техника клонирования объектов).</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Singleton/Program.cs">Singleton</a> - Одиночка</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Гарантирует что класс имеет только один экземпляр и представляет глобальную точку доступа к нему.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<h1 align="center">🏩 Structural - Структурные [7]🏩<h1><br>
|
||||||
|
<table align="center">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Паттерн</th>
|
||||||
|
<th>Краткое определение</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Adapter/Program.cs">Adapter</a> - Адаптер</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Конвенртирует интерфейс класса в другой интерфейс, ожидаемый клиентом. Позволяет классам с разными интерфейсами работать вместе.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Bridge/Program.cs">Bridge</a> - Мост</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Разделяет абстракцию и реализацию так, чтобы они могли изменяться независимо друг от друга.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Composite/Program.cs">Composite</a> - Компоновщик</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Компонует объекты в древовидную структуру по принципу "часть-целое", представляя их в виде иерархии. Позволяет клиенту одинаково обращаться как к отдельному, так и к целому поддереву.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Decorator/Program.cs">Decorator</a> - Декоратор</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Динамически предоставляет объекту дополнительные возможности. Представляет собой гибкую альтернативу наследованию для расширения функциональности.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Facade/Program.cs">Facade</a> - Фасад</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Предоставляет единый интерфейс к группе интерфейсов подсистемы. Определяет высокоуровневый интерфейс, делая систему проще для использования.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Flyweight/Program.cs">Flyweight</a> - Приспособленец</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Благодаря совместному использованию, поддерживает эффективную работу с большим количеством объектов. (для оптимизации работы с памятью)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="width: 500px; padding: 18px;">💢 <a href="/Patterns/Proxy/Program.cs">Proxy</a> - Заместитель</td>
|
||||||
|
<td style="width: 500px; padding: 18px;">🔎 Предоставляет объект-заместитель другого объекта для контроля доступа к нему.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
Loading…
Reference in New Issue
Block a user