我想设计一个类似于单例的类,就像该类的单个主实例一样,但主实例也可以有多个克隆。只允许1个类创建主实例,其他人都可以创建克隆。这样的事情(c#):
class Singleton
{
private static Singleton _mainInstance;
private Singleton() {..}
public void Clone() {..}
public static Singleton MainInstance
{
if (_mainInstance == null)
{
_mainInstance = new Singleton(); // how to secure this for only 1 class?
}
return _mainInstance;
}
}
class MainClass
{
public MainClass()
{
Singleton.MainInstance ....
}
}
MainClass应该是唯一允许实例化单例的类。在C ++中,这可以通过完全隐藏创建逻辑并让MyClass成为Singleton的朋友来实现。
答案 0 :(得分:2)
您可以在类中使用Singleton模式和私有静态字段。
像这样:
class Singleton
{
private static Singleton _mainInstance = new Singleton();
private Singleton() { }
public void Clone() {..}
public static Singleton MainInstance
{
return _mainInstance;
}
}
您的唯一实例将存储在类的_mainInstance静态字段中,并且无法创建任何其他实例。
答案 1 :(得分:2)
以下是一个完整的工作实现,演示了实现所需内容的两种可能方法。
两种方法均采用工厂概念;由于Singleton
的构造函数是私有的,因此只有嵌套的Factory
类才能创建Singleton
类的新实例。由于嵌套的Factory
类本身是私有的,因此获取工厂实例的唯一方法是通过Singleton.GetFactoryFirstOneWins
方法(“First one wins”方法)或Singleton.AssignFactories
方法( “间接分配”方法)。
interface IFactory<T>
{
T CreateInstance();
}
class Singleton
{
class Factory : IFactory<Singleton>
{
public Singleton CreateInstance()
{
// return a clone of _MainInstance
return new Singleton(_MainInstance);
}
}
// *** Begin "First one wins" approach
static IFactory<Singleton> _FactoryFirstOneWins;
public static IFactory<Singleton> GetFactoryFirstOneWins()
{
if (_FactoryFirstOneWins != null)
throw new InvalidOperationException("A factory has already been created.");
return _FactoryFirstOneWins = new Factory();
}
// *** End "First one wins" approach
// *** Begin "Indirect assignment" approach
public static void AssignFactories()
{
MainClass.SingletonFactory = new Factory();
}
// *** End "Indirect assignment" approach
private static readonly Singleton _MainInstance = new Singleton();
public static Singleton MainInstance
{
get { return _MainInstance; }
}
private Singleton()
{
// perform initialization logic
this.SomeValue = 5; // pick some arbitrary number
}
private Singleton(Singleton instance)
{
// perform cloning logic here to make "this" a clone of "instance"
this.SomeValue = instance.SomeValue;
}
public int SomeValue { get; set; }
public void DoSomething()
{
Console.WriteLine("Singleton.DoSomething: " + this.SomeValue);
// ...
}
}
class MainClass
{
private static IFactory<Singleton> _SingletonFactory;
public static IFactory<Singleton> SingletonFactory
{
get { return _SingletonFactory; }
set { _SingletonFactory = value; }
}
public Singleton Singleton { get; private set; }
public MainClass()
{
this.Singleton = SingletonFactory.CreateInstance();
}
public void DoWork()
{
Console.WriteLine("MainClass.DoWork");
this.Singleton.DoSomething();
// ...
}
}
class Program
{
static void Main(string[] args)
{
// you could either use the "First one wins" approach
MainClass.SingletonFactory = Singleton.GetFactoryFirstOneWins();
// or use the "Indirect assignment" approach
Singleton.AssignFactories();
// create two separate MainClass instances
MainClass mc1 = new MainClass();
MainClass mc2 = new MainClass();
// show that each one utilizes a Singleton cloned from Singleton.MainInstance
mc1.DoWork();
mc2.DoWork();
// updating mc1.Singleton.SomeValue does not affect any other instances of MainClass
mc1.Singleton.SomeValue = 7;
mc1.DoWork();
mc2.DoWork();
// updating Singleton.MainInstance.SomeValue affects any new instances of MainClass, but not existing instances
Singleton.MainInstance.SomeValue = 10;
MainClass mc3 = new MainClass();
mc1.DoWork();
mc2.DoWork();
mc3.DoWork();
}
}
答案 2 :(得分:1)
您可以使用内部构造函数使类仅可由其程序集中的其他类实例化:
class InternalInstantiation {
internal InternalInstantiation() {}
public void Clone() {}
}
class MainClass {
private InternalInstantiation _instance =
new InternalInstantiation();
}
此外,您可以将一个类嵌套在另一个类中,以使用私有构造函数实例化一个类。
class PrivateInstantiation {
private PrivateInstantiation() { }
public void Clone() {}
public class MainClass {
private PrivateInstantiation _instance =
new PrivateInstantiation();
}
}
您还可以创建一个私有实例化类在主类中注入它的实例的方案(没有其他类可以使用它):
public class MainClass {
internal PrivateInstantiation PrivateInstantiation { get; set; }
public MainClass() {
PrivateInstantiation.CreateAndSet(this);
}
}
class PrivateInstantiation {
private PrivateInstantiation() { }
public void Clone() {}
public static void CreateAndSet(MainClass mc) {
mc.PrivateInstantiation = new PrivateInstantiation();
}
}
请注意,我没有将您的班级称为单身,因为Clone
方法的存在似乎不会使其成为单身。
答案 3 :(得分:1)
让我们试一试:你需要prototype模式,而不是单身。
答案 4 :(得分:0)
单例模式意味着那个类只有一个实例。如果你的类有某种克隆方法,那么每个人都能够克隆这个实例。所以我看不出你的问题。
您的单身人员实施几乎是正确的,只有_mainInstance
和MainInstance
需要static
。
答案 5 :(得分:0)
像Monostate Pattern这样的东西?虽然这些实例都具有相同的状态,但这可能不是您想要的。