Skip to content

Commit

Permalink
add project ChainOfResponsibility
Browse files Browse the repository at this point in the history
  • Loading branch information
abolfazlSadeqi committed Nov 2, 2023
1 parent ed14722 commit c7f5079
Show file tree
Hide file tree
Showing 29 changed files with 336 additions and 1 deletion.
10 changes: 10 additions & 0 deletions ChainOfResponsibility/ChainOfResponsibility.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
18 changes: 18 additions & 0 deletions ChainOfResponsibility/Classes/Domin/Customer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChainOfResponsibility.Classes.Domin;

public class CustomerModel
{
public string Name { get; set; }
public string Account { get; set; }
public string Address { get; set; }
public string Number { get; set; }


}

17 changes: 17 additions & 0 deletions ChainOfResponsibility/Classes/Service/CustomerAddressValid.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using ChainOfResponsibility.Classes.Domin;
using ChainOfResponsibility.Classes.interfaces;

namespace ChainOfResponsibility.Classes.Service;


public class CustomerAddressValid : AbstractHandler
{
public override object Handle(object request)
{
CustomerModel vm = (CustomerModel)request;

if (vm.Address.Split(",").Count() != 3)
return $"Address is not valid";
return base.Handle(request);
}
}
17 changes: 17 additions & 0 deletions ChainOfResponsibility/Classes/Service/CustomerNameValid.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using ChainOfResponsibility.Classes.Domin;
using ChainOfResponsibility.Classes.interfaces;

namespace ChainOfResponsibility.Classes.Service;


public class CustomerNameValid : AbstractHandler
{
public override object Handle(object request)
{
CustomerModel vm = (CustomerModel)request;

if (vm.Name.Length < 10)
return $"Name is not valid";
return base.Handle(request);
}
}
17 changes: 17 additions & 0 deletions ChainOfResponsibility/Classes/Service/CustomerNumberValid.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using ChainOfResponsibility.Classes.Domin;
using ChainOfResponsibility.Classes.interfaces;

namespace ChainOfResponsibility.Classes.Service;


public class CustomerNumberValid : AbstractHandler
{
public override object Handle(object request)
{
CustomerModel vm = (CustomerModel)request;

if (vm.Number.Length == 10)
return $"number is not valid";
return base.Handle(request);
}
}
25 changes: 25 additions & 0 deletions ChainOfResponsibility/Classes/interfaces/AbstractHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Text;
using System.Threading.Tasks;

namespace ChainOfResponsibility.Classes.interfaces;

public abstract class AbstractHandler : IHandler
{
private IHandler NextHandler;
public virtual object Handle(object request) => (NextHandler?.Handle(request));




public IHandler SetNext(IHandler next)
{
NextHandler = next;
return next;
}
}


13 changes: 13 additions & 0 deletions ChainOfResponsibility/Classes/interfaces/IHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChainOfResponsibility.Classes.interfaces;

public interface IHandler
{
IHandler SetNext(IHandler handler);
object Handle(object request);
}
14 changes: 14 additions & 0 deletions ChainOfResponsibility/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using ChainOfResponsibility.Classes.Domin;
using ChainOfResponsibility.Classes.Service;

CustomerModel Customervm = new CustomerModel() { Number = "123", Name = "test4", Address = "tehran,shariati,12", Account = "123" };


CustomerNameValid _CustomerNameValidHandler = new CustomerNameValid();
CustomerNumberValid _CustomerNumberValidHandler = new CustomerNumberValid();
CustomerAddressValid _CustomerAddressValidHandler = new CustomerAddressValid();


_CustomerNameValidHandler.SetNext(_CustomerNumberValidHandler).SetNext(_CustomerAddressValidHandler);

var finalMessage = _CustomerNameValidHandler.Handle(Customervm);
25 changes: 25 additions & 0 deletions ChainOfResponsibility/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
the Chain of Responsibility relies on transforming particular behaviors into stand-alone objects called handlers.
In our case, each check should be extracted to its own class with a single method that performs the check.
The request, along with its data, is passed to this method as an argument.

The pattern suggests that you link these handlers into a chain.
Each linked handler has a field for storing a reference to the next handler in the chain.
In addition to processing a request, handlers pass the request further along the chain.
The request travels along the chain until all handlers have had a chance to process it.

Here’s the best part: a handler can decide not to pass the request further down the chain and effectively stop any further processing.

In our example with ordering systems, a handler performs the processing and then decides whether to pass the request further down the chain.
Assuming the request contains the right data, all the handlers can execute their primary behavior, whether it’s authentication checks or caching.


----

Chain of Responsibility and Decorator have very similar class structures.
Both patterns rely on recursive composition to pass the execution through a series of objects. However, there are several crucial differences.

The CoR handlers can execute arbitrary operations independently of each other.
They can also stop passing the request further at any point.
On the other hand, various Decorators can extend the object’s behavior while keeping it consistent with the base interface.
In addition, decorators aren’t allowed to break the flow of the request.

10 changes: 10 additions & 0 deletions Command/Command.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions Command/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
10 changes: 10 additions & 0 deletions Decorator/Decorator.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions Decorator/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
16 changes: 16 additions & 0 deletions Decorator/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Extending a class is the first thing that comes to mind when you need to alter an object’s behavior.
However, inheritance has several serious caveats that you need to be aware of.

Inheritance is static. You can’t alter the behavior of an existing object at runtime.
You can only replace the whole object with another one that’s created from a different subclass.
Subclasses can have just one parent class.
In most languages, inheritance doesn’t let a class inherit behaviors of multiple classes at the same time.
One of the ways to overcome these caveats is by using Aggregation or Composition instead of Inheritance.
Both of the alternatives work almost the same way:
one object has a reference to another and delegates it some work, whereas with inheritance,
the object itself is able to do that work, inheriting the behavior from its superclass.

With this new approach you can easily substitute the linked “helper” object with another, changing the behavior of the container at runtime.
An object can use the behavior of various classes, having references to multiple objects and delegating them all kinds of work.
Aggregation/composition is the key principle behind many design patterns, including Decorator. On that note, let’s return to the pattern discussion.

56 changes: 55 additions & 1 deletion DesginPattern.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,25 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Adapter", "Adapter\Adapter.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Builder", "Builder\Builder.csproj", "{23D56DE8-87D7-4DCD-BAA8-AC7E955582E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bridge", "Bridge\Bridge.csproj", "{7EB57B4F-E7DA-44BF-8EE6-9C1DCCA8A02F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bridge", "Bridge\Bridge.csproj", "{7EB57B4F-E7DA-44BF-8EE6-9C1DCCA8A02F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facade", "Facade\Facade.csproj", "{721D7EA4-7733-415D-A147-DA644EC7F37F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Proxy", "Proxy\Proxy.csproj", "{3F1E651B-4A8E-4623-9878-E592CA9C5F91}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChainOfResponsibility", "ChainOfResponsibility\ChainOfResponsibility.csproj", "{580EC1A8-8419-4EB7-B031-02F326B96C35}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decorator", "Decorator\Decorator.csproj", "{1245B922-DF1F-4763-A458-48BE5A8DB6EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Visitor", "Visitor\Visitor.csproj", "{2C4A0711-D6D6-4289-8D61-51F92A799D76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Strategy", "Strategy\Strategy.csproj", "{9B0BEB4B-5B27-45CB-AC57-F54E61A34E3B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Observer", "Observer\Observer.csproj", "{4742A01F-76C9-436E-B5E2-4D783A11B195}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flyweight", "Flyweight\Flyweight.csproj", "{D8A2CDFB-D00B-4B4B-A810-26B9037CE506}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Command", "Command\Command.csproj", "{B0FC2B5A-711E-4EDE-ADBF-78C64CD2C357}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -45,6 +63,42 @@ Global
{7EB57B4F-E7DA-44BF-8EE6-9C1DCCA8A02F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EB57B4F-E7DA-44BF-8EE6-9C1DCCA8A02F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EB57B4F-E7DA-44BF-8EE6-9C1DCCA8A02F}.Release|Any CPU.Build.0 = Release|Any CPU
{721D7EA4-7733-415D-A147-DA644EC7F37F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{721D7EA4-7733-415D-A147-DA644EC7F37F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{721D7EA4-7733-415D-A147-DA644EC7F37F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{721D7EA4-7733-415D-A147-DA644EC7F37F}.Release|Any CPU.Build.0 = Release|Any CPU
{3F1E651B-4A8E-4623-9878-E592CA9C5F91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F1E651B-4A8E-4623-9878-E592CA9C5F91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F1E651B-4A8E-4623-9878-E592CA9C5F91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F1E651B-4A8E-4623-9878-E592CA9C5F91}.Release|Any CPU.Build.0 = Release|Any CPU
{580EC1A8-8419-4EB7-B031-02F326B96C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{580EC1A8-8419-4EB7-B031-02F326B96C35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{580EC1A8-8419-4EB7-B031-02F326B96C35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{580EC1A8-8419-4EB7-B031-02F326B96C35}.Release|Any CPU.Build.0 = Release|Any CPU
{1245B922-DF1F-4763-A458-48BE5A8DB6EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1245B922-DF1F-4763-A458-48BE5A8DB6EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1245B922-DF1F-4763-A458-48BE5A8DB6EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1245B922-DF1F-4763-A458-48BE5A8DB6EB}.Release|Any CPU.Build.0 = Release|Any CPU
{2C4A0711-D6D6-4289-8D61-51F92A799D76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C4A0711-D6D6-4289-8D61-51F92A799D76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C4A0711-D6D6-4289-8D61-51F92A799D76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C4A0711-D6D6-4289-8D61-51F92A799D76}.Release|Any CPU.Build.0 = Release|Any CPU
{9B0BEB4B-5B27-45CB-AC57-F54E61A34E3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B0BEB4B-5B27-45CB-AC57-F54E61A34E3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B0BEB4B-5B27-45CB-AC57-F54E61A34E3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B0BEB4B-5B27-45CB-AC57-F54E61A34E3B}.Release|Any CPU.Build.0 = Release|Any CPU
{4742A01F-76C9-436E-B5E2-4D783A11B195}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4742A01F-76C9-436E-B5E2-4D783A11B195}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4742A01F-76C9-436E-B5E2-4D783A11B195}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4742A01F-76C9-436E-B5E2-4D783A11B195}.Release|Any CPU.Build.0 = Release|Any CPU
{D8A2CDFB-D00B-4B4B-A810-26B9037CE506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D8A2CDFB-D00B-4B4B-A810-26B9037CE506}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D8A2CDFB-D00B-4B4B-A810-26B9037CE506}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D8A2CDFB-D00B-4B4B-A810-26B9037CE506}.Release|Any CPU.Build.0 = Release|Any CPU
{B0FC2B5A-711E-4EDE-ADBF-78C64CD2C357}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0FC2B5A-711E-4EDE-ADBF-78C64CD2C357}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0FC2B5A-711E-4EDE-ADBF-78C64CD2C357}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0FC2B5A-711E-4EDE-ADBF-78C64CD2C357}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
10 changes: 10 additions & 0 deletions Facade/Facade.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions Facade/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
7 changes: 7 additions & 0 deletions Facade/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
A facade is a class that provides a simple interface to a complex subsystem which contains lots of moving parts.
A facade might provide limited functionality in comparison to working with the subsystem directly.
However, it includes only those features that clients really care about.

Having a facade is handy when you need to integrate your app with a sophisticated library that has dozens of features,
but you just need a tiny bit of its functionality.

10 changes: 10 additions & 0 deletions Flyweight/Flyweight.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions Flyweight/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
10 changes: 10 additions & 0 deletions Observer/Observer.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions Observer/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
2 changes: 2 additions & 0 deletions Proxy/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
10 changes: 10 additions & 0 deletions Proxy/Proxy.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions Strategy/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
10 changes: 10 additions & 0 deletions Strategy/Strategy.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions Visitor/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
6 changes: 6 additions & 0 deletions Visitor/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
The Visitor pattern suggests that you place the new behavior into a separate class called visitor,instead of trying to integrate it into existing classes.
The original object that had to perform the behavior is now passed to one of the visitor’s methods as an argument,
providing the method access to all necessary data contained within the object.

Now, what if that behavior can be executed over objects of different classes?
https://www.dntips.ir/post/2373/%d8%a7%d9%84%da%af%d9%88%db%8c-%d8%a8%d8%a7%d8%b2%d8%af%db%8c%d8%af%da%a9%d9%86%d9%86%d8%af%d9%87-visitor-pattern
10 changes: 10 additions & 0 deletions Visitor/Visitor.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

0 comments on commit c7f5079

Please sign in to comment.