首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多层应用配置

多层应用配置
EN

Code Review用户
提问于 2015-11-05 17:23:29
回答 1查看 71关注 0票数 0

上下文:下面的代码用于根据应用程序中的多个配置层查找设置值。对于任何给定的设置(即:默认打印机),可以按照优先级顺序在以下级别配置应用程序。

  1. 操作
  2. 材料
  3. 工作站与程序组合
  4. 工作站
  5. 程序
  6. 用户

当应用程序需要设置时,它通过提供上下文中可用的尽可能多的信息来执行查找,然后搜索每个级别并使用它找到的第一个值。如果没有找到值,调用方将处理默认操作。

逻辑层

这是应用程序中需要查找设置值的任何部分将调用的函数。调用方必须指定设置ID和一个或多个其他参数。这里的目的是让调用者只查找“工作站”级别设置。

代码语言:javascript
运行
复制
 Public Function SettingLookup(operationID As String,
                              materialID As String,
                              userID As String,
                              plantID As String,
                              workstationID As String,
                              programID As String,
                              settingID As String
                              ) As String()

    If settingID = "" Then
        Throw New Exception("Setting ID Required")
    End If

    Dim settingValue = SettingLookupHelper(operationID, materialID, userID, plantID, workstationID, programID, settingID)

    If settingValue IsNot Nothing Then
        Return JsonConvert.DeserializeObject(Of String())(settingValue)
    Else
        Return Nothing
    End If

End Function

该函数用于访问数据访问层并从数据库获取设置。

代码语言:javascript
运行
复制
Private Function SettingLookupHelper(operationID As String,
                                     materialID As String,
                                     userID As String,
                                     plantID As String,
                                     workstationID As String,
                                     programID As String,
                                     settingID As String
                                     ) As String

    Dim settingValue As Setting

    If operationID <> "" Then
        settingValue = GetOperationSetting(operationID, settingID)

        If settingValue IsNot Nothing Then
            Return settingValue.Value
        End If
    End If

    If materialID <> "" Then
        settingValue = GetMaterialSetting(materialID, settingID)

        If settingValue IsNot Nothing Then
            Return settingValue.Value
        End If
    End If

    If workstationID <> "" And programID <> "" Then
        settingValue = GetWorkstationProgramSetting(workstationID, programID, settingID)

        If settingValue IsNot Nothing Then
            Return settingValue.Value
        End If
    End If

    If workstationID <> "" Then
        settingValue = GetWorkstationSetting(workstationID, settingID)

        If settingValue IsNot Nothing Then
            Return settingValue.Value
        End If
    End If

    If programID <> "" Then
        settingValue = GetProgramSetting(programID, settingID)

        If settingValue IsNot Nothing Then
            Return settingValue.Value
        End If
    End If

    If userID <> "" Then
        settingValue = GetUserSetting(userID, settingID)

        If settingValue IsNot Nothing Then
            Return settingValue.Value
        End If
    End If

    If plantID <> "" Then
        settingValue = GetPlantSetting(plantID, settingID)

        If settingValue IsNot Nothing Then
            Return settingValue.Value
        End If
    End If

    Return Nothing

End Function

数据访问层

这是我在数据访问层中为上面列出的每个配置级别编写的代码的一个例子。每个文件都包含访问设置表的代码,其中定义了设置,还有一个多到多连接表(即: Material_Settings或Operation_Settings),用于设置设置值并将其链接到实体,如材料、操作或用户。在我的数据访问层中有很多几乎重复的代码来支持这个设计。

代码语言:javascript
运行
复制
Public Class MaterialSetting
    Inherits Setting

    Private _MaterialID As String
    Public Property Material_ID() As String
        Get
            Return _MaterialID
        End Get
        Set(ByVal value As String)
            _MaterialID = value
        End Set
    End Property


    Private _Material As String
    Public Property Material() As String
        Get
            Return _Material
        End Get
        Set(ByVal value As String)
            _Material = value
        End Set
    End Property


End Class


Public Module MaterialSettingsUtilities


    Public Function GetMaterialSetting(materialID As String, settingID As String) As MaterialSetting

        Dim parameters As New Dictionary(Of String, Object)
        parameters.Add("Material_ID", materialID)
        parameters.Add("Setting_ID", settingID)

        Dim queryCondition As String
        queryCondition = " WHERE Material_ID = HEXTORAW(:Material_ID) AND Setting_ID = HEXTORAW(:Setting_ID) "

        Dim settings As Settings = GetMaterialSettingsFiltered(parameters, queryCondition)

        If settings.Count > 0 Then
            Return CType(settings(0), MaterialSetting)
        Else
            Return Nothing
        End If

    End Function


    Private Function GetMaterialSettingsFiltered(parameters As Dictionary(Of String, Object), queryCondition As String) As Settings

        Dim query As String
        query = " SELECT * "
        query += "  FROM (Materials NATURAL JOIN Material_Settings) "
        query += "       NATURAL JOIN Settings "
        query += queryCondition

        Using conn As New OracleConnection(GetConnectionString("WeighScaleDB"))
            Using cmd = CreateOracleCommand(query, parameters, conn)

                conn.Open()

                Using dr = cmd.ExecuteReader

                    Dim settings As New Settings

                    If Not dr.Read() Then
                        Return settings
                    End If

                    Do
                        settings.Add(New MaterialSetting With {
                                     .Setting_ID = ConvertByteArrayToString(TryCast(dr("Setting_ID"), Byte())),
                                     .Material_ID = ConvertByteArrayToString(TryCast(dr("Material_ID"), Byte())),
                                     .Material = dr("Material").ToString(),
                                     .Value = dr("Setting_Value").ToString(),
                                     .Name = dr("Setting_Name").ToString(),
                                     .Description = dr("Setting_Description").ToString(),
                                     .DataType = dr("Setting_Data_Type").ToString(),
                                     .Category = dr("Setting_Category").ToString()
                                 })
                    Loop While dr.Read()

                    Return settings

                End Using
            End Using
        End Using

    End Function


End Module

这是从其中派生每个子类型(即: MaterialSetting)的Settings对象。

代码语言:javascript
运行
复制
Public Class Setting

    Private _SettingID As String
    Public Property Setting_ID() As String
        Get
            Return _SettingID
        End Get
        Set(ByVal value As String)
            _SettingID = value
        End Set
    End Property

    Private _SettingName As String
    Public Property Name() As String
        Get
            Return _SettingName
        End Get
        Set(ByVal value As String)
            _SettingName = value
        End Set
    End Property

    Private _SettingDescription As String
    Public Property Description() As String
        Get
            Return _SettingDescription
        End Get
        Set(ByVal value As String)
            _SettingDescription = value
        End Set
    End Property

    Private _SettingDataType As String
    Public Property DataType() As String
        Get
            Return _SettingDataType
        End Get
        Set(ByVal value As String)
            _SettingDataType = value
        End Set
    End Property

    Private _SettingCategory As String
    Public Property Category() As String
        Get
            Return _SettingCategory
        End Get
        Set(ByVal value As String)
            _SettingCategory = value
        End Set
    End Property

    Private _SettingValue As String
    Public Property Value() As String
        Get
            Return _SettingValue
        End Get
        Set(ByVal value As String)
            _SettingValue = value
        End Set
    End Property        
End Class

如对此有任何建设性的想法,将不胜感激。我可以发布表结构的示例或代码中显示的任何其他助手或DAL函数。

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-11-06 07:29:18

SettingLookup

如果settingID = "“,则抛出新异常(”设置ID必需“)结束

  • 您不应该仅仅抛出一个Exception,而是应该抛出一个ArgumentException。从异常设计指南抛出最具体(派生最多)的异常是适当的。例如,如果一个方法收到null ( Visual中为Nothing)参数,它应该抛出System.ArgumentNullException而不是其基本类型System.ArgumentException。
  • 海事组织,你应该测试settingID是否也是null (没什么)。如果settingID为Nothing,则抛出新ArgumentNullException(" settingID "),否则,如果settingID= String.Empty,则抛出新ArgumentException(“设置ID必需”)
  • 在这里,如果settingValue IsNot Nothing,则返回JsonConvert.DeserializeObject(Of String())(settingValue),否则,如果Else是冗余的,则不返回结束,因为如果If条件为true,则Else部分将被嵌套命中。如果settingValue IsNot Nothing,那么返回JsonConvert.DeserializeObject(Of String())(settingValue)如果不返回

SettingLookupHelper

  • SettingLookupHelper是名词,但是方法名称应该由动词或动词短语组成。请参阅:网络命名准则
  • 与其检查"",我建议检查String.Empty,这是海事组织更易读,至少当你变老,你的眼睛变坏,你会同意。

MaterialSetting & Setting

如果您使用VS 2010,您可以/应该使用自动实现的属性,至少如果您没有在setter中进行任何验证,并且不需要不同的可访问性修饰符(**Private**,Public等等)。

你的MaterialSetting就会变成这样

代码语言:javascript
运行
复制
Public Class MaterialSetting
    Inherits Setting

    Public Property Material_ID As String
    Public Property Material As String

End Class

Setting类将如下所示

公共类设置

代码语言:javascript
运行
复制
Public Property Setting_ID As String
Public Property Name As String
Public Property Description As String
Public Property DataType As String
Public Property Category As String
Public Property Value As String

端级

看上去干净多了,不是吗?

GetMaterialSetting

看起来对冗余的Else**.**很有期望

GetMaterialSettingsFiltered

字符串连接

Dim查询为字符串查询=“SELECT *”query +=“FROM (资料自然连接Material_Settings)”“query +=”天然连接设置“查询+= queryCondition”

每次创建一个新的String对象,因为字符串是不可变的。您应该考虑使用行延续_,如下所示

代码语言:javascript
运行
复制
query = " SELECT * " _
      + "  FROM (Materials NATURAL JOIN Material_Settings) " _
      + "       NATURAL JOIN Settings " _
      + queryCondition  

您应该考虑是否最好只将您需要的字段包含到Select中,而不是返回所有列。当然,您可以说您需要所有这些列,但是如果您或其他人向datatable中添加了更多的列(这些列是其他东西所需的),则仍然会返回所有列。

您正在使用Using,这很好。

您正在使用一个参数化查询,这也很好。

您应该考虑将实际的数据检索提取到一个单独的数据访问层,该层不应该知道这些MaterialSetting**'s (或任何其他类)中的任何一个,它只返回一个** DataSet或一个DataTable*。

这样,您就可以在项目中的任何地方使用它。

沿着这条线的东西

代码语言:javascript
运行
复制
Public Function GetRecords(parameters As Dictionary(Of String, Object), query As String, connectionString As String) As DataTable

    Using DataTable table As New DataTable()
        Using conn As New OracleConnection(connectionString)
            Using cmd = CreateOracleCommand(query, parameters, conn)
                Using adapter As New OracleDataAdapter(cmd)
                     adapter.Fill(table)
                     Return table
                End Using
            End Using
        End Using
    End Using
End Function  

这样就可以被称为

代码语言:javascript
运行
复制
Private Function GetMaterialSettingsFiltered(parameters As Dictionary(Of String, Object), queryCondition As String) As Settings

    Dim query As String = " SELECT * " _
                        + "  FROM (Materials NATURAL JOIN Material_Settings) " _
                        + "       NATURAL JOIN Settings " _
                        + queryCondition

    Dim settings As New Settings()

    Dim table As DataTable = GetRecords(parameters, query, GetConnectionString("WeighScaleDB"))

    If table Is Nothing Then
        Return settings
    End If

    For Each row As DataRow In table.Rows
        settings.Add(New MaterialSetting With {
                                 .Setting_ID = ConvertByteArrayToString(TryCast(row("Setting_ID"), Byte())),
                                 .Material_ID = ConvertByteArrayToString(TryCast(row("Material_ID"), Byte())),
                                 .Material = row("Material").ToString(),
                                 .Value = row("Setting_Value").ToString(),
                                 .Name = row("Setting_Name").ToString(),
                                 .Description = row("Setting_Description").ToString(),
                                 .DataType = row("Setting_Data_Type").ToString(),
                                 .Category = row("Setting_Category").ToString()
                             })
    Next

    Return settings

End Function

GetRecords()这个名字并没有那么好,也许你可以想出一个更好的名字。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/109909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档