2014-09-04 75 views
0

我有以下代碼。我有兩個不同的工作,它們調用下面提到的處理器類。這兩項工作幾乎完全相同,但只有在最後一步纔會有所不同。目前,我正在基於布爾變量'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

請使用語法高亮顯示 – 2014-09-04 18:51:40

+0

我沒有看到問題。模板方法聽起來像一個合理的方法。什麼阻止你在抽象類中定義存儲庫變量? – 2014-09-05 07:23:44

回答

1

我會分裂在表達流不同類別的Process方法,你希望你的代碼遵循。然後將這些類傳遞到主算法的後面,這樣您就可以動態地替換部分行爲。

在這種情況下,您希望列出資產並處理每項資產。該過程執行N次操作並完成資產(即或者同步創建報告)。讓我們把它分解成子/界面,我們可以使用:

  • IAssetListCreator {IEnumerable的CreateAssetList();}
  • IAssetProcessor {無效處理(資產一,IAssetFinalizer AF);}
  • IAssetFinalizer {無效敲定(一資產);}

現在你可以撰寫不同的磚塊,以複製你有算法之前:

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,則創建一個繼承自使用構造函數中的repositoryA的IAssetFinalizer的類。本着同樣的精神,只有IAssetListCreator實例需要了解資產所在的路徑,或者是否應該涉及緩存等等。

我全速前進,打破原始代碼;您仍然可以使用Process函數中的列表代碼,但是您真正受益於將參數限制爲需要它們的組件:

相關問題