我有以下代码。我有两个不同的工作,它们调用相同的下面提到的处理器类。这两项工作几乎完全相同,但仅在最后一步有所不同。目前,我正在基于布尔变量' createReport'来处理它。我想将90%的常用功能提取到一个类中。
我想到了模板模式。但是我如何在抽象类中注入repositoryA的依赖?
Imports log4net
Imports System
Imports System.Collections.Generic
Public Interface IProcessor
Sub Process(path As String, includeCache As Boolean, createReport As Boolean)
End Interface
Public Class Processor
Implements IProcessor
Private ReadOnly _repositoryA As IRepositoryA
Private ReadOnly _repositoryB As IRepositoryB
Private ReadOnly _logger As ILog
Public Sub New(repositoryA As IRepositoryA, repositoryB As IRepositoryB, logger As ILog)
If repositoryA Is Nothing Then
Throw New ArgumentNullException("repositoryA")
End If
If repositoryB Is Nothing Then
Throw New ArgumentNullException("repositoryB")
End If
If logger Is Nothing Then
Throw New ArgumentNullException("logger")
End If
_repositoryA = repositoryA
_repositoryB = repositoryB
_logger = logger
End Sub
Public Sub Process(folderPaths As String, includeCache As Boolean, createReport As Boolean) Implements IProcessor.Process
_logger.Info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
If String.IsNullOrEmpty(folderPaths) Then
Throw New ArgumentNullException("folderPaths")
End If
Dim paths() As String = folderPaths.Split(New Char() {";"c})
For Each path As String In paths
Dim cList As List(Of Container) = _repositoryA.GetContainers(path, includeCache)
For Each container As Container In cList
If Not container.IsDeleted Then
Dim assetList As List(Of Asset) = _repositoryA.GetAssets(container.ContainerID)
If Not assetList Is Nothing Then
For Each asset As Asset In assetList
ProcessAsset(asset, createReport)
Next
End If
End If
Next
Next
_logger.Info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
End Sub
Private Sub ProcessAsset(asset As Asset, createReport As Boolean)
'Again some common business logic
'at last depending on value of createReport
If createReport Then
CreateReport(asset)
Else
SyncAsset(asset, ...other arguments)
End If
End Sub
Private Sub SyncAsset(asset As asset, ..other arguments)
'business logic. Dependency on _repositoryB here
End Sub
Private Sub CreateReport(asset As asset)
'business logic
End Sub
End Class
感谢您的帮助
此致 Suyog
答案 0 :(得分:1)
我会将您的Process
方法划分为表达您希望代码遵循的流程的不同类。然后将抽象背后的类传递给主算法,这样就可以动态地交换部分行为。
在这种情况下,您希望列出资产并处理每个资产。该过程执行N次操作并最终确定资产(即,同步它创建报告)。让我们将它分解为我们可以使用的子组件/接口:
现在你可以编写不同的砖块来复制你以前的算法:
Public Interface IProcessor
Sub Process(creator as IAssetListCreator, processor as IAssetProcessor, finalizer as IAssetFinalizer)
End Interface
' inside the process class
Public Sub Process(creator as IAssetListCreator, processor as IAssetProcessor, finalizer as IAssetFinalizer) Implements IProcessor.Process
_logger.Info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
For Each asset As Asset In creator.CreateAssetList()
processor.Process(asset, finalizer)
Next
_logger.Info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
End Sub
' inside the IAssetProcessor
Private Sub ProcessAsset(asset As Asset, finalizer as IAssetFinalizer)
'Again some common business logic
finalizer.Finalize(asset)
End Sub
现在可以仅使用所需的元素构造每个组件:如果仅在同步行为中需要repositoryA,则创建一个继承自IAssetFinalizer
的类,该类在构造函数中使用repositoryA。本着同样的精神,只有IAssetListCreator
实例需要知道资产所在的路径,或者是否应该涉及缓存等......
我在打破原始代码方面全力以赴;您仍然可以使用Process函数中的列表代码,但您确实可以将参数限制为需要它们的组件: