@stupid_Dotnetchik

Правильна ли реализация наследования синглтона?

Ку!
Небольшое десктоп приложение, есть пара десятков классов, плодить объекты которых не хочется.
Первое решение приходящее на ум - сделать их статическими, со всеми вытекающими последствиями: все поля классов статические, все методы тоже статические, что кажется не сильно правильным в ООП-языке.
Вторая идея - сделать всё синглтонами:
public class YellowClass
	{
		private static YellowClass _instance;
		private YellowClass() { }
		public static YellowClass GetInstance()
		{
			return _instance ?? (_instance = new YellowClass());
		}
	}

Однако копипастить в каждый класс 6 строк кода (в примерах посложнее тредсэйфом и поболее) кажется весьма унылым.
Нашёл несколько примеров 'наследуемых синглтонов', подумал что счастье близко. Один из них: пр
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

namespace DemoApplication
{
	static class Program
	{
		static void Main(string[] args)
		{
			var yellowClass1 = new YellowClass();
			var yellowClass2 = YellowClass.Instance;

			Debug.Print(yellowClass1.Equals(yellowClass2) ? "All good!" : "WTF???");
		}
	}

	public class Singleton<T>
	{
		[SuppressMessage("ReSharper", "InconsistentNaming")]
		private static readonly Lazy<T> _instance = new Lazy<T>(CreateInstance);

		private static T CreateInstance()
		{
			return (T)Activator.CreateInstance(typeof(T), true);
		}

		public static T Instance
		{
			get { return _instance.Value; }
		}
	}

	public class YellowClass : Singleton<YellowClass>
	{
	}
}

Мне казалось, что синглтон подразумевает существование только 1 экземпляра класса в виртуальной машине, а тут я конструктором создаю ещё 1 экземпляр. Можно конечно для всех классов-наследников добавить приватные конструкторы, но я (или коллега) просто можем забыть это сделать через полгода при добавлении ещё пары классов этой категории, что может привести к коварным багам (уже были случаи).

Я нагуглил плохие примеры наследования синглтона? Может можно как-нибудь обойтись без приватного конструктора в каждом классе-наследнике?
  • Вопрос задан
  • 98 просмотров
Пригласить эксперта
Ответы на вопрос 4
zagayevskiy
@zagayevskiy
Android developer at Yandex
По-моему, фигня и бред. Открой для себя dependency injection.
Ответ написан
Griboks
@Griboks
Ну и, чтобы не накладывать дополнительных ограничений на T (в данном случае - наличие непараметризованного конструктора), можно написать так: (T)Activator.CreateInstance(typeof(T), true);

Так может быть стоило прочитать сначала описание этого примера?
Ответ написан
@kttotto
все, что .NET
Я пользуюсь такой конструкцией, проверенной временем
public class Singleton<T> where T : class
{
	private static readonly Lazy<T> _instance = new Lazy<T>(() => (T)typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[0], null).Invoke(null), true);

	public static T Instance => _instance.Value;
}

public sealed class CustomSingleton : Singleton<CustomSingleton>
{
}

var single = CustomSingleton.Instance
Ответ написан
Первое решение приходящее на ум - сделать их статическими, со всеми вытекающими последствиями: все поля классов статические, все методы тоже статические, что кажется не сильно правильным в ООП-языке.

Если хотите писать процедурно - пишите процедурно) То, что вы сделаете все синглтонами - не сделает ваш код ООП-шным. Он будет только притворяться ООПшным, но не быть им. Но, возможно, оно вам и не нужно?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
от 250 000 до 360 000 руб.
ЛАНИТ Москва
от 80 000 до 100 000 руб.
Кнопка Екатеринбург
До 100 000 руб.
20 авг. 2018, в 21:21
30000 руб./за проект
20 авг. 2018, в 20:46
5000 руб./за проект
20 авг. 2018, в 20:38
700 руб./в час