(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': data().getTime(),įvykis:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5LHNRP9'); Polimorfizmas "Ruby" ir GraphQL kalbose - The Codest
The Codest
  • Apie mus
  • Paslaugos
    • Programinės įrangos kūrimas
      • Priekinės dalies kūrimas
      • Galinės dalies kūrimas
    • Staff Augmentation
      • Priekinės dalies kūrėjai
      • Atgalinės versijos kūrėjai
      • Duomenų inžinieriai
      • Debesų inžinieriai
      • QA inžinieriai
      • Kita
    • Patariamoji tarnyba
      • Auditas ir konsultacijos
  • Pramonės šakos
    • Fintech ir bankininkystė
    • E-commerce
    • Adtech
    • Sveikatos technologijos
    • Gamyba
    • Logistika
    • Automobiliai
    • IOT
  • Vertė už
    • CEO
    • CTO
    • Pristatymo vadybininkas
  • Mūsų komanda
  • Case Studies
  • Sužinokite, kaip
    • Tinklaraštis
    • Susitikimai
    • Interneto seminarai
    • Ištekliai
Karjera Susisiekite su mumis
  • Apie mus
  • Paslaugos
    • Programinės įrangos kūrimas
      • Priekinės dalies kūrimas
      • Galinės dalies kūrimas
    • Staff Augmentation
      • Priekinės dalies kūrėjai
      • Atgalinės versijos kūrėjai
      • Duomenų inžinieriai
      • Debesų inžinieriai
      • QA inžinieriai
      • Kita
    • Patariamoji tarnyba
      • Auditas ir konsultacijos
  • Vertė už
    • CEO
    • CTO
    • Pristatymo vadybininkas
  • Mūsų komanda
  • Case Studies
  • Sužinokite, kaip
    • Tinklaraštis
    • Susitikimai
    • Interneto seminarai
    • Ištekliai
Karjera Susisiekite su mumis
Atgal rodyklė GRĮŽTI ATGAL
2022-01-13
Programinės įrangos kūrimas

Polimorfizmas "Ruby" ir "GraphQL" kalbose

Lukasz Brzeszcz

Šiame straipsnyje pristatysiu polimorfizmo naudojimą GraphQL. Tačiau prieš pradedant verta priminti, kas yra polimorfizmas ir GraphQL.

Polimorfizmas

Polimorfizmas yra pagrindinė sudedamoji į objektus orientuotas programavimas. Kad būtų paprasčiau, ji grindžiama tuo, kad skirtingų klasių objektai turi prieigą prie tos pačios sąsajos, o tai reiškia, kad iš kiekvieno iš jų galime tikėtis tos pačios funkcijos, tačiau nebūtinai įgyvendintos tuo pačiu būdu. Svetainėje Ruby kūrėjai gali gauti polimorfizmas trimis būdais:

Paveldėjimas

Paveldėjimas sukuriama tėvinė klasė ir antrinės klasės (t. y. paveldimos iš tėvinės klasės). Pakartotinės klasės perima tėvinės klasės funkcionalumą, taip pat leidžia keisti ir papildyti funkcionalumą.

Pavyzdys:

klasė Document
  attr_reader :name
pabaiga

klasė PDFDocument < Dokumentas
  def plėtinys
    :pdf
  end
end

klasė ODTDocument < Dokumentas
  def plėtinys
    :odt
  end
end

Moduliai

Moduliai Ruby turi daugybę panaudojimo būdų. Vienas iš jų - mišiniai (daugiau apie mišinius skaitykite Galutinis suskirstymas: Python vs. Python). Ruby mišinius galima naudoti panašiai kaip sąsajas kitose programose. programavimo kalbos (pvz. Java), pavyzdžiui, juose galite apibrėžti metodus, bendrus objektams, kuriuose bus tam tikras mišinys. Gera praktika yra į modulius įtraukti tik skaitymo metodus, t. y. metodus, kurie nekeis šio objekto būsenos.

Pavyzdys:

modulis Apmokestinamasis
  def tax

     kaina * 0,23
  pabaiga
end

klasė Automobilis
  include Taxable
 attr_reader :price
end

klasė Book
  include Taxable

 attr_reader :price
end

Ančių spausdinimas

Tai viena iš pagrindinių dinamiškai tipizuotų kalbų savybių. Pavadinimas kilo iš garsaus testo, jei atrodo kaip antis, plaukia kaip antis ir klykia kaip antis, vadinasi, tikriausiai yra antis. Adresas programuotojas nereikia domėtis, kuriai klasei priklauso duotas objektas. Svarbu, kokius metodus galima iškviesti šiam objektui.

Naudodami pirmiau pateiktame pavyzdyje apibrėžtas klases:

klasė Automobilis
  attr_reader :price

 def initialize(price)
    @price = price
   end
end

klasė Book
  attr_reader :price

 def initialize(price)
    @price = price
  end
end

car = Car.new(20.0)
book = Book.new(10.0)

[car, book].map(&:price

GrapQL

GraphQL yra palyginti nauja API užklausų kalba. Jos privalumai - labai paprasta sintaksė, be to, klientas pats sprendžia, ką tiksliai nori gauti, nes kiekvienas klientas gauna būtent tai, ko nori, ir nieko daugiau.

Pavyzdinė užklausa GraphQL:

{
  allUsers {
     users {
        id
        login
        el. paštas

       }
     }
   }

Atsakymo pavyzdys:

{
  "allUsers": {
    "users": [
     {
        "id": 1,
        "login": "user1",
        "el. paštas": "[email protected]"
      },
      {
        "id": 2,
        "login": "user2",
        "el. paštas": "[email protected]".
      },
    ]
  }
}

Šiuo metu tai tikriausiai viskas, ką mums reikia žinoti. Taigi pereikime prie esmės.

Problemos pristatymas

Kad geriau suprastume problemą ir jos sprendimą, sukurkime pavyzdį. Būtų gerai, kad pavyzdys būtų originalus ir gana žemiškas. Toks, kad kiekvienas iš mus kada nors gali susidurti. Kaip dėl... gyvūnų? Taip! Puiki idėja!

Ruby ir grapql polimorfizmas - gyvūnai

Tarkime, kad turime galinę programą, parašytą Ruby on Rails. Ji jau pritaikyta pirmiau nurodytai schemai tvarkyti. Taip pat darykime prielaidą, kad jau turime GraphQL sukonfigūruotas. Norime, kad klientas galėtų pateikti užklausą pagal tokią struktūrą:

{
 allZoos : {
    zoologijos sodas: {
      pavadinimas
      miestas
      gyvūnai: {
        ...
      }
    }
  }
}

Ką reikėtų įrašyti vietoj trijų taškų, kad gautume trūkstamą informaciją - sužinosime vėliau.

Įgyvendinimas

Toliau pateiksiu žingsnius, kurių reikia šiam tikslui pasiekti.

Užklausos pridėjimas prie QueryType

Pirmiausia reikia apibrėžti, ką tiksliai reiškia užklausa allZoos. Norėdami tai padaryti, turime apsilankyti faileapp/graphql/types/query_type.rb ir apibrėžkite užklausą:

   modulių tipai
      klasė QueryType < Types::BaseObject
       field :all_zoos, [Types::ZooType], null: false

       def all_zoos
          Zoo.all
       end
    end
 end

Užklausa jau apibrėžta. Dabar laikas apibrėžti grąžinimo tipus.

Tipų apibrėžimas

Pirmasis reikalaujamas tipas bus ZooType. Apibrėžkime jį faile app/graphql/types/ zoo_type.rb:

modulių tipai
  klasė ZooType < Types::BaseObject
    field :name, String, null: false
    laukas :city, String, null: false
    laukas :animals, [Types::AnimalType], null: false
  end
end

Dabar laikas apibrėžti tipą AnimalType:

modulių tipai
  klasė AnimalType < Types::BaseUnion
   possible_types ElephantType, CatType, DogType

     def self.resolve_type(obj, ctx)
       if obj.is_a?(Elephant)
          ElephantType
       elsif obj.is_a?(Cat)
         CatType
       elsif obj.is_a?(Dog)
        DogType
      end
    end
  end
end

Ką mes matome kodas aukščiau?

  1. AnimalType paveldi iš Tipai::BaseUnion.
  2. Turime išvardyti visus tipus, kurie gali sudaryti tam tikrą sąjungą.
    3.Mes pakeičiame funkciją self.resolve_object(obj, ctx),kuris turi grąžinti duoto objekto tipą.

Kitas žingsnis - apibrėžti gyvūnų tipus. Tačiau žinome, kad kai kurie laukai yra bendri visiems gyvūnams. Įtraukime juos į tipą AnimalInterface:

modulių tipai
  modulis AnimalInterface
    include Types::BaseInterface

    field :name, String, null: false
    field :age, Integer, null: false
  end
end

Turėdami šią sąsają, galime apibrėžti konkrečių gyvūnų tipus:

modulių tipai
  klasė ElephantType < Types::BaseObject
    įgyvendina Types::AnimalInterface

    field :trunk_length, Float, null: false
  end
end

modulis Types
  klasė CatType < Types::BaseObject
   įgyvendina Types::AnimalInterface

   field :hair_type, String, null: false
  end
end

modulis Tipai
  klasė DogType < Types::BaseObject
    įgyvendina Types::AnimalInterface

     field :breed, String, null: false
  end
end

Štai ir viskas! Paruošta! Paskutinis klausimas: kaip galime panaudoti tai, ką padarėme iš kliento pusės?

Užklausos kūrimas

{
 allZoos : {
   zoologijos sodas: {
      pavadinimas
      miestas
      gyvūnai: {
        __typename

        ... on ElephantType {
          pavadinimas
          amžius
          kamieno ilgis
        }

         ... on CatType {
          vardas
          amžius
          hairType
         }
         ... on DogType {
          vardas
          amžius
          veislė
         }
       }
     }
   }
 }

Čia galime naudoti papildomą lauką __typename, kuris grąžins tikslų duoto elemento tipą (pvz., CatType). Kaip atrodys pavyzdinis atsakymas?

{
  "allZoos": [

   {
      "name": "Natura Artis Magistra",
      "city": "Amsterdam",
      "gyvūnai": [
        {
          "__typename": "ElephantType"
          "name": "Franco",
          "amžius": 28,
          "liemens ilgis": 9.27
         },
         {
         "__typename": "DogType"
         "name": "Jack",
         "amžius": 9,
         "veislė": "Džeko Raselo terjeras".
        },
      ]
    }
  ]
} 

Analizė

Akivaizdus vienas šio metodo trūkumas. Užklausoje turime įvesti kiekvieno tipo pavadinimą ir amžių, nors žinome, kad visi gyvūnai turi šiuos laukus. Tai netrukdo, kai kolekcijoje yra visiškai skirtingų objektų. Tačiau šiuo atveju gyvūnai turi beveik visus bendrus laukus. Ar tai galima kaip nors patobulinti?

Žinoma! Atliekame pirmąjį failo pakeitimą app/graphql/types/zoo_type.rb:

modulių tipai
  klasė ZooType < Types::BaseObject
    field :name, String, null: false
    laukas :city, String, null: false
    laukas :animals, [Types::AnimalInterface], null: false
  end
end

Mums nebereikia sąjungos, kurią apibrėžėme anksčiau. Keičiame Tipai::AnimalType į Tipai::AnimalInterface.

Kitas žingsnis - pridėti funkciją, kuri grąžina tipą iš Tipai :: AnimalInterface taip pat pridėkite "orphan_types" sąrašą, t. y. tipų, kurie niekada nėra tiesiogiai naudojami:

modulių tipai
  modulis AnimalInterface
    include Types::BaseInterface

   field :name, String, null: false
   field :age, Integer, null: false

   definition_methods do
      def resolve_type(obj, ctx)
        if obj.is_a?(Elephant)
          ElephantType
        elsif obj.is_a?(Cat)
          CatType
        elsif obj.is_a?(Dog)
          DogType
        end
      end
    end
    orphan_types Types::ElephantType, Types::CatType, Types::DogType
  end
end

Dėl šios paprastos procedūros užklausos forma nėra tokia sudėtinga:

{
  allZoos : {
   zoologijos sodas: {
      pavadinimas
      miestas
      gyvūnai: {
        __typename
        vardas
        amžius

       ... on ElephantType {
          kamieno ilgis

       }
       ... on CatType {
          hairType

       }
       ... on DogType {
          veislė

        }
      }
    }
  }
}

Santrauka

GraphQL yra tikrai puikus sprendimas. Jei dar nežinote, išbandykite jį. Patikėkite manimi, verta. Jis puikiai sprendžia problemas, kylančias, pavyzdžiui, REST API. Kaip parodžiau pirmiau, polimorfizmas nėra tikra kliūtis. Pateikiau du būdus, kaip ją įveikti.
Primename:

  • Jei dirbate su objektų, turinčių bendrą pagrindą arba bendrą sąsają, sąrašu, naudokite sąsajas,
  • Jei dirbate su kitokios struktūros objektų sąrašu, naudokite kitą sąsają - naudokite sąjungą

Skaityti daugiau

"GraphQL Ruby". O kaip dėl našumo?

Bėgiai ir kitos transporto priemonės

"Rails" kūrimas naudojant TMUX, "Vim", Fzf + Ripgrep

Susiję straipsniai

Išmaniojo telefono sveikatos priežiūros programėlės su širdies piktograma ir kylančia sveikatos diagrama, pažymėtos The Codest logotipu, iliustracija, vaizduojanti skaitmeninės sveikatos ir sveikatos technologijų sprendimus.
Programinės įrangos kūrimas

Sveikatos priežiūros programinė įranga: Sveikatos priežiūros paslaugos: tipai, naudojimo atvejai

Įrankiai, kuriais šiandien naudojasi sveikatos priežiūros organizacijos, nė iš tolo neprimena prieš kelis dešimtmečius naudotų popierinių kortelių. sveikatos priežiūros programinė įranga dabar padeda sveikatos sistemoms, pacientų priežiūrai ir šiuolaikiniam sveikatos priežiūros paslaugų teikimui klinikinėse ir...

GERIAUSIAS
Abstrakti mažėjančios stulpelinės diagramos su kylančia rodykle ir auksine moneta, simbolizuojančia ekonomiškumą arba taupymą, iliustracija. Viršutiniame kairiajame viršutiniame kampe pavaizduotas The Codest logotipas ir šūkis "In Code We Trust" šviesiai pilkame fone.
Programinės įrangos kūrimas

Kaip padidinti savo Dev komandą neprarandant produkto kokybės

Didinate savo kūrėjų komandą? Sužinokite, kaip augti neprarandant produkto kokybės. Šiame vadove aptariami ženklai, kad atėjo laikas didinti komandą, komandos struktūra, įdarbinimas, vadovavimas ir įrankiai - ir kaip The Codest gali...

GERIAUSIAS
Programinės įrangos kūrimas

Sukurkite ateičiai atsparias žiniatinklio programas: The Codest ekspertų komandos įžvalgos

Sužinokite, kaip The Codest puikiai kuria keičiamo dydžio interaktyvias žiniatinklio programas, naudodama pažangiausias technologijas ir užtikrindama vientisą naudotojų patirtį visose platformose. Sužinokite, kaip mūsų patirtis skatina skaitmeninę transformaciją ir verslo...

GERIAUSIAS
Programinės įrangos kūrimas

10 geriausių Latvijoje įsikūrusių programinės įrangos kūrimo įmonių

Naujausiame mūsų straipsnyje sužinokite apie geriausias Latvijos programinės įrangos kūrimo įmones ir jų inovatyvius sprendimus. Sužinokite, kaip šie technologijų lyderiai gali padėti pakelti jūsų verslo lygį.

thecodest
Įmonių ir didinimo sprendimai

"Java" programinės įrangos kūrimo pagrindai: A Guide to outsourcing Outsourcing Successfully

Išnagrinėkite šį esminį vadovą, kaip sėkmingai outsourcing "Java" programinę įrangą kurti, kad padidintumėte efektyvumą, įgytumėte patirties ir sėkmingai įgyvendintumėte projektus su The Codest.

thecodest

Prenumeruokite mūsų žinių bazę ir būkite nuolat informuoti apie IT sektoriaus patirtį.

    Apie mus

    The Codest - tarptautinė programinės įrangos kūrimo bendrovė, turinti technologijų centrus Lenkijoje.

    Jungtinė Karalystė - būstinė

    • 303B biuras, 182-184 High Street North E6 2JA
      Londonas, Anglija

    Lenkija - vietiniai technologijų centrai

    • Fabryczna biurų parkas, Aleja
      Pokoju 18, 31-564 Krokuva
    • Brain Embassy, Konstruktorska
      11, 02-673 Varšuva, Lenkija

    The Codest

    • Pagrindinis
    • Apie mus
    • Paslaugos
    • Case Studies
    • Sužinokite, kaip
    • Karjera
    • Žodynas

    Paslaugos

    • Patariamoji tarnyba
    • Programinės įrangos kūrimas
    • Galinės dalies kūrimas
    • Priekinės dalies kūrimas
    • Staff Augmentation
    • Atgalinės versijos kūrėjai
    • Debesų inžinieriai
    • Duomenų inžinieriai
    • Kita
    • QA inžinieriai

    Ištekliai

    • Faktai ir mitai apie bendradarbiavimą su išoriniu programinės įrangos kūrimo partneriu
    • Iš JAV į Europą: Kodėl Amerikos startuoliai nusprendžia persikelti į Europą?
    • Technikos plėtros centrų užsienyje palyginimas: Tech Offshore Europa (Lenkija), ASEAN (Filipinai), Eurazija (Turkija)
    • Kokie yra svarbiausi CTO ir CIO iššūkiai?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Autorinės teisės © 2026 The Codest. Visos teisės saugomos.

    lt_LTLithuanian
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian es_ESSpanish nl_NLDutch etEstonian elGreek pt_PTPortuguese cs_CZCzech lvLatvian is_ISIcelandic lt_LTLithuanian