2009-11-06 3 views
3

Иногда возникает необходимость инициализировать класс singleton с некоторыми вспомогательными значениями. Но мы не можем «публиковать» конструктор для него. Каков обходной путь для этого?как инициализировать Singleton?

Внимание! перегрузка GetInstance или установка цвета - это не моя идея. Цвет должен быть установлен только один раз. Я хотел бы быть уверенным, что MyPainter рисует ТОЛЬКО с инициализированным цветом. Должен использоваться любой цвет по умолчанию.

Для большей ясности я предоставить образец:

''' <summary> 
''' Singleton class MyPainter 
''' </summary> 
Public Class MyPainter 
    Private Shared _pen As Pen 
    Private Shared _instance As MyPainter = Nothing 

    Private Sub New() 
    End Sub 

    ''' <summary> 
    ''' This method should be called only once, like a constructor! 
    ''' </summary> 
    Public Shared Sub InitializeMyPainter(ByVal defaultPenColor As Color) 
    _pen = New Pen(defaultPenColor) 
    End Sub 


    Public Shared Function GetInstance() As MyPainter 
    If _instance Is Nothing Then 
     _instance = New MyPainter 
    End If 

    Return _instance 
    End Function 

    Public Sub DrawLine(ByVal g As Graphics, ByVal pointA As Point, ByVal pointB As Point) 
    g.DrawLine(_pen, pointA, pointB) 
    End Sub 

End Class 

Спасибо.

ответ

2

Не могли бы вы просто перегрузить метод GetInstance?

Dim _IsInitialized as boolean = false  
Public Shared ReadOnly Property IsInitialized() As Boolean 
     Get 
      Return _IsInitialized 
     End Get 
    End Property 


Public Shared Function GetInstance() As MyPainter 
     If _instance Is Nothing Then 
      _instance = New MyPainter 
     End If 

     _IsInitialized = True 
     Return _instance 
    End Function 

    Public Overloads Shared Function GetInstance(ByVal DefaultPenColor As Color) As MyPainter 
     If _instance Is Nothing Then 
      _instance = New MyPainter 
      InitializeMyPainter(DefaultPenColor) 
     End If 

     _IsInitialized = True 
     Return _instance 
    End Function 

Прежде чем приступить к методу GetInstance, отметьте, было ли оно еще включено. Если не дать цвет пера.

If MyPainter.IsInitialized then 
    Dim Painter as MyPainter = MyPainter.GetInstance 
Else 
    Dim Painter as MyPainter - MyPainter.GetInstance(System.Drawing.Color.Red) 
EndIf 
+0

нет, перегрузки GetInstance не была моей хорошей идеей. Я хотел бы заверить, что MyPainter рисует ТОЛЬКО с инициализированным цветом. Любой цвет по умолчанию по умолчанию должен использоваться. – serhio

+0

То, как я перегрузил GetInstance, только установил цвет пера один раз (в первый раз он называется).Вы можете добавить дополнительный общий элемент, чтобы узнать, был ли класс иналинизирован. Я обновил образец кода. Дайте мне знать, если это еще не то, что вы ищете. –

+0

Согласен. Однако у вашей функции нет прозрачного смысла быть публичным и может вызвать ошибку (новый) разработчик ... И во-вторых, только я, этот создатель синглтона, будет знать и помнить, не забудьте установить цвет перед его использованием. _IsInitialized = True без параметров GetInstance неверен, потому что я ничего не знаю о том, был ли цвет инициализирован или нет. – serhio

1

Вы можете объявить Shared конструкторов, но они должны быть без параметров:

Public Class MyPainter 
    Private Shared _pen As Pen 

    Shared Sub New() 
     _pen = New Pen(Color.White) 
    End Sub 

    .... 

End Class 

Вы можете установить цвет на разумный умолчанию в конструкторе, а затем добавить вспомогательный метод для изменения цвета, при желании, так же, как у вас в образце:

Public Shared Sub SetColor(ByVal defaultPenColor As Color) 
    _pen = New Pen(defaultPenColor) 
End Sub 
1

вы можете использовать дополнительный параметр в GetInstance

Public Shared Function GetInstance(Optional ByVal defaultPenColor As Color = Colors.Red) As MyPainter 
    If _instance Is Nothing Then 
     If defaultPenColor is nothing then 
      defaultPenColor = Colors.Red 
     end if 
     _pen = New Pen(defaultPenColor) 
     _instance = New MyPainter 
    End If 

    Return _instance 
End Function 
+0

Итак, в зависимости от того, вызвана ли функция GetInstance() с параметрами или без них в первый раз, следующие вызовы получат разные объекты? Это работает только в том случае, если вы всегда можете быть уверены в том, кто сначала называет GetInstance(). –

+0

Нет, они получат тот же объект. В конце концов, это одноэлементный класс. Единственное, что меняется, это исходный цвет пера. –

+0

Правильно, вот что я имел в виду. Я просто не могу сегодня мыслить в словах ... Тем не менее это проблема, если вы не можете контролировать первый вызов. –

3

Если вы хотите инициализировать его только один раз при создании, почему бы не сделать это внутри конструктора, вызвав какой-то метод, который будет вытаскивать параметры откуда-то? Если эта инициализация будет вызываться несколько раз - превратите ее в отдельный метод, например setOptions.

+0

К сожалению, MyPainter не знает себя, откуда взять эти параметры ... И цвет по умолчанию должен быть явно определен. – serhio

0

Создайте метод CreateInstance, который принимает требуемые параметры. И удалите способность создания от GetInstance. Тогда не полностью синглтон, но, по крайней мере, вы ЗНАЕТЕ, что все будет правильно инициализировано.

0

Вы можете использовать Init-метод: (Это C# пример, я побежал в том же номере с initializable одиночек)

public sealed class XSingleton 
{ 
    private static XSingleton instance = null; 
    int value = -1; 

    private XSingleton(int v) 
    { 
     value = v; 
    } 

    public static void Init(int v) 
    { 
     if (instance != null) throw new Exception("Init() must be called only once!"); 
     instance = new XSingleton(v); 
    } 

    public static XSingleton Instance 
    { 
     get 
     { 
      if (instance == null) throw new Exception("Call Init() before!"); 
      return instance; 
     } 
    } 

    public int Value { get { return value; } } 
} 

Если вы пытаетесь использовать XSingleton unitinialized или попытаться инициализировать несколько раз , вы получаете исключение.

Таким образом, вы инициализировать синглтон с

XSingleton.Init(123); 

Теперь вы можете использовать инициализированную Значение:

Console.WriteLine(XSingleton.Instance.Value); 
Смежные вопросы