Äau Habr! PiedÄvÄju jÅ«su uzmanÄ«bai raksta tulkojumu autors Kristofers KÅ«Äs.
ObjektorientÄtas un funkcionÄlas programmÄÅ”anas paradigmas var Ŕķist pretrunÄ«gas viena otrai, taÄu PowerShell vienlÄ«dzÄ«gi atbalsta abas. GandrÄ«z visas programmÄÅ”anas valodas, funkcionÄlas vai nÄ, piedÄvÄ plaÅ”u nosaukuma-vÄrtÄ«bas saistīŔanu; klases, piemÄram, struktÅ«ras un ieraksti, ir tikai viena pieeja. Ierobežojot klaÅ”u izmantoÅ”anu ar nosaukuma-vÄrtÄ«bas saistīŔanu un izvairoties no sarežģītiem objektorientÄtas programmÄÅ”anas jÄdzieniem, piemÄram, mantoÅ”anas, polimorfisma vai mainÄmÄ«bas, mÄs varam izmantot to priekÅ”rocÄ«bas, nesarežģījot savu kodu. TurklÄt, pievienojot nemainÄ«gas tipu konvertÄÅ”anas metodes, mÄs varam bagÄtinÄt savu funkcionÄlo kodu ar klasÄm.
Kastu maģija
TransformÄcijas ir viena no jaudÄ«gÄkajÄm PowerShell funkcijÄm. Kad jÅ«s transformÄjat vÄrtÄ«bu, jÅ«s paļaujaties uz netieÅ”ajÄm inicializÄcijas un validÄcijas iespÄjÄm, ko vide pievieno jÅ«su lietojumprogrammai. PiemÄram, vienkÄrÅ”i transfÄrÄjot virkni uz [xml], tÄ tiks palaista caur parsÄtÄja kodu un Ä£enerÄts pilns XML koks. MÄs varam izmantot klases savÄ kodÄ tam paÅ”am mÄrÄ·im.
Apraides heŔtabulas
Ja jums nav konstruktora, varat turpinÄt bez tÄ, pÄrveidojot heÅ”tabulu par savas klases tipu. Neaizmirstiet izmantot validÄcijas atribÅ«tus, lai pilnÄ«bÄ izmantotu Å”o modeli. Varam arÄ« izmantot tipizÄtas klases Ä«paŔības, lai ieviestu vÄl dziļÄku inicializÄcijas un validÄcijas loÄ£iku.
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
}TurklÄt pÄrveidoÅ”ana palÄ«dz iegÅ«t tÄ«rÄku izvadi. SalÄ«dziniet Cluster masÄ«va heÅ”tabulu izvadi, kas nodota Format-Table, ar to, ko iegÅ«stat, ja vispirms pÄrveidojat Ŕīs heÅ”tabulas klasÄ. Klases Ä«paŔības vienmÄr ir uzskaitÄ«tas tÄdÄ secÄ«bÄ, kÄdÄ tÄs ir definÄtas. Neaizmirstiet pievienot atslÄgvÄrdu "hidden" pirms jebkuras Ä«paŔības, kuru nevÄlaties redzÄt izvadÄ.

VÄrtÄ«bu kasta
Ja jums ir konstruktors ar vienu argumentu, vÄrtÄ«bas pieŔķirÅ”ana klases tipam nodos vÄrtÄ«bu jÅ«su konstruktoram, kurÄ varat inicializÄt savas klases instanci.
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"Izliet līdz līnijai
Varat arÄ« ignorÄt [string] klases ToString() metodi, lai definÄtu objekta attÄloÅ”anas loÄ£iku virknÄ, piemÄram, izmantojot virkÅu interpolÄciju.
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'"SerializÄtu instanÄu lieÅ”ana
ApstrÄdes metode ļauj droÅ”i veikt deserializÄciju. TÄlÄk sniegtie piemÄri neizdosies, ja dati neatbilst mÅ«su klastera specifikÄcijai.
# ŠŠ°Š»ŠøŠ“Š°ŃŠøŃ ŃŠµŃиализованнŃŃ
ГаннŃŃ
[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"JÅ«su funkcionÄlÄ koda pÄrveidoÅ”ana
FunkcionÄlÄs programmas vispirms definÄ datu struktÅ«ras un pÄc tam ievieÅ” programmu kÄ transformÄciju secÄ«bu nemainÄ«gÄs datu struktÅ«rÄs. Neskatoties uz neloÄ£iski Ŕķietamo iespaidu, klases faktiski palÄ«dz rakstÄ«t funkcionÄlu kodu, pateicoties to tipu konvertÄÅ”anas metodÄm.
Vai es rakstu funkcionÄlu Powershell?
Daudzi cilvÄki ar C# vai lÄ«dzÄ«gu pieredzi raksta PowerShell, kas ir lÄ«dzÄ«gs C#. TÄ rÄ«kojoties, jÅ«s atsakÄties no funkcionÄlÄs programmÄÅ”anas koncepcijÄm un, visticamÄk, gÅ«tu labumu no dziļÄkas iedziļinÄÅ”anÄs objektorientÄtÄ programmÄÅ”anÄ PowerShell vai vairÄku zinÄÅ”anu apgūŔanas par funkcionÄlo programmÄÅ”anu.
Ja jÅ«s lielÄ mÄrÄ paļaujaties uz nemainÄmu datu pÄrveidoÅ”anu, izmantojot vertikÄlÄs lÄ«nijas (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object utt., jums ir funkcionÄlÄks stils, un jÅ«s iegÅ«siet no funkcionÄlÄ stila Powershell klaÅ”u izmantoÅ”anas.
Klases funkcionÄlÄ izmantoÅ”ana
Lai gan pÄrsÅ«tÄ«jumi izmanto alternatÄ«vu sintaksi, tie ir vienkÄrÅ”i kartÄjums starp diviem domÄniem. CauruļvadÄ var kartÄt vÄrtÄ«bu masÄ«vu, izmantojot ForEach-Object.
ZemÄk redzamajÄ piemÄrÄ Node konstruktors tiek izpildÄ«ts katru reizi, kad tiek pÄrveidots Datum, tÄdÄjÄdi samazinot ievÄrojamu koda apjomu. TÄ rezultÄtÄ mÅ«su cauruļvads koncentrÄjas uz deklaratÄ«vu datu vaicÄÅ”anu un apkopoÅ”anu, savukÄrt mÅ«su klases apstrÄdÄ datu parsÄÅ”anu un validÄciju.
# ŠŃŠøŠ¼ŠµŃ ŠŗŠ¾Š¼Š±ŠøŠ½ŠøŃŠ¾Š²Š°Š½ŠøŃ клаŃŃŠ¾Š² Ń ŠŗŠ¾Š½Š²ŠµŠ¹ŠµŃŠ°Š¼Šø Š“Š»Ń 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 -UniquePÄrstrÄdÄjams iepakojums
Nekas nav tik labs, kÄ Å”Ä·iet
DiemžÄl klases nevar eksportÄt moduļos tÄpat kÄ funkcijas vai mainÄ«gos, taÄu ir daži triki. PieÅemsim, ka jÅ«su klases ir definÄtas failÄ ./my-classes.ps1.
Varat dotsource tipa klases failu: ./my-classes.ps1. Tas izpildÄ«s my-classes.ps1 jÅ«su paÅ”reizÄjÄ darbÄ«bas jomÄ un definÄs visas klases no Ŕī faila.
Varat izveidot Powershell moduli, kas eksportÄ visus jÅ«su pielÄgotos API (cmdlet), un moduļa manifestÄ iestatÄ«t mainÄ«go ScriptsToProcess = "./my-classes.ps1", iegÅ«stot tÄdu paÅ”u rezultÄtu: jÅ«su vidÄ tiks izpildÄ«ts ./my-classes.ps1.
NeatkarÄ«gi no izvÄlÄtÄs opcijas atcerieties, ka PowerShell tipu sistÄma nevar atŔķirt tipus ar vienÄdu nosaukumu, kas ielÄdÄti no dažÄdÄm vietÄm.
Pat ja ielÄdÄjat divas identiskas klases ar vienÄdÄm Ä«paŔībÄm no dažÄdÄm vietÄm, jÅ«s riskÄjat saskarties ar problÄmÄm.
CeļŔ uz priekŔu
LabÄkais veids, kÄ izvairÄ«ties no tipu atpazīŔanas problÄmÄm, ir nekad neizpaust savas klases lietotÄjiem. TÄ vietÄ, lai gaidÄ«tu, ka lietotÄji importÄs klasÄ definÄtu tipu, eksportÄjiet funkciju no sava moduļa, kas novÄrÅ” nepiecieÅ”amÄ«bu tieÅ”i piekļūt klasei. Klastera gadÄ«jumÄ mÄs varam eksportÄt New-Cluster funkciju, kas atbalsta lietotÄjam draudzÄ«gas parametru kopas un atgriež klastera vÄrtÄ«bu.
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-ClusterKo vÄl lasÄ«t
Avots: www.habr.com
