├── 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 | --------------------------------------------------------------------------------