Powershell-и функсионалӣ бо синфҳо оксиморон нест, ман кафолат медиҳам

Салом, Хабр! Ман ба диққати шумо тарҷумаи мақоларо пешкаш мекунам "PowerShell функсионалӣ бо синфҳо.
Ман ваъда медиҳам, ки ин оксиморон нест"
аз ҷониби Кристофер Куч.

Парадигмаҳои барномасозии ба объект нигаронидашуда ва функсионалӣ метавонанд бо ҳамдигар мухолифат кунанд, аммо ҳарду дар Powershell баробар дастгирӣ карда мешаванд. Қариб ҳамаи забонҳои барномасозӣ, ки функсионалӣ ё не, дорои имконоти васеъи ҳатмии ном ва арзиш доранд; Синфҳо, ба монанди сохторҳо ва сабтҳо, танҳо як равиш мебошанд. Агар мо истифодаи Классҳоро бо ҳатмии номҳо ва арзишҳо маҳдуд кунем ва аз мафҳумҳои барномасозии вазнин ба объект нигаронидашуда, ба монанди мерос, полиморфизм ё тағирёбӣ канорагирӣ кунем, мо метавонем аз онҳо бидуни мушкилсозии коди худ истифода барем. Ғайр аз он, бо илова кардани усулҳои табдили навъи тағирнопазир, мо метавонем рамзи функсионалии худро бо Синфҳо ғанӣ гардонем.

Сеҳри кастаҳо

Кастҳо яке аз хусусиятҳои пурқувват дар Powershell мебошанд. Вақте ки шумо арзиш мегузоред, шумо ба қобилиятҳои ибтидоӣ ва тасдиқи муҳити атроф ба барномаи шумо илова мекунад, такя мекунед. Масалан, танҳо гузоштани сатр дар [xml] онро тавассути коди таҳлилгар иҷро мекунад ва дарахти пурраи xml тавлид мекунад. Мо метавонем Синфҳоро дар коди худ бо ҳамин мақсад истифода барем.

Ҷадвалҳои резиши

Агар шумо конструктор надошта бошед, шумо метавонед бо гузоштани hashttable ба навъи синфи худ бидуни он идома диҳед. Фаромӯш накунед, ки атрибутҳои тасдиқро барои пурра истифода бурдани ин намуна истифода баред. Ҳамзамон, мо метавонем хосиятҳои чопшудаи синфро истифода барем, то мантиқи боз ҳам амиқтар оғозсозӣ ва тасдиқро иҷро кунем.

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index
}

[Cluster]@{
    Service       = "MyService"
    FlightingRing = "PROD"
    Region        = "EastUS"
    Index         = 2
}

Илова бар ин, рехтагарӣ барои ба даст овардани ҳосили тоза кӯмак мекунад. Натиҷаи массиви hashtable Cluster, ки ба Формат-Ҷадвал дода шудааст, бо он чизе, ки шумо мегиред, агар шумо аввал ин хэштедҳоро ба синф гузоред, муқоиса кунед. Хусусиятҳои синф ҳамеша бо тартибе, ки дар он ҷо муайян карда шудаанд, номбар карда мешаванд. Фаромӯш накунед, ки пеш аз ҳама хосиятҳое, ки шумо намехоҳед дар натиҷаҳо намоён шаванд, калимаи калидии пинҳоншударо илова кунед.

Powershell-и функсионалӣ бо синфҳо оксиморон нест, ман кафолат медиҳам

Мафҳуми маъноҳо

Агар шумо як созанда бо як аргумент дошта бошед, гузоштани арзиш ба навъи синфи шумо арзишро ба созандаи шумо интиқол медиҳад, ки дар он шумо метавонед як мисоли синфи худро оғоз кунед

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index

    Cluster([string] $id) {
        $this.Service, $this.FlightingRing, $this.Region, $this.Index = $id -split "-"
    }
}

[Cluster]"MyService-PROD-EastUS-2"

Ба сатр партоед

Шумо инчунин метавонед усули синфи [string] ToString()-ро бекор кунед, то мантиқи паси намоиши сатри объектро муайян кунед, ба монанди истифодаи интерполятсияи сатр.

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index

    [string] ToString() {
        return $this.Service, $this.FlightingRing, $this.Region, $this.Index -join "-"
    }
}

$cluster = [Cluster]@{
    Service       = "MyService"
    FlightingRing = "PROD"
    Region        = "EastUS"
    Index         = 2
}

Write-Host "We just created a model for '$cluster'"

Нақшаҳои сериализатсияшуда

Cast имкон медиҳад, ки сериализатсияи бехатар. Намунаҳои дар поён овардашуда ноком мешаванд, агар маълумот ба мушаххасоти мо дар Кластер мувофиқат накунад

# Валидация сериализованных данных

[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"

Дар рамзи функсионалии шумо ҷойгир карда мешавад

Барномаҳои функсионалӣ аввал сохторҳои додаҳоро муайян мекунанд, сипас барномаро ҳамчун пайдарпаии табдили сохторҳои тағирнопазири додаҳо амалӣ мекунанд. Сарфи назар аз таассуроти зиддиятнок, дарсҳо воқеан ба шумо дар навиштани коди функсионалӣ ба шарофати усулҳои табдилдиҳии намуд кӯмак мекунанд.

Оё Powershell, ки ман менависам, кор мекунад?

Бисёр одамоне, ки аз C# ё заминаҳои шабеҳ омадаанд, Powershell менависанд, ки ба C# монанд аст. Бо ин кор, шумо аз истифодаи консепсияҳои барномасозии функсионалӣ дур мешавед ва эҳтимол аз ғарқ шудан ба барномасозии ба объект нигаронидашуда дар Powershell ё омӯзиши бештар дар бораи барномасозии функсионалӣ манфиат хоҳед гирифт.

Агар шумо бештар ба табдил додани додаҳои тағирнашаванда бо истифода аз қубурҳо (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object ва ғайра такя кунед - шумо услуби функсионалии бештар доред ва аз истифодаи Powershell манфиат хоҳед гирифт. дарсҳо дар услуби функсионалӣ.

Истифодаи функсионалии синфҳо

Кастҳо, гарчанде ки онҳо синтаксиси алтернативӣ истифода мебаранд, танҳо харитасозии байни ду домен мебошанд. Дар лӯла шумо метавонед бо истифода аз ForEach-Object як қатор арзишҳоро харита кунед.

Дар мисоли дар поён овардашуда, конструктори Node ҳар дафъае, ки Datum дода мешавад, иҷро мешавад ва ин ба мо имкон медиҳад, ки миқдори одилонаи кодро нанависем. Дар натиҷа, лӯлаи мо ба пурсиш ва ҷамъбасти декларативии додаҳо тамаркуз мекунад, дар ҳоле ки синфҳои мо ба таҳлил ва тасдиқи додаҳо ғамхорӣ мекунанд.

# Пример комбинирования классов с конвейерами для separation of concerns в конвейерах

class Node {
    [ValidateLength(3, 7)]
    [string] $Name
    [ValidateSet("INT", "PPE", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope", "WestEurope")]
    [string] $Region
    Node([string] $Name) {
        $Name -match "([a-z]+)(INT|PPE|PROD)([a-z]+)"
        $_, $this.Service, $this.FlightingRing, $this.Region = $Matches
        $this.Name = $Name
    }
}

class Datum {
    [string] $Name
    [int] $Value
    [Node] $Computer
    [int] Severity() {
        $this.Name -match "[0-9]+$"
        return $Matches[0]
    }
}

Write-Host "Urgent Security Audit Issues:"
Import-Csv "./audit-results.csv" `
    | ForEach-Object {[Datum]$_} `
    | Where-Object Value -gt 0 `
    | Group-Object {$_.Severity()} `
    | Where-Object Name -lt 2 `
    | ForEach-Object Group `
    | ForEach-Object Computer `
    | Where-Object FlightingRing -eq "PROD" `
    | Sort-Object Name, Region -Unique

Синфи бастабандӣ барои истифодаи дубора

Ҳеҷ чиз он қадар хуб нест, ки ба назар мерасад

Мутаассифона, синфҳоро бо модулҳо ба мисли функсияҳо ё тағирёбандаҳо содир кардан мумкин нест; вале баъзе найрангхо мавчуданд. Фарз мекунем, ки синфҳои шумо дар файли ./my-classes.ps1 муайян карда шудаанд

  • Шумо метавонед файлро бо синфҳои нуқта:. ./my-classes.ps1. Ин my-classes.ps1-ро дар доираи ҷории шумо иҷро мекунад ва ҳамаи синфҳоро аз файли он ҷо муайян мекунад.

  • Шумо метавонед як модули Powershell эҷод кунед, ки ҳамаи API-ҳои фармоишии шуморо (cmdlets) содир мекунад ва дар манифести модули худ тағирёбандаи ScriptsToProcess = "./my-classes.ps1" -ро насб кунед, бо ҳамон натиҷа: ./my-classes.ps1 дар иҷро мешавад муҳити шумо.

Кадом вариантеро, ки шумо интихоб мекунед, дар хотир доред, ки системаи навъи Powershell наметавонад намудҳои як номро, ки аз ҷойҳои гуногун бор карда шудаанд, ҳал кунад.
Ҳатто агар шумо ду синфи якхеларо бо хосиятҳои якхела аз ҷойҳои гуногун бор карда бошед ҳам, шумо хавфи дучори мушкилот мешавед.

Роҳи пеш

Роҳи беҳтарини пешгирӣ кардани мушкилоти ҳалли намуд ин аст, ки ҳеҷ гоҳ дарсҳои худро ба корбарон фош накунед. Ба ҷои он ки интизор шавед, ки корбар як навъи аз рӯи синф муайяншударо ворид кунад, функсияеро аз модули худ содир кунед, ки зарурати дастрасӣ ба синфро аз байн мебарад. Барои Кластер, мо метавонем функсияи New-Cluster-ро содир кунем, ки маҷмӯи параметрҳои барои корбарро дӯстона дастгирӣ мекунад ва кластерро бармегардонад.

class Cluster {
    [ValidatePattern("^[A-z]+$")]
    [string] $Service
    [ValidateSet("TEST", "STAGE", "CANARY", "PROD")]
    [string] $FlightingRing
    [ValidateSet("EastUS", "WestUS", "NorthEurope")]
    [string] $Region
    [ValidateRange(0, 255)]
    [int] $Index
}

function New-Cluster {
    [OutputType([Cluster])]
    Param(
        [Parameter(Mandatory, ParameterSetName = "Id", Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string] $Id,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [string] $Service,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [string] $FlightingRing,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [string] $Region,
        [Parameter(Mandatory, ParameterSetName = "Components")]
        [int] $Index
    )

    if ($Id) {
        $Service, $FlightingRing, $Region, $Index = $Id -split "-"
    }

    [Cluster]@{
        Service       = $Service
        FlightingRing = $FlightingRing
        Region        = $Region
        Index         = $Index
    }
}

Export-ModuleMember New-Cluster

Боз чӣ хондан

Дар бораи синфҳо
PowerShell мудофиавӣ
Барномасозии функсионалӣ дар PowerShell

Манбаъ: will.com

Илова Эзоҳ