Tere Habr! Esitan teie tähelepanu artikli tõlkele
Ma luban, et see pole oksüümoron"
Objektorienteeritud ja funktsionaalse programmeerimise paradigmad võivad tunduda üksteisega vastuolus, kuid Powershellis toetatakse mõlemat võrdselt. Peaaegu kõik programmeerimiskeeled, olgu need funktsionaalsed või mitte, sisaldavad laiendatud nime-väärtuse sidumise võimalusi; Klassid, nagu struktuurid ja kirjed, on vaid üks lähenemisviis. Kui piirame klasside kasutamist nimede ja väärtuste sidumisega ning väldime raskeid objektorienteeritud programmeerimiskontseptsioone, nagu pärimine, polümorfism või muutuvus, saame neid ära kasutada ilma oma koodi keerulisemaks muutmata. Lisaks saame muutumatute tüüpide teisendusmeetodite lisamisega oma funktsionaalset koodi klassidega rikastada.
Kastide maagia
Kastid on Powershelli üks võimsamaid funktsioone. Väärtuse ülekandmisel tuginete kaudsetele lähtestamis- ja valideerimisvõimalustele, mille keskkond teie rakendusele lisab. Näiteks lihtsalt stringi ülekandmine [xml]-s käivitab selle parserikoodi ja loob täieliku xml-puu. Samal eesmärgil saame oma koodis kasutada klasse.
Cast hashtables
Kui teil pole konstruktorit, saate jätkata ilma selleta, kandes oma klassitüübile räsitabeli. Ärge unustage kasutada valideerimisatribuute, et seda mustrit täielikult ära kasutada. Samal ajal saame kasutada klassi tipitud atribuute veelgi sügavama initsialiseerimis- ja valideerimisloogika käivitamiseks.
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
}
Lisaks aitab casting saada puhast väljundit. Võrrelge Format-Table'ile edastatud klastri räsitabeli massiivi väljundit sellega, mida saate nende räsitabelite esmakordsel klassi kandmisel. Klassi omadused on alati loetletud selles järjekorras, milles need seal määratletakse. Ärge unustage lisada peidetud märksõna enne kõiki neid omadusi, mida te ei soovi tulemustes näha.
Tähenduste loomine
Kui teil on ühe argumendiga konstruktor, edastab klassitüübile väärtuse ülekandmine selle teie konstruktorile, kus saate oma klassi eksemplari initsialiseerida
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"
Valage joonele
Samuti saate alistada klassi meetodi [string] ToString(), et määratleda objekti stringi esituse taga olevat loogikat, näiteks kasutada stringide interpolatsiooni.
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'"
Serialiseeritud eksemplaride ülekandmine
Cast võimaldab ohutut deserialiseerimist. Allpool toodud näited ebaõnnestuvad, kui andmed ei vasta meie klastri spetsifikatsioonidele
# Валидация сериализованных данных
[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"
Kastib teie funktsionaalsesse koodi
Funktsionaalsed programmid määratlevad esmalt andmestruktuurid, seejärel rakendavad programmi muutumatute andmestruktuuride teisenduste jadana. Vaatamata vastuolulisele muljele aitavad klassid tõesti tänu tüübiteisendusmeetoditele funktsionaalset koodi kirjutada.
Kas Powershell, mida ma kirjutan, töötab?
Paljud C# või sarnase taustaga inimesed kirjutavad Powershelli, mis sarnaneb C#-ga. Seda tehes loobute funktsionaalsete programmeerimiskontseptsioonide kasutamisest ja tõenäoliselt oleks kasulik sukelduda Powershelli objektorienteeritud programmeerimisse või õppida funktsionaalse programmeerimise kohta lisateavet.
Kui tuginete suurel määral muutumatute andmete teisendamisele torujuhtmete (|), Kus-Objekt, ForEach-Object, Select-Object, Group-Object, Sort-Object jne abil, on teil funktsionaalsem stiil ja teile on kasulik Powershelli kasutamine. klassid funktsionaalses stiilis.
Klasside funktsionaalne kasutamine
Kastid, kuigi nad kasutavad alternatiivset süntaksit, on vaid kahe domeeni vaheline vastendus. Konveieril saate ForEach-Object abil kaardistada väärtuste massiivi.
Allolevas näites käivitatakse sõlmekonstruktor iga kord, kui nullpunkti heidetakse, ja see annab meile võimaluse mitte kirjutada päris palju koodi. Selle tulemusena keskendub meie konveieri deklaratiivsetele andmete päringutele ja koondamisele, samas kui meie klassid hoolitsevad andmete sõelumise ja valideerimise eest.
# Пример комбинирования классов с конвейерами для 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
Taaskasutamiseks mõeldud pakendiklass
Miski pole nii hea, kui tundub
Kahjuks ei saa klasse moodulite kaupa eksportida samamoodi nagu funktsioone või muutujaid; aga seal on mõned nipid. Oletame, et teie klassid on määratletud failis ./my-classes.ps1
-
Saate anda allikaks faili klassidega:. ./my-classes.ps1. See käivitab faili my-classes.ps1 teie praeguses ulatuses ja määratleb seal olevast failist kõik klassid.
-
Saate luua Powershelli mooduli, mis ekspordib kõik teie kohandatud API-d (cmdletid) ja määrata mooduli manifestis muutuja ScriptsToProcess = "./my-classes.ps1", sama tulemusega: ./my-classes.ps1 käivitatakse teie keskkond.
Ükskõik millise valiku valite, pidage meeles, et Powershelli tüübisüsteem ei suuda lahendada erinevatest kohtadest laaditud sama nimega tüüpe.
Isegi kui laadisite erinevatest kohtadest kaks identset klassi, millel on samad omadused, võib teil tekkida probleeme.
Edasine tee
Parim viis tüübilahutusprobleemide vältimiseks on mitte kunagi avaldada oma klasse kasutajatele. Selle asemel, et eeldada, et kasutaja impordiks klassi määratud tüübi, eksportige oma moodulist funktsioon, mis välistab vajaduse klassile otse juurde pääseda. Clusteri jaoks saame eksportida funktsiooni New-Cluster, mis toetab kasutajasõbralikke parameetrikomplekte ja tagastab klastri.
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
Mida muud lugeda
Allikas: www.habr.com