Hei Habr! Esitän huomionne artikkelin käännöksen
Lupaan, että se ei ole oksymoroni"
Oliosuuntautunut ja toiminnallinen ohjelmointiparadigmat voivat tuntua ristiriidassa keskenään, mutta Powershell tukee molempia yhtä hyvin. Lähes kaikissa ohjelmointikielissä, toimivissa tai ei, on mahdollisuudet laajennettuun nimiarvosidontaan; Luokat, kuten rakenteet ja tietueet, ovat vain yksi lähestymistapa. Jos rajoitamme luokkien käytön nimien ja arvojen sitomiseen ja vältämme raskaita olio-ohjelmointikonsepteja, kuten periytymistä, polymorfismia tai muuntuvuutta, voimme hyödyntää niiden etuja mutkistamatta koodiamme. Lisäksi lisäämällä muuttumattomia tyyppimuunnosmenetelmiä voimme rikastaa toiminnallista koodiamme luokilla.
Kastien taikuutta
Kastit ovat yksi Powershellin tehokkaimmista ominaisuuksista. Kun annat arvon, luotat implisiittisiin alustus- ja vahvistusominaisuuksiin, joita ympäristö lisää sovellukseesi. Esimerkiksi merkkijonon lähettäminen [xml]:ssä ajaa sen jäsennyskoodin läpi ja luo täydellisen xml-puun. Voimme käyttää koodissamme luokkia samaan tarkoitukseen.
Cast hashtables
Jos sinulla ei ole rakentajaa, voit jatkaa ilman sitä lähettämällä hashtable luokkatyyppiisi. Älä unohda käyttää vahvistusattribuutteja saadaksesi täyden hyödyn tästä mallista. Samalla voimme käyttää luokan kirjoitettuja ominaisuuksia ajaaksemme entistä syvempää alustus- ja validointilogiikkaa.
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
}
Lisäksi valu auttaa saamaan puhtaan lopputuloksen. Vertaa Format-Tablelle välitetyn klusterin hashtable-taulukon tulosta siihen, mitä saat, jos lähetät nämä hashtablet ensin luokkaan. Luokan ominaisuudet luetellaan aina siinä järjestyksessä, jossa ne on määritelty. Älä unohda lisätä piilotettua avainsanaa ennen kaikkia niitä ominaisuuksia, joiden et halua näkyvän tuloksissa.
Valinta merkityksiä
Jos sinulla on konstruktori yhdellä argumentilla, arvon lähettäminen luokkatyyppiin välittää arvon konstruktorillesi, jossa voit alustaa luokkasi esiintymän
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 riviin
Voit myös ohittaa [string] ToString()-luokan menetelmän määrittääksesi logiikan objektin merkkijonoesityksen takana, kuten käyttämällä merkkijonointerpolaatiota.
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 sarjoitetut esiintymät
Cast mahdollistaa turvallisen deserialisoinnin. Alla olevat esimerkit epäonnistuvat, jos tiedot eivät täytä klusterin määrityksiämme
# Валидация сериализованных данных
[Cluster]$cluster = Get-Content "./my-cluster.json" | ConvertFrom-Json
[Cluster[]]$clusters = Import-Csv "./my-clusters.csv"
Castes toiminnallisessa koodissasi
Toiminnalliset ohjelmat määrittelevät ensin tietorakenteet ja toteuttavat sitten ohjelman muunnossarjana muuttumattomien tietorakenteiden yli. Ristiriitaisesta vaikutelmasta huolimatta luokat todella auttavat sinua kirjoittamaan toiminnallista koodia tyyppimuunnosmenetelmien ansiosta.
Onko kirjoittamani Powershell toimiva?
Monet C#:sta tai vastaavasta taustasta tulevat ihmiset kirjoittavat Powershelliä, joka on samanlainen kuin C#. Tekemällä tämän siirryt pois toiminnallisten ohjelmointikonseptien käytöstä ja todennäköisesti hyötyisit sukeltamasta voimakkaasti Powershell-olioohjelmointiin tai oppimaan lisää toiminnallisesta ohjelmoinnista.
Jos luotat voimakkaasti muuttumattomien tietojen muuntamiseen liukuputkien (|), Where-Object, ForEach-Object, Select-Object, Group-Object, Sort-Object jne. avulla - sinulla on toiminnallisempi tyyli ja hyödyt Powershellin käytöstä tunnit toiminnallisella tyylillä.
Luokkien toiminnallinen käyttö
Kastit, vaikka ne käyttävät vaihtoehtoista syntaksia, ovat vain kartoitus kahden toimialueen välillä. Valmistelussa voit kartoittaa joukon arvoja ForEach-Objectin avulla.
Alla olevassa esimerkissä solmukonstruktori suoritetaan joka kerta, kun Datum heitetään, ja tämä antaa meille mahdollisuuden olla kirjoittamatta kohtuullista määrää koodia. Tämän seurauksena putkistomme keskittyy deklaratiiviseen tietojen kyselyyn ja yhdistämiseen, kun taas luokat huolehtivat tietojen jäsentämisestä ja validoinnista.
# Пример комбинирования классов с конвейерами для 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
Pakkausluokka uudelleenkäyttöön
Mikään ei ole niin hyvä kuin miltä näyttää
Valitettavasti luokkia ei voi viedä moduuleittain samalla tavalla kuin funktioita tai muuttujia; mutta on joitain temppuja. Oletetaan, että luokat on määritetty tiedostossa ./my-classes.ps1
-
Voit luoda pistelähteen tiedoston luokilla:. ./my-classes.ps1. Tämä suorittaa my-classes.ps1:n nykyisessä laajuudessasi ja määrittää kaikki luokat siellä olevasta tiedostosta.
-
Voit luoda Powershell-moduulin, joka vie kaikki mukautetut sovellusliittymäsi (cmdletit) ja asettaa ScriptsToProcess = "./my-classes.ps1" -muuttujan moduulin luetteloon samalla tuloksella: ./my-classes.ps1 suoritetaan ympäristösi.
Valitsetpa minkä vaihtoehdon tahansa, muista, että Powershellin tyyppijärjestelmä ei pysty ratkaisemaan eri paikoista ladattuja samannimisen tyyppejä.
Vaikka ladasit kaksi identtistä luokkaa, joilla on samat ominaisuudet eri paikoista, voit joutua ongelmiin.
Tie eteenpäin
Paras tapa välttää tyypin resoluutioongelmia on olla koskaan paljastamatta luokkiasi käyttäjille. Sen sijaan, että odottaisit käyttäjän tuovan luokan määrittämän tyypin, vie moduulista funktio, joka eliminoi tarpeen käyttää luokkaa suoraan. Clusterille voimme viedä New-Cluster-funktion, joka tukee käyttäjäystävällisiä parametrijoukkoja ja palauttaa klusterin.
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
Mitä muuta luettavaa
Lähde: will.com