Skip to content

Commit d3b974f

Browse files
committed
Singleton as StaticInit and ThreadSafe
1 parent ed98672 commit d3b974f

File tree

12 files changed

+105
-109
lines changed

12 files changed

+105
-109
lines changed

CreationalPatterns/CreationalPatterns.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,19 @@
4545
<ItemGroup>
4646
<Compile Include="Program.cs" />
4747
<Compile Include="Properties\AssemblyInfo.cs" />
48+
<Compile Include="Singleton\ChocolateBoiler_StaticInit.cs" />
4849
<Compile Include="Singleton\ChocolateBoiler.cs" />
4950
</ItemGroup>
5051
<ItemGroup>
5152
<None Include="App.config" />
52-
<None Include="Singleton\Singleton.cd" />
53+
<None Include="doc\Singleton.cd" />
5354
</ItemGroup>
5455
<ItemGroup>
5556
<Folder Include="AbstractFactory\" />
5657
</ItemGroup>
58+
<ItemGroup>
59+
<Content Include="doc\Singleton.png" />
60+
</ItemGroup>
5761
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
5862
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
5963
Other similar extension points exist, see Microsoft.Common.targets.

CreationalPatterns/Singleton/ChocolateBoiler.cs renamed to CreationalPatterns/Singleton/ChocolateBoiler_StaticInit.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,24 @@
66

77
namespace CreationalPatterns.Singleton
88
{
9-
class ChocolateBoiler
9+
public sealed class ChocolateBoiler_StaticInit
1010
{
1111
public bool Empty { get; set; }
1212
public bool Boiled { get; set; }
1313

1414
// singleton instance
15-
private static ChocolateBoiler instance;
15+
private static readonly ChocolateBoiler_StaticInit instance = new ChocolateBoiler_StaticInit();
1616

17-
private ChocolateBoiler()
17+
private ChocolateBoiler_StaticInit()
1818
{
1919
this.Empty = true;
2020
this.Boiled = false;
2121
}
2222

23-
public static ChocolateBoiler Instance
23+
public static ChocolateBoiler_StaticInit Instance
2424
{
2525
get
2626
{
27-
if(instance == null)
28-
{
29-
instance = new ChocolateBoiler();
30-
}
3127
return instance;
3228
}
3329
}
@@ -48,7 +44,7 @@ public void Drain()
4844
{
4945
// To drain the boiler, it must be full and also boiled.
5046
// Once it is drained we set the Empty property back to true
51-
if(!this.Empty && this.Boiled)
47+
if (!this.Empty && this.Boiled)
5248
{
5349
// drain the boiled milk and chocolate
5450
this.Empty = true;
@@ -59,7 +55,7 @@ public void Boil()
5955
{
6056
// To boil the mixture, the boiler has to be full and not already boiled.
6157
// Once it is boiled we set the boiled flag to true
62-
if(!this.Empty && !this.Boiled)
58+
if (!this.Empty && !this.Boiled)
6359
{
6460
// bring the contents to a boil
6561
this.Boiled = true;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace CreationalPatterns.Singleton
8+
{
9+
public sealed class ChocolateBuilder_ThreadSafe
10+
{
11+
public bool Empty { get; set; }
12+
public bool Boiled { get; set; }
13+
14+
// singleton instance
15+
private static volatile ChocolateBuilder_ThreadSafe instance;
16+
private static object syncLock = new object();
17+
18+
private ChocolateBuilder_ThreadSafe()
19+
{
20+
this.Empty = true;
21+
this.Boiled = false;
22+
}
23+
24+
public static ChocolateBuilder_ThreadSafe Instance
25+
{
26+
get
27+
{
28+
if (instance == null)
29+
{
30+
lock (syncLock)
31+
{
32+
if(instance == null)
33+
{
34+
instance = new ChocolateBuilder_ThreadSafe();
35+
}
36+
}
37+
}
38+
return instance;
39+
}
40+
}
41+
42+
public void Fill()
43+
{
44+
// To fill the boiler, it must be empty, and once it's full, we set the empty and boiled flags
45+
if (this.Empty)
46+
{
47+
this.Empty = false;
48+
this.Boiled = false;
49+
50+
// fill the boiler with a milk/chocolate mixture
51+
}
52+
}
53+
54+
public void Drain()
55+
{
56+
// To drain the boiler, it must be full and also boiled.
57+
// Once it is drained we set the Empty property back to true
58+
if (!this.Empty && this.Boiled)
59+
{
60+
// drain the boiled milk and chocolate
61+
this.Empty = true;
62+
}
63+
}
64+
65+
public void Boil()
66+
{
67+
// To boil the mixture, the boiler has to be full and not already boiled.
68+
// Once it is boiled we set the boiled flag to true
69+
if (!this.Empty && !this.Boiled)
70+
{
71+
// bring the contents to a boil
72+
this.Boiled = true;
73+
}
74+
}
75+
}
76+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
# Singleton
22

33
![ChocolateBoiler as Singleton](/CreationalPatterns/doc/Singleton.png)
4+
5+
## Static Initialization
6+
7+
If your applicatioin always creates and uses an instance of the `Singleton` or the overhead of creation and runtime aspects of the Singleton are not onerous, you may want to create your Singleton eagerly, like `ChocolateBoiler_StaticInit.cs`.
8+
9+
The class is marked as **sealed** to prevent derivation, which could add instances. In addition, the variable is marked **readonly**, which means that it can be assigned only during static Initialization or in a class constructor.
10+

CreationalPatterns/doc/Singleton.cd

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="NameAndType">
3-
<Class Name="CreationalPatterns.Singleton.ChocolateBoiler">
4-
<Position X="3.5" Y="1" Width="2" />
3+
<Class Name="CreationalPatterns.Singleton.ChocolateBoiler_StaticInit">
4+
<Position X="2.75" Y="1" Width="2.75" />
55
<TypeIdentifier>
66
<HashCode>IAAAAAAAAAAAAAAgAAJAAAAAAABACAAAQAAAAAAAAAA=</HashCode>
7-
<FileName>Singleton\ChocolateBoiler.cs</FileName>
7+
<FileName>Singleton\ChocolateBoiler_StaticInit.cs</FileName>
8+
<NewMemberFileName>Singleton\ChocolateBoiler.cs</NewMemberFileName>
9+
</TypeIdentifier>
10+
</Class>
11+
<Class Name="CreationalPatterns.Singleton.ChocolateBuilder_ThreadSafe">
12+
<Position X="6" Y="1" Width="2.75" />
13+
<TypeIdentifier>
14+
<HashCode>IAAAAAAAAAAAAAAgAAJAAAgAAABACAAAQAAAAAAAAAA=</HashCode>
15+
<FileName>Singleton\ChocolateBoiler_ThreadSafe.cs</FileName>
816
</TypeIdentifier>
917
</Class>
1018
<Font Name="Segoe UI" Size="9" />
15.4 KB
Loading

DesignPatterns.sln

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1010
README.md = README.md
1111
EndProjectSection
1212
EndProject
13-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{5F946B5C-E2E4-4740-B8C9-8EAC24BCFA38}"
14-
EndProject
15-
Project("{F088123C-0E9E-452A-89E6-6BA2F21D5CAC}") = "Diagrams", "Diagrams\Diagrams.modelproj", "{65DF9949-9385-4C80-A529-54EB58F9F1D7}"
16-
EndProject
17-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CreationalPatterns", "CreationalPatterns", "{4C621B54-9BDF-4842-91DA-45DC95063B9C}"
18-
ProjectSection(SolutionItems) = preProject
19-
CreationalPatterns\Singleton.cd = CreationalPatterns\Singleton.cd
20-
EndProjectSection
21-
EndProject
2213
Global
2314
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2415
Debug|Any CPU = Debug|Any CPU
@@ -29,15 +20,8 @@ Global
2920
{32536589-DE08-4C37-962F-2C92136B239E}.Debug|Any CPU.Build.0 = Debug|Any CPU
3021
{32536589-DE08-4C37-962F-2C92136B239E}.Release|Any CPU.ActiveCfg = Release|Any CPU
3122
{32536589-DE08-4C37-962F-2C92136B239E}.Release|Any CPU.Build.0 = Release|Any CPU
32-
{65DF9949-9385-4C80-A529-54EB58F9F1D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33-
{65DF9949-9385-4C80-A529-54EB58F9F1D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
34-
{65DF9949-9385-4C80-A529-54EB58F9F1D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
35-
{65DF9949-9385-4C80-A529-54EB58F9F1D7}.Release|Any CPU.Build.0 = Release|Any CPU
3623
EndGlobalSection
3724
GlobalSection(SolutionProperties) = preSolution
3825
HideSolutionNode = FALSE
3926
EndGlobalSection
40-
GlobalSection(NestedProjects) = preSolution
41-
{4C621B54-9BDF-4842-91DA-45DC95063B9C} = {5F946B5C-E2E4-4740-B8C9-8EAC24BCFA38}
42-
EndGlobalSection
4327
EndGlobal

Diagrams/CreationalPatterns.classdiagram

Lines changed: 0 additions & 1 deletion
This file was deleted.

Diagrams/CreationalPatterns.classdiagram.layout

Lines changed: 0 additions & 1 deletion
This file was deleted.
-8.87 KB
Binary file not shown.

0 commit comments

Comments
 (0)