powershell重构函数到一个主函数

时间:2015-06-24 13:41:49

标签: powershell

我有几个函数使用相同的方法调用另一个函数或执行某些操作:

function doMyFn 
{
    if ($getProject -match 'all')
    {
        foreach ($project in $projectAllowedLst)
        {
             # section a
             # params to be passed to the script block below in this case it is $project
             # the command or function that are being called are to be set here (based on the $project)
        }
    }
    elseif ($getProject -match ',')
    {
        $projects = $getProject -split (',')

        foreach ($project in $projects)
        {         
             # section b
             # params to be passed to the script block below in this case it is $project
             # the command or function that are being called are to be set here (based on the $project)
        }
    }
    elseif ($getProject -notmatch ',')
    {
          # section c
          # params to be passed to the script block below in this case it is $getProject    
          # the command or function that are being called are to be set here (based on the $getProject)
    }
}

另一个看起来像这样的函数:

if (testBeforeBackup $project){doProjectBackup $project} else {updateXML $project}

和一个带开关和功能的块如下所示。所有这些都在上面的主函数中用于名为a,b,c

的所有部分
#function  1 
function one {
    if ($getProject -match 'all')
    {
        foreach ($project in @('de','idm'))
        {
            copyXML $project
        }   
    }
    elseif ($getProject -match ',') 
    {
        $projects = $getProject -split (',')

        foreach ($project in $projects)
        {
            copyXML $project
        }
    }
    elseif ($getProject -notmatch ',') 
    {
        copyXML $getProject
    }
}

#function 2
function two {
    if ($getProject -match 'all')
    {
        foreach ($project in $projectAllowedLst)
        {
            $dstAppList[$project] = readNewAppName $project
        }   
    }
    elseif ($getProject -match ',') 
    {
        $projects = $getProject -split (',')

        foreach ($project in $projects)
        {
            $dstAppList[$project] = readNewAppName $project
        }
    }
    elseif ($getProject -notmatch ',') 
    {
            $dstAppList[$getProject] = readNewAppName $getProject
    }
}

#function 4
funciton four {

    if ($getProject -match 'all')
    {
        foreach ($project in $projectAllowedLst)
        {
            switch($project)
            {
                'de'{ 
                        if (testBeforeBackup $project)
                        {
                            deleteFiles $e_dst_folder $noDeleteEfolders 
                        } 
                    }
                'home'{
                        if (testBeforeBackup $project)
                        {
                            deleteFiles $home_dst_folder $noDeleteHomefolders
                        }
                    }
                'idm'{
                        if (testBeforeBackup $project)
                        {
                            deleteFiles $i_dst_folder $noDeleteifolders
                        }
                    }
            }
            copyProject $project
        }   
    }
    elseif ($getProject -match ',') 
    {
        $projects = $getProject -split (',')

        foreach ($project in $projects)
        {
            switch($project)
            {
                'de'{ 
                        if (testBeforeBackup $project)
                        {
                            deleteFiles $e_dst_folder $noDeleteEfolders 
                        } 
                    }
                'home'{
                        if (testBeforeBackup $project)
                        {
                            deleteFiles $home_dst_folder $noDeleteHomefolders
                        }
                    }
                'idm'{
                        if (testBeforeBackup $project)
                        {
                            deleteFiles $i_dst_folder $noDeleteifolders
                        }
                    }
            }

            copyProject $project
        }
    }
    elseif ($getProject -notmatch ',') 
    {
            switch($getProject)
            {
                'de'{ 
                        if (testBeforeBackup $getProject)
                        {
                            deleteFiles $e_dst_folder $noDeleteEfolders 
                        } 
                    }
                'home'{
                        if (testBeforeBackup $getProject)
                        {
                            deleteFiles $home_dst_folder $noDeleteHomefolders
                        }
                    }
                'idm'{
                        if (testBeforeBackup $getProject)
                        {
                            deleteFiles $i_dst_folder $noDeleteifolders
                        }
                    }
            }

            copyProject $getProject
    }


}

有些变量可以从脚本范围访问,因此不必担心其他变量。

如何以更好的方式重构它?

1 个答案:

答案 0 :(得分:0)

我相信你希望你的函数作为单个参数对all作出反应,而不是像“wall,bash”那样 - 这件事匹配 all。您所要求的是“正确解析参数”,事实上,您只应该处理“全部”情况,其他所有内容都可以在数组中进行处理,然后在后续代码中将其视为数组。

假设$projectAllowedLst是你在参数中收到“all”时应解析的内容,这应该可以解决问题:

if ($getProject -ieq "all") {$getProject=$projectAllowedLst}
foreach ($project in $getProject) {
    # main body, only dependent on $project
}

更新:你应该对你的项目做更多的工作,我看到代码中有逻辑链接的变量,它们似乎包含有关一个项目的各种数据。因此,您将项目放入哈希表,每个项目描述包含目标文件夹,受保护文件夹(?)和名称的字段。一个例子:

$projectAllowedLst = @() # an array of projects
$projectAllowedLst += @{ 
    "Name" = "de";
    "DestinationFolder" = $e_dst_folder;
    "ProtectedFolders" = $noDeleteEfolders
} # "de" project
# same for other projects. 

然后,例如,您的“功能四”将被重写为:

function four (param $getProject) {
    if ($getProject -ieq "all") {$getProject=$projectAllowedLst}
    foreach ($project in $getProject) {
       deleteFiles $project.DestinationFolder $project.ProtectedFolders
       copyProject $project # better rewrite this one to use full project data
    }
}

但是,这会禁止您在函数中对"de","idm"进行硬编码,因为您必须将完整的项目数据填充到copyXML才能使其正常工作,但通常会使您的代码更清晰,数据更清晰更加结构化,并且可以允许您扩展到支持更多项目而无需重写每个功能。

更新2:如果您由于某种原因决定允许用户(或您自己)传递项目名称列表,您仍然可以这样做,但您必须自己控制对象类型。一个例子:

function copyXML (param $projects) {
    foreach ($project in $projects) {
        if ($project.getType().fullname -eq "System.String") {
            # we've been given a string - search for name
            $detailedProject = $projectAllowedLst | where {$_.name -eq $project}
            if ($detailedProject.getType().fullName -ne "System.Collections.Hashtable") 
                { $detailedProject=$detailedProject[0]}
            # TWO OR MORE projects? Take first one
            $project=$detailedProject
        } 
        # do your stuff with complete project data
    }
}