diff --git a/README.md b/README.md index eda8e45..26c1d5f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ The Swift coding conventions guide documents many best practices for writing Swi * [Naming](Naming.md) * [Property Observers](PropertyObservers.md) * [Range Operators](RangeOperators.md) +* [Singletons](Singletons.md) * [Type Casting](TypeCasting.md) * [Type Inference](TypeInference.md) diff --git a/Singletons.md b/Singletons.md new file mode 100644 index 0000000..959b5a3 --- /dev/null +++ b/Singletons.md @@ -0,0 +1,39 @@ +# Singletons + +## Convention + +If a singleton must be used (and effort should be taken to avoid this where possible), then they should always be implemented as a class with a shared reference to an instance of itself, with instance properties, rather than static properties. + +## Rationale + +Following this convention makes it clear that this class is a singleton and should be used that way. More importantly, it makes testing significantly simpler as new versions can be instatiated and passed around. + +## Examples + +```swift +// good: The singleton has no static properties +class MyManager { + static let shared = MyManager() + var someVar: String = "Hello" +} + +// bad: The singleton only has static properties +class MyManager { + static var someVar: String = "Hello" +} + +// A more complete example +public class OurDefaults { + // Called throughout the application + public static let shared = OurDefaults(userDefaults: .standard) + + private let userDefaults: UserDefaults + + // Called during test case set up + // Initializer also makes it clear how many dependencies this class has. + init(userDefaults: UserDefaults) { + self.userDefaults = userDefaults + } + +} +```