2008-10-07 23 views
3

我正在實現一個包裝一個非常嚴格定義的模式的XML文檔的類。我不控制架構。如何向我的班級的用戶指出驗證要求?

該類中的一個屬性是模式指示必須與特定正則表達式匹配的元素值。在屬性的setter中,如果一個字符串與表達式不匹配,我會拋出一個異常。

我的問題是,我怎樣才能更好地向我的班級的用戶傳達這個領域的要求?有我可以使用的屬性嗎? Xml評論(所以它顯示在intellisense中)?我應該做除了拋出異常之外的其他東西嗎?我還有什麼其他選擇?

回答

0

感謝您的意見。

我在思考這個問題時想到的一個想法是創建一個名爲MatchedString的新類來強制約束。

它會有一個構造函數需要一個正則表達式字符串,並且在構建之後,表達式只會通過只讀屬性向用戶公開。然後它將擁有一個值屬性,用戶可以設置它來檢查設置器中的表達式。

我的想法是,我可以那麼還可以創建選項,不同的行爲時所使用的驗證在枚舉失敗,讓用戶指定他們希望:

  • 設置爲空字符串
  • 集空字符串,並拋出異常
  • 設置錯誤值反正
  • 設置錯誤值,無論如何,並拋出錯誤時拋出
  • 只是拋出異常
  • 無能爲力

另外,我在想,這將讓我的用戶類做一些基本的測試,而無需重複regex對象在自己的代碼。向/從字符串類型中隱式轉換,並且對類用戶應該是直觀的。

對此有何看法?

+0

我相信這將是一個適當的重構,符合單一責任主體(類應該只有一個原因來改變)。 – ckramer 2008-10-09 23:51:15

0

將它記錄在XML註釋中,並引發異常。使消息明確:

「元素<elementname> must match/regex /」;

這就是你所能做的一切。

0

您的代碼文檔應該滿足需求,或者模式的文檔應該解釋需求。對於那些不打算研究即將使用的代碼的人,你無能爲力。

+0

當然架構文檔解釋它,但類的重點是隱藏需要使用它們。我的文檔已經解釋了它,但我正在尋找更多的「在你臉上」來幫助實施它。 – 2008-10-07 17:18:57

1

XmlComments可能會幫助您將它們與您的程序集一起發貨,但我會說如果不滿足要求,最好拋出異常,並儘可能詳細地創建異常消息。如果在用戶調用時方法不符合要求,並且方法/屬性依賴於屬性,我還會拋出異常(同樣有很多細節)。

確實有很多事情可以讓第一次使用代碼來避免錯誤,但是當錯誤發生時如何糾正錯誤應該儘可能清楚。

+0

upvote。我認爲例外應該是非常特殊的。如果這段代碼直接接受來自最終用戶的輸入,它可能不是(也就是說:我不想強制我的類用戶複製正則表達式,以避免讓最終用戶引起異常)。 – 2008-10-07 17:21:04

0

無論我使用它,實現一個MatchedString類看起來都很有趣。所以這裏是:

Public Class MatchedString 
    Public Enum InvalidValueBehaviors 
     SetToEmpty 
     AllowSetToInvalidValue 
     DoNothing 
    End Enum 

    Public Sub New(ByVal Expression As String) 
     Me.expression = Expression 
     exp = New Regex(Me.expression) 
    End Sub 

    Public Sub New(ByVal Description As String, ByVal Expression As String) 
     Me.expression = Expression 
     exp = New Regex(Me.expression) 
     _expressiondescription = Description 
    End Sub 

    Public Sub New(ByVal Expression As String, ByVal ThrowOnInvalidValue As Boolean, ByVal InvalidValueBehavior As InvalidValueBehaviors) 
     Me.expression = Expression 
     exp = New Regex(Me.expression) 
     Me.ThrowOnInvalidValue = ThrowOnInvalidValue 
     Me.InvalidValueBehavior = InvalidValueBehavior 
    End Sub 

    Public Sub New(ByVal Description As String, ByVal Expression As String, ByVal ThrowOnInvalidValue As Boolean, ByVal InvalidValueBehavior As InvalidValueBehaviors) 
     Me.expression = Expression 
     exp = New Regex(Me.expression) 
     _expressiondescription = Description 
     Me.ThrowOnInvalidValue = ThrowOnInvalidValue 
     Me.InvalidValueBehavior = InvalidValueBehavior 
    End Sub 

    Private exp As Regex 
    Private expression As String 

    Public ReadOnly Property MatchExpression() As String 
     Get 
      Return expression 
     End Get 
    End Property 

    Public ReadOnly Property ExpressionDescription() As String 
     Get 
      Return _expressiondescription 
     End Get 
    End Property 
    Private _expressiondescription As String 

    Public Function CheckIsMatch(ByVal s As String) 
     Return exp.IsMatch(s) 
    End Function 

    Public Property ThrowOnInvalidValue() As Boolean 
     Get 
      Return _thrownoninvalidvalue 
     End Get 
     Set(ByVal value As Boolean) 
      _thrownoninvalidvalue = value 
     End Set 
    End Property 
    Private _thrownoninvalidvalue = True 

    Public Property InvalidValueBehavior() As InvalidValueBehaviors 
     Get 
      Return _invalidvaluebehavior 
     End Get 
     Set(ByVal value As InvalidValueBehaviors) 
      _invalidvaluebehavior = value 
     End Set 
    End Property 
    Private _invalidvaluebehavior As InvalidValueBehaviors = InvalidValueBehaviors.DoNothing 

    Public Property Value() As String 
     Get 
      Return _value 
     End Get 
     Set(ByVal value As String) 
      If value Is Nothing Then value = "" 'Never set to Nothing 

      If CheckIsMatch(value) Then 
       _value = value 
      Else 
       Select Case InvalidValueBehavior 
        Case InvalidValueBehaviors.AllowSetToInvalidValue 
         _value = value 
        Case InvalidValueBehaviors.SetToEmpty 
         _value = "" 
       End Select 

       If ThrowOnInvalidValue Then 
        Throw New ArgumentOutOfRangeException(String.Format("String: {0} does not match expression: {1}", value, MatchExpression)) 
       End If 
      End If 
     End Set 
    End Property 
    Private _value As String = "" 

    Public Overrides Function ToString() As String 
     Return _value 
    End Function 
End Class