├── Slides.pdf
├── Demo
├── ISoundSink.cs
├── App.config
├── SoundPlayer.cs
├── Program.cs
├── AudioFile.cs
├── SoundEditor.cs
├── Properties
│ └── AssemblyInfo.cs
└── Demo.csproj
├── README.md
└── Demo.sln
/Slides.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zoran-horvat/conf-jetbrains-net-days-2020/HEAD/Slides.pdf
--------------------------------------------------------------------------------
/Demo/ISoundSink.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Demo
4 | {
5 | public interface ISoundSink : IDisposable
6 | {
7 | void Append(byte[] uncompressed);
8 | }
9 | }
--------------------------------------------------------------------------------
/Demo/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Demo/SoundPlayer.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace Demo
4 | {
5 | class SoundPlayer : ISoundSink
6 | {
7 | private int DeviceId { get; }
8 |
9 | public SoundPlayer(int deviceId)
10 | {
11 | this.DeviceId = deviceId;
12 | }
13 |
14 | public void Append(byte[] uncompressed)
15 | {
16 | Debug.WriteLine($"Playing {uncompressed.Length} bytes on device #{this.DeviceId}");
17 | }
18 |
19 | public void Dispose() { }
20 | }
21 | }
--------------------------------------------------------------------------------
/Demo/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace Demo
5 | {
6 | class Program
7 | {
8 | static void Main(string[] args)
9 | {
10 | FileInfo destination = new FileInfo("music.mp3");
11 | Func sinkFactory = () => new SoundPlayer(0);
12 |
13 | using (SoundEditor editor = new SoundEditor(sinkFactory))
14 | {
15 | editor.AddSilence(TimeSpan.FromSeconds(2));
16 | editor.GenerateTone();
17 | editor.AddSilence(TimeSpan.FromSeconds(2));
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Demo/AudioFile.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.IO;
3 |
4 | namespace Demo
5 | {
6 | class AudioFile : ISoundSink
7 | {
8 | private FileInfo Destination { get; }
9 |
10 | public AudioFile(FileInfo destination)
11 | {
12 | this.Destination = destination;
13 | }
14 |
15 | public void Append(byte[] uncompressed)
16 | {
17 | byte[] compressed = this.Compress(uncompressed);
18 | Debug.WriteLine($"Writing compressed sound to {this.Destination.Name}");
19 | File.WriteAllBytes(this.Destination.FullName, compressed);
20 | }
21 |
22 | private byte[] Compress(byte[] sound)
23 | {
24 | Debug.WriteLine($"Compressing {sound.Length} bytes of sound");
25 | return sound;
26 | }
27 |
28 | public void Dispose() { }
29 | }
30 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Refactoring to Patterns with ReSharper
2 | *Code and slides from talk included in JetBrains .NET Days Online, May 2020.*
3 |
4 | From the Gang of Four, we learned to value flexible designs.
5 | From Martin Fowler, Kent Beck, and others, we learned to actually flex the design and to value the axes of change.
6 | These two concepts – design patterns and refactoring – have been around for over two decades, and yet the combination of the two systems never got a grip in the industry.
7 | Why so?
8 |
9 | In this demonstration, we will apply refactoring techniques to flex the design and meet the requirements.
10 | But as every refactoring needs an end goal that motivates it, you will learn that established design patterns can often be seen as the final design.
11 | Through a series of examples, you will learn how refactoring techniques can easily – in particular, thanks to using ReSharper – be applied to introduce design patterns into existing code.
12 |
--------------------------------------------------------------------------------
/Demo.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30011.22
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo\Demo.csproj", "{16A3643D-1E9B-42C8-A569-0B859E2B7240}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {16A3643D-1E9B-42C8-A569-0B859E2B7240}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {16A3643D-1E9B-42C8-A569-0B859E2B7240}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {16A3643D-1E9B-42C8-A569-0B859E2B7240}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {16A3643D-1E9B-42C8-A569-0B859E2B7240}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {72BBF7CF-A73F-440C-88E7-9EF782750029}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/Demo/SoundEditor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 |
4 | namespace Demo
5 | {
6 | public class SoundEditor : IDisposable
7 | {
8 | private ISoundSink SoundSink { get; set; }
9 | private Func SinkFactory { get; }
10 |
11 | public SoundEditor(Func sinkFactory)
12 | {
13 | this.SinkFactory = sinkFactory;
14 | }
15 |
16 | public void GenerateTone()
17 | {
18 | byte[] raw = new byte[1_000_000];
19 | this.DoTheMagic(raw);
20 | this.GetSoundSink().Append(raw);
21 | }
22 |
23 | public void AddSilence(TimeSpan duration)
24 | {
25 | int samplesPerSec = 88200;
26 | int bytesPerSample = 2;
27 | int bytesCount = (int) (samplesPerSec * bytesPerSample * duration.TotalSeconds);
28 | byte[] silence = new byte[bytesCount];
29 | this.GetSoundSink().Append(silence);
30 | }
31 |
32 | private ISoundSink GetSoundSink()
33 | {
34 | this.SoundSink = this.SoundSink ?? this.SinkFactory();
35 | return this.SoundSink;
36 | }
37 |
38 | private void DoTheMagic(byte[] signal)
39 | {
40 | Debug.WriteLine("Generating tone...");
41 | }
42 |
43 | public void Dispose()
44 | {
45 | this.SoundSink?.Dispose();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Demo/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Demo")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("HP Inc.")]
12 | [assembly: AssemblyProduct("Demo")]
13 | [assembly: AssemblyCopyright("Copyright © HP Inc. 2020")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("16a3643d-1e9b-42c8-a569-0b859e2b7240")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/Demo/Demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {16A3643D-1E9B-42C8-A569-0B859E2B7240}
8 | Exe
9 | Demo
10 | Demo
11 | v4.7.2
12 | 512
13 | true
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------