Nid yw Powershell Swyddogaethol gyda dosbarthiadau yn ocsimoron, rwy'n ei warantu

Hei Habr! Cyflwynaf i'ch sylw gyfieithiad yr erthygl β€œShell PowerShell Swyddogaethol gyda Dosbarthiadau.
Rwy'n addo nad yw'n ocsimoron"
gan Christopher Kuech.

Gall patrymau rhaglennu gwrthrychol a swyddogaethol ymddangos yn groes i'w gilydd, ond mae'r ddau yn cael eu cefnogi'n gyfartal yn Powershell. Mae gan bron bob iaith raglennu, boed yn weithredol neu beidio, gyfleusterau ar gyfer rhwymo gwerth-enw estynedig; Dim ond un dull yw dosbarthiadau, fel strwythurau a chofnodion. Os byddwn yn cyfyngu ein defnydd o Ddosbarthiadau i rwymo enwau a gwerthoedd, ac yn osgoi cysyniadau rhaglennu trwm sy'n canolbwyntio ar wrthrych fel etifeddiaeth, amryffurfedd, neu mutability, gallwn fanteisio ar eu buddion heb gymhlethu ein cod. Ymhellach, trwy ychwanegu dulliau trosi math na ellir eu cyfnewid, gallwn gyfoethogi ein cod swyddogaethol gyda Dosbarthiadau.

Hud y castiau

Castes yw un o nodweddion mwyaf pwerus Powershell. Pan fyddwch chi'n bwrw gwerth, rydych chi'n dibynnu ar y galluoedd cychwyn a dilysu ymhlyg y mae'r amgylchedd yn eu hychwanegu at eich cais. Er enghraifft, bydd castio llinyn yn [xml] yn ei redeg trwy'r cod parser ac yn cynhyrchu coeden xml gyflawn. Gallwn ddefnyddio Dosbarthiadau yn ein cod at yr un diben.

Castiwch hashnodau

Os nad oes gennych chi adeiladwr, gallwch chi barhau heb un trwy gastio hashtable i'ch math o ddosbarth. Peidiwch ag anghofio defnyddio'r priodoleddau dilysu i fanteisio'n llawn ar y patrwm hwn. Ar yr un pryd, gallwn ddefnyddio priodweddau teipiedig y dosbarth i redeg rhesymeg cychwyn a dilysu dyfnach fyth.

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
}

Yn ogystal, mae castio yn helpu i gael allbwn glΓ’n. Cymharwch allbwn yr arae bwrdd stwnsh Clwstwr a drosglwyddwyd i Format-Table gyda'r hyn a gewch os byddwch yn bwrw'r stwnfwrdd hwn i mewn i ddosbarth am y tro cyntaf. Mae priodweddau dosbarth bob amser yn cael eu rhestru yn y drefn y cΓ’nt eu diffinio yno. Peidiwch ag anghofio ychwanegu'r allweddair cudd cyn yr holl eiddo hynny nad ydych chi am fod yn weladwy yn y canlyniadau.

Nid yw Powershell Swyddogaethol gyda dosbarthiadau yn ocsimoron, rwy'n ei warantu

Cast o ystyron

Os oes gennych chi adeiladwr gydag un ddadl, bydd bwrw gwerth i'ch math o ddosbarth yn trosglwyddo'r gwerth i'ch lluniwr, lle gallwch chi gychwyn enghraifft o'ch dosbarth

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"

Cast i linell

Gallwch hefyd ddiystyru'r dull dosbarth [llinyn] ToString() i ddiffinio'r rhesymeg y tu Γ΄l i gynrychioliad llinyn y gwrthrych, megis defnyddio rhyngosodiad llinynnol.

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'"

Enghreifftiau cyfresol o'r cast

Mae cast yn caniatΓ‘u dad-gyfeiriannu'n ddiogel. Bydd yr enghreifftiau isod yn methu os nad yw'r data'n bodloni ein manyleb yn y Clwstwr

# Валидация сСриализованных Π΄Π°Π½Π½Ρ‹Ρ…

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

Castes yn eich cod swyddogaethol

Mae rhaglenni swyddogaethol yn diffinio strwythurau data yn gyntaf, yna'n gweithredu'r rhaglen fel dilyniant o drawsnewidiadau dros strwythurau data na ellir eu cyfnewid. Er gwaethaf yr argraff groes, mae dosbarthiadau wir yn eich helpu i ysgrifennu cod swyddogaethol diolch i ddulliau trosi math.

A yw'r Powershell rwy'n ei ysgrifennu yn ymarferol?

Mae llawer o bobl sy'n dod o C# neu gefndiroedd tebyg yn ysgrifennu Powershell, sy'n debyg i C#. Trwy wneud hyn, rydych chi'n symud i ffwrdd o ddefnyddio cysyniadau rhaglennu swyddogaethol ac mae'n debygol y byddech chi'n elwa o blymio'n drwm i raglennu gwrthrych-ganolog yn Powershell neu ddysgu mwy am raglennu swyddogaethol.

Os ydych chi'n dibynnu'n fawr ar drawsnewid data digyfnewid gan ddefnyddio piblinellau (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object, ac ati - mae gennych chi arddull fwy ymarferol a byddwch chi'n elwa o ddefnyddio Powershell dosbarthiadau mewn arddull swyddogaethol.

Defnydd swyddogaethol o ddosbarthiadau

Mae castes, er eu bod yn defnyddio cystrawen amgen, yn fapio rhwng dau barth yn unig. Ar y gweill, gallwch fapio amrywiaeth o werthoedd gan ddefnyddio ForEach-Object.

Yn yr enghraifft isod, mae'r adeiladwr Node yn cael ei weithredu bob tro y caiff Datwm ei gastio, ac mae hyn yn rhoi'r cyfle i ni beidio ag ysgrifennu cryn dipyn o god. O ganlyniad, mae ein piblinell yn canolbwyntio ar ymholi a chyfuno data datganiadol, tra bod ein dosbarthiadau yn gofalu am ddosrannu a dilysu data.

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ комбинирования классов с ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°ΠΌΠΈ для 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

Dosbarth pecynnu i'w ailddefnyddio

Nid oes dim cystal ag y mae'n ymddangos

Yn anffodus, ni ellir allforio dosbarthiadau gan fodiwlau yn yr un modd Γ’ ffwythiannau neu newidynnau; ond mae rhai triciau. Dywedwch fod eich dosbarthiadau wedi'u diffinio yn y ffeil ./my-classes.ps1

  • Gallwch dotsource ffeil gyda dosbarthiadau:. ./fy-dosbarthiadau.ps1. Bydd hyn yn gweithredu my-classes.ps1 yn eich cwmpas presennol ac yn diffinio'r holl ddosbarthiadau o'r ffeil yno.

  • Gallwch greu modiwl Powershell sy'n allforio eich holl APIs arferol (cmdlets) a gosod y newidyn ScriptsToProcess = "./my-classes.ps1" ym maniffest eich modiwl, gyda'r un canlyniad: ./my-classes.ps1 fydd yn gweithredu yn eich amgylchedd.

Pa bynnag opsiwn a ddewiswch, cofiwch na all system fath Powershell ddatrys mathau o'r un enw wedi'u llwytho o wahanol leoedd.
Hyd yn oed os gwnaethoch chi lwytho dau ddosbarth union yr un fath Γ’'r un priodweddau o wahanol leoedd, rydych mewn perygl o fynd i broblemau.

Y ffordd ymlaen

Y ffordd orau o osgoi problemau datrys math yw peidio byth Γ’ datgelu'ch dosbarthiadau i ddefnyddwyr. Yn hytrach na disgwyl i'r defnyddiwr fewnforio math a ddiffinnir gan y dosbarth, allforio swyddogaeth o'ch modiwl sy'n dileu'r angen i gael mynediad uniongyrchol i'r dosbarth. Ar gyfer Clwstwr, gallwn allforio swyddogaeth Clwstwr Newydd a fydd yn cefnogi setiau paramedr hawdd eu defnyddio ac yn dychwelyd Clwstwr.

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

Beth arall i'w ddarllen

Am Ddosbarthiadau
PowerShell Amddiffynnol
Rhaglennu Swyddogaethol yn PowerShell

Ffynhonnell: hab.com

Ychwanegu sylw