JavaRush /Java Blog /Random-TL /Object-oriented programming (pagsasalin ng artikulo)
Exidnus
Antas
Санкт-Петербург

Object-oriented programming (pagsasalin ng artikulo)

Nai-publish sa grupo
Mula sa tagasalin: Sa kasamaang palad, wala akong anumang makabuluhang karanasan sa pagsasalin mula sa Ingles, kahit na marami akong nabasa sa Ingles. Ngunit lumabas na ang pagbabasa at pagsasalin ay dalawang magkaibang bagay. Gayundin, sa kasamaang-palad, wala akong makabuluhang karanasan sa programming (kamakailan lamang ay gumawa ako ng isang simpleng web application sa Spring MVC at Hibernate). Samakatuwid, ang pagsasalin ay naging mas masahol pa kaysa sa maaaring mangyari. Kinuha ko ang kalayaan ng bahagyang pagwawasto sa mga halimbawa ng code na ibinigay sa artikulo, dahil hindi sila sumusunod sa mga kombensiyon sa pagbibigay ng pangalan sa Java. Marahil ay hindi sulit na isalin ang mga pangalan ng ilang mga pattern (ang ganitong pagsasalin ay hindi nagbibigay ng maraming pag-unawa), ngunit naisip ko na ito ang mas mababang kasamaan. Ito ay nagkakahalaga ng hiwalay na pagbanggit tungkol sa "mataas na pagkakaisa" bilang isang pagsasalin ng "mataas na pagkakaisa". Sumasang-ayon ako, hindi ang pinakamahusay na pagsasalin. Ngunit ang "malakas na pagkakakonekta" ay "mataas na pagkabit" (isa pang mahalagang konsepto), at ang "pagkakaugnay" ay malamang na hindi angkop dito. Bukas ako sa pagpuna at buong pasasalamat na tatanggap ng mga komento sa artikulo sa anumang anyo. Ang Object-oriented programming ay isang istilo ng programming kung saan ang isang programa ay binubuo ng mga bahagi na tumutugma sa mga bagay sa totoong mundo. Anumang tunay na bagay ay may ilang mga katangian (na maaaring magbago o hindi sa paglipas ng panahon) at pag-uugali (na maaaring o hindi pagbabago depende sa iba).kondisyon). Halimbawa, ang lapis ay isang tunay na bagay sa mundo na may mga sumusunod na katangian:
  • Ito ay pula (hindi ito nagbabago sa paglipas ng panahon).
  • 10 sentimetro na ang haba nito ngayon (maaaring magbago ito kung tatasa ang lapis).
At mayroon itong sumusunod na pag-uugali:
  • Nag-iiwan ito ng marka kung ginamit nang tama.
  • Ang bakas ay maaaring mag-iba depende sa presyon (depende sa panlabas na mga kadahilanan).
  • Ang haba nito ay umiikli kung ito ay matalas (permanenteng pag-uugali).
Tulad ng sa halimbawang ito, ang mga bagay sa totoong mundo ay maaaring magkaroon ng maraming katangian, ngunit kapag nagsusulat ng mga programa ay isinasaalang-alang lamang namin ang mga kinakailangang katangian. Ang Object-oriented programming ay may mga pakinabang nito. Halimbawa, pinapadali nitong magtatag ng koneksyon sa pagitan ng isang real-world na bagay at isang programa sa inaasahang paraan. Talagang nakakatulong ito habang lumalaki ang application at maraming bagay ang nakikipag-ugnayan sa isa't isa. Nakakatulong ito sa pamamahagi ng mga responsibilidad sa loob ng layunin ng mundo, na nagbibigay-daan sa iyong tumuon sa pag-iisip sa pamamagitan ng aplikasyon. Ang isa pang mahalagang tampok na nauugnay sa OOP (Object Oriented Programming) ay ang pag-uuri ng mga bagay. Dahil ang mundo (totoo/virtual) ay puno ng mga bagay, mahirap kontrolin ang mga ito nang paisa-isa. Kailangan namin ng isang paraan upang pag-uri-uriin ang mga bagay na ito na makakatulong sa amin na iugnay ang iba't ibang mga bagay at ang kanilang mga katangian, tulad ng isang itim na lapis. Ito ay hindi makilala (pareho?) Kung ginamit sa nakaraang halimbawa, ngunit ito ay ibang bagay. Ngunit dahil pareho silang lapis, kabilang sila sa parehong klase na "Pencil". Samantalang ang panulat, na halos kapareho ng lapis, ay kabilang sa ibang klase. Gayunpaman, ang panulat at lapis ay parehong "Instrumento sa Pagsulat". Ang Object-oriented programming ay may mga sumusunod na prinsipyo:
Abstraction
Ang abstraction ay tinukoy bilang ang kalidad ng pakikipag-ugnayan sa mga ideya sa halip na mga kaganapan o, sa madaling salita, kalayaan mula sa mga katangiang representasyon . Nagbibigay-daan ito sa mga programmer na tumuon sa kung ano ang iprograma sa halip na kung paano magprograma . Ang abstraction ay maaaring isipin bilang isang kontrata kung saan nagbibigay kami ng functionality. Maaaring itago ang mga detalye ng pagpapatupad kapag ginagamit ang konseptong ito. Halimbawa, kung kailangan natin ng isang klase na nagsusulat, dapat nating tiyakin na mayroon itong "write" na paraan. abstract class writer { write (); } Ano ang nagawa natin? Nagdisenyo kami ng isang mataas na antas na klase na abstract, sa madaling salita, alam nito kung anong functionality ang kailangan namin, ngunit kung paano ito ipatupad ay wala sa saklaw ng klase na ito. Nag-aalok ito ng maraming benepisyo:
  • Ibinunyag namin ang pinakamababang impormasyong kinakailangan sa mga panlabas na entity, nagbibigay-daan ito sa amin na tumuon sa pag-iisip sa pamamagitan ng programa (ito ay nagbibigay-daan sa nakatutok na pag-iisip), maiwasan ang pagkalito at maiwasan ang paggawa ng hindi sinasadyang mga pangako.
  • Nag-iiwan kami ng puwang para sa mga pagpapabuti sa hinaharap na hindi magiging posible kung ang mga detalye ng pagpapatupad ay ibinunyag.
Mana
Ang ibig sabihin ng "mana" sa karaniwang Ingles ay "to acquire and pass on." Ang salitang ito ay umiral sa ating kultura sa napakatagal na panahon. Nakuha ng mga ninuno ang lupa sa pamamagitan ng pagsusumikap at ipinasa ito sa kanilang mga anak, maging ang kalikasan ay pinapaboran ang pamana. Lahat ng katangian ng katawan, gaya ng taas, kulay ng balat/mata/buhok, atbp. depende sa mga gene na minana natin sa ating mga magulang. Pinipigilan ng mana ang muling pag-imbento ng gulong at pinapabilis ang pag-unlad. Ito ay pareho sa OOP. Gumagawa kami ng parent class na may ilang pangunahing katangian/gawi. Ang lahat ng klase na nagmana mula sa magulang na ito ay maglalaman ng parehong mga katangian/gawi bilang kanilang magulang. Gayunpaman, ang mga minanang klase ay maaaring makakuha ng higit pang mga katangian/gawi o baguhin ang pagpapatupad ng gawi. class WritingInstrument { colour; write() { } } class Pen (child of parent) { inkcolour; } Sa halimbawa sa itaas, ang parent class (WritingInstrument) ay may "kulay" na katangian at isang "magsulat" na pag-uugali. Kapag idineklara ang descendant class (handle), ang "color" property at ang "write" na pag-uugali ay hindi na kailangang ideklara muli. Sila ay naroroon sa "handle" na klase dahil sa mana. Gayunpaman, ang isang descendant class ay maaaring magdeklara ng sarili nitong mga karagdagang katangian/gawi. Paano natin ito magagamit sa pagsasanay? Kaming mga developer ay sobrang tamad. Hindi namin gustong mag-print ng isang bagay nang paulit-ulit. Ang pagkakaroon ng maraming kopya ng parehong code ay hindi hinihikayat dahil sa mga sumusunod na pagsasaalang-alang:
  • Ang mas kaunting mga kopya ng code, mas madali itong mapanatili.
  • Kung walang maraming kopya ng code, ang pagbabago sa isang lugar ay makikita sa lahat ng dako.
  • Ang mas kaunting code, mas kaunting mga error.
  • Kung ginagamit ang isang code sa maraming lugar, makakamit ang generalization.
  • Nakatuon kami sa pagsulat ng code.
  • Nakatuon kami sa mga pagsubok.
Ang pamana sa Java ay nakakamit gamit ang mga keyword na "extends" at "implements". class WritingInstrument { } class Pen extends WritingInstrument { }
Polymorphism
Ang salitang "polymorphism" ay nagmula sa dalawang salita: "Poly" , i.e. “many” / “more than one” “morph” , i.e. "form" Sa literal, ang salitang "polymorphism" ay tumutukoy sa kakayahan ng mga bagay na kumilos sa iba't ibang paraan depende sa mga kondisyon. Sa programming, ang polymorphism ay maaaring ipatupad sa maraming lugar:
  • Mga klase
  • Paraan
  • Mga operator
Ang lahat ng nasa itaas ay maaaring kumilos nang iba depende sa mga kundisyon, marahil sa konteksto, kung saan ginagamit ang mga ito. Ito ay kapaki-pakinabang dahil ang kliyente (ang programmer na gumagamit ng iyong mga aklatan) ay hindi kailangang malaman ang maraming mga subtleties, at ang nais na pag-andar ay ipinatupad sa pamamagitan ng pagpili ng kinakailangang impormasyon mula sa konteksto. Class WritingObject { wrire() { // пишем, используя стандартные (по дефолту) цвета } } class Pencil extends WritingObject { write() { // пишем, используя серый цвет, написанный текст можно стереть } } class Pen extends WritingObject { write() { // пишем, используя голубой цвет, написанный текст нельзя стереть } } class Main { main() { WritingObject wr = new WritingObject(); wr.write(); // первый вызов WritingObject wr = new Pen(); wr.write(); // второй вызов WritingObject wr2 = new Pencil(); wr2.write(); // третий вызов } } Ang halimbawa sa itaas ay may default na pagpapatupad sa WritingObject, na pinalawig/na-override ng nagmula na mga klase na panulat at panulat. Ang write() method ay tinatawag na tatlong beses sa Main class. Sa bawat oras na ang isang iba't ibang mga pagpapatupad ay tinatawag na depende sa kung aling bagay ang pamamaraan ay tinatawag na. Sa kasong ito, ang write() na paraan ay may maraming uri ng pag-uugali dahil ito ay polymorphic.
Encapsulation
Ang Encapsulation ay tinukoy bilang pagkolekta ng kaugnay na data/functionality sa isang unit. Nakakatulong ito sa pagpapadali sa pag-access/pagbabago ng data. Halimbawa, kung kailangan naming i-print ang lahat ng mga katangian na mayroon ang isang partikular na user, mayroon kaming mga sumusunod na opsyon: printUserProperties(userName, userId, firstname, lastname, email, phone, … … ….) Gumawa kami ng isang paraan na kumukuha ng lahat ng mga katangian at i-print ang mga ito nang sunud-sunod. Habang dumarami ang bilang ng mga elemento sa listahan, hindi na posibleng matukoy ang mga tamang field, at ang pagdaragdag/pag-alis ng isang field ay magbabago sa lagda ng pamamaraan. Samakatuwid, kailangan nating palitan ang lahat ng gumagamit ng paraang ito, kahit na hindi nila kailangan ang mga kamakailang idinagdag na field. Upang gawing mas nababasa ang code at gawing mas madali ang mga pagbabago sa hinaharap, isinasama namin ang mga property sa isang klase at ginagawa itong isang collective object. class User { userName userId firstname lastname email phone .. .. .. } printUserProperties(user) {} Ang object ay isang software bundle ng mga variable at nauugnay na pamamaraan. Maaari kang kumatawan sa mga bagay sa totoong mundo gamit ang mga bagay sa programa. Maaari mong isipin ang mga totoong aso sa isang programa ng animation, o isang tunay na bisikleta bilang isang software object sa loob ng isang exercise bike. Sa OOP, ang isang klase ay isang napapalawak na template (program-code-template) para sa paglikha ng mga bagay, na nagbibigay sa kanila ng isang paunang estado (mga variable) at pagpapatupad ng pag-uugali (mga function, pamamaraan). Ang acronym na SOLID ay nilikha ni Michael Feather para sa "unang limang prinsipyo" na pinangalanan ni Robert C. Martin noong unang bahagi ng 2000s. Ang layunin ng mga prinsipyo, kapag ipinatupad nang magkasama, ay pataasin ang posibilidad na ang programmer ay gagawa ng isang sistema na madaling mapanatili at mapalawak. Ang mga SOLID na prinsipyo ay mga patnubay sa pagbuo ng programa na kinakailangan upang alisin ang "bulok" na code sa pamamagitan ng refactoring, bilang resulta kung saan ang code ay dapat na madaling mabasa at mapalawak. Ito ay bahagi ng agile at adaptive programming strategy.
Prinsipyo ng Iisang Pananagutan
Sa OOP, ang nag-iisang prinsipyo ng responsibilidad ay nagsasaad na ang bawat klase ay dapat na maging responsable para sa isang bahagi ng functionality na ibinigay ng programa, at ang responsibilidad na iyon ay dapat na ganap na naka-encapsulated ng klase na iyon. Ang lahat ng pag-andar nito ay dapat na malapit na nauugnay sa responsibilidad na ito.
Bukas/Saradong Prinsipyo
Sa OOP, ang bukas/sarado na prinsipyo ay nagsasaad na "ang mga entity ng software (mga klase, module, pamamaraan, atbp.) ay dapat na bukas sa extension ngunit sarado upang baguhin." Sa madaling salita, dapat payagan ng entity ang pag-uugali nito na palawigin nang hindi binabago ang source code.
Prinsipyo ng Pagpapalit ng Liskov
Ang substituability ay isang prinsipyo sa OOP. Ito ay nagsasaad na kung ang S sa isang computer program ay isang subtype ng T, kung gayon ang mga bagay na may uri ng T ay dapat na mapalitan ng mga bagay na may uri ng S (ibig sabihin, ang mga bagay na may uri ng S ay maaaring mapalitan ng mga bagay na may uri ng T) nang hindi nagbabago. anumang kinakailangang mga programa sa pag-aari (katumpakan, pagkumpleto ng gawain, atbp.).
Prinsipyo ng Interface Segregation
Ang prinsipyo ng paghihiwalay ng interface ay nagsasaad na ang programmer ng kliyente ay hindi dapat pilitin na umasa sa mga pamamaraan na hindi nito ginagamit. Ayon sa prinsipyong ito, kinakailangan na hatiin ang mga malalaking interface sa mas maliit at mas tiyak upang malaman lamang ng programmer ng kliyente ang tungkol sa mga pamamaraan na kawili-wili sa kanya. Ang layunin ng prinsipyo ng pag-decoupling ng interface ay panatilihing decoupled ang system, na magpapadali sa refactor, gumawa ng mga pagbabago, at muling i-deploy.
Dependency Inversion Principle
Sa OOP, ang prinsipyo ng dependency inversion ay nangangahulugang isang tiyak na anyo ng pagdiskonekta ng mga module ng programa. Sa pamamagitan ng pagsunod sa prinsipyong ito, ang mga karaniwang ugnayan ng dependency na itinatag mula sa mga high-level na module na bumubuo sa arkitektura ng aplikasyon (policy-setting) hanggang sa umaasa na mga low-level na module ay binabaligtad (nababaligtad), upang ang binagong mga high-level na module ay maging independent sa mga detalye ng pagpapatupad ng mababang antas ng mga module. Ang prinsipyong ito ay nagsasaad:
  • Ang mga high level na module ay hindi dapat nakadepende sa mga low level na module. Ang parehong uri ng mga module ay dapat nakadepende sa mga abstraction.
  • Ang mga abstraction ay hindi dapat nakadepende sa mga detalye ng pagpapatupad. Ang mga detalye ay dapat nakadepende sa mga abstraction.
Binabaligtad ng prinsipyo ang paraan ng pag-iisip ng mga tao tungkol sa object-oriented na disenyo sa pamamagitan ng pangangatwiran na ang mga bagay na may mataas at mababang antas ay dapat nakadepende sa parehong abstraction.

Mga prinsipyo ng GRASP

Ang General Responsibility Assignment Software Patterns (GRASP) ay nagbibigay ng mga alituntunin para sa pagtatalaga ng mga responsibilidad sa mga klase at bagay sa object-oriented na disenyo.
Controller
Ang pattern ng Controller ay nagtatalaga ng responsibilidad para sa pakikipag-ugnayan sa mga kaganapan sa system sa mga klase na hindi GUI na kumakatawan sa buong sistema o senaryo ng use case. Controller:
  • Ito ay isang bagay na hindi direktang nakikipag-ugnayan sa user at responsable para sa pagtanggap at pagtugon sa mga kaganapan sa system.
  • Dapat gamitin upang harapin ang lahat ng mga kaganapan sa system ng isa (o maraming magkakaugnay) na mga kaso ng paggamit.
  • Ito ang unang bagay sa likod ng GUI na kumokontrol sa mga pagpapatakbo ng system.
  • Hindi niya kailangang gawin ang gawain sa kanyang sarili; ang kanyang gawain ay kontrolin ang daloy ng mga kaganapan.
Tagapaglikha
Ang gawain ng creator class ay lumikha at magpasimula ng mga bagay para sa kasunod na paggamit. Alam nito ang mga parameter ng pagsisimula, pati na rin kung anong bagay ang gagawin. Minsan ang creator class ay aktibong gumagawa ng mga bagay at inilalagay ang mga ito sa cache, at nagbibigay ng isang pagkakataon kapag ito ay kinakailangan.
Mataas na Pagkakaisa
Ang mataas na pagkakaisa ay isang evaluative pattern, ang layunin nito ay upang mapanatili ang mga bagay sa isang estado na ang mga ito ay naglalayong magsagawa ng isang malinaw na gawain, ay madaling kontrolin at nauunawaan. Ang High Coupling ay karaniwang ginagamit upang suportahan ang Low Coupling. Ang mataas na pagkakaugnay ay nangangahulugan na ang mga responsibilidad ng isang partikular na elemento ay malinaw na tinukoy (mahigpit na nauugnay at lubos na nakatuon). Ang paghahati ng isang programa sa mga klase at subsystem ay isang halimbawa ng mga aksyon na nagpapataas ng pagkakaisa ng mga katangian ng system. Ang maluwag na pagkabit, sa kabilang banda, ay isang sitwasyon kung saan ang isang elemento ay may napakaraming hindi nauugnay na mga gawain. Ang maluwag na pinagsamang mga elemento ay malamang na mahirap maunawaan, magagamit muli, mahirap mapanatili, at mahirap baguhin.
Hindi direksyon
Ang pattern ng Roundabout ay nagpapanatili ng maluwag na pagkakabit (at muling paggamit) sa pagitan ng dalawang elemento sa pamamagitan ng pagtatalaga ng responsibilidad para sa pakikipag-ugnayan sa pagitan ng mga ito sa isang intermediate na bagay. Ang isang halimbawa ay ang pagpapakilala ng isang controller upang mamagitan sa pagitan ng data (modelo) at ang pagpapakita nito (view) sa pattern ng Model-View-Controller (MVC).
Dalubhasa sa Impormasyon
Ang Dalubhasa sa Impormasyon (din ang Eksperto o Prinsipyo ng Eksperto) ay isang prinsipyong ginagamit upang matukoy kung kanino ipagkakaloob ang responsibilidad. Kasama sa mga responsibilidad ang mga pamamaraan, mga kalkuladong field, atbp. Kapag ginagamit ang prinsipyong ito kapag nagtatalaga ng responsibilidad, ang pangunahing diskarte ay ang sumusunod na pagkakasunud-sunod ng mga aksyon: pag-aaral ng responsibilidad, pagtukoy sa impormasyong kinakailangan upang matupad ito, at sa wakas ay pagtatatag kung saan matatagpuan ang impormasyong ito. Ang paggamit ng prinsipyo ng Information Expert ay nagreresulta sa pagtatalaga ng responsibilidad sa klase na may pinakamaraming impormasyon upang maisakatuparan ito.
Mababang Coupling
Ang loose coupling ay isang evaluation pattern na tumutukoy kung paano magtalaga ng mga responsibilidad: maluwag na coupling sa pagitan ng mga klase, ang pagpapalit ng isa ay dapat na may kaunting epekto sa isa pa, na nagpapalaki ng reusability.
Polymorphism
Ayon sa polymorphism, ang pagkakaiba-iba ng pag-uugali batay sa uri ay itinalaga sa mga uri kung saan nangyayari ang pagkakaiba-iba na ito. Nakamit ito gamit ang mga polymorphic na operasyon.
Mga Protektadong Pagkakaiba-iba
Pinoprotektahan ng pattern ng Protected Changes ang mga elemento mula sa mga pagbabago sa iba pang elemento (mga object, system, subsystem) sa pamamagitan ng pagbabalot ng focus ng instability sa isang interface at paggamit ng polymorphism upang lumikha ng iba't ibang pagpapatupad ng interface na iyon.
Purong Katha
Ang purong konstruksyon ay nagsasangkot ng isang klase na hindi kumakatawan sa isang konsepto sa domain ng problema at partikular na idinisenyo upang makamit ang maluwag na pagkakabit, mataas na pagkakabit, at samakatuwid ay maximum na potensyal na muling paggamit (ang solusyon na inaalok ng pattern ng Information Expert ay hindi nakakamit nito). Ang ganitong klase ay karaniwang tinatawag na "Serbisyo" sa disenyong batay sa Domain.

Pagpuna

Ang pananaliksik ni Potok et al. ay nagpakita ng walang makabuluhang pagkakaiba sa pagitan ng OOP at mga pamamaraang pamamaraan.
Ang kritikal na paghahambing ng OOP sa iba pang mga teknolohiya, lalo na ang mga teknolohiyang may kaugnayan, ay mahirap dahil sa kakulangan ng kahulugan ng OOP na mahigpit at malawak na tinatanggap (Christopher J. Date)
Kung ikukumpara sa iba pang mga wika (LISP dialect, functional na wika, atbp.), Ang mga wikang OOP ay walang natatanging bentahe at nagpapataw ng hindi kinakailangang kumplikado. (Lawrence Krubner)
Nakikita ko ang object-oriented programming na teknikal na manipis. Sinusubukan nitong i-decompose ang mundo sa mga bahagi ayon sa mga interface na nag-iiba sa loob ng isang uri. Upang harapin ang mga tunay na problema, kailangan mo ng multisorted algebras - mga pamilya ng mga interface na umaabot sa maraming uri. Nakikita ko ang object-oriented programming na pilosopiko na hindi malusog. Ito ay nagsasaad na ang lahat ay isang bagay. Kahit na ito ay totoo, ito ay hindi masyadong kawili-wili: upang sabihin na ang lahat ng bagay ay isang bagay ay upang sabihin wala sa lahat. (Alexander Stepanov)
Ang katanyagan ng OOP sa mga malalaking kumpanya ay dahil sa "malalaki (at madalas na nagbabago) na mga grupo ng mga karaniwang programmer." Ang disiplina na ipinataw ng OOP ay pumipigil sa programmer na gumawa ng "sobrang pinsala." (Paul Graham)
Ang Object-oriented programming ay inuuna ang mga pangngalan at pangunahin. Bakit pumunta sa gayong matinding mga hakbang at ilagay ang isang bahagi ng pagsasalita sa isang pedestal? Bakit inuuna ang isang konsepto kaysa sa isa pa? Imposible para sa OOP na biglang gawing hindi gaanong mahalaga ang mga pandiwa sa ating pag-iisip. Ito ay isang kakaibang liko na pananaw. (Steve Yegge)
Inilarawan ni Rick Hickey, ang lumikha ng Clojure, ang mga object system bilang napakasimpleng modelo ng totoong mundo. Binigyang-diin niya ang kawalan ng kakayahan ng OOP na magmodelo ng oras nang tama, na lumilikha ng malalaking problema kapag nagiging karaniwan ang multithreading sa mga programa. Si Eric S. Raymond, isang Unix programmer at open source software advocate, ay naging kritikal sa pag-aangkin na ang OOP ay "The One Solution" at isinulat na ang OOP ay naghihikayat ng mga multi-layered na programa, na humahadlang sa transparency. Bilang isang kabaligtaran na diskarte, ibinigay ni Raymond ang halimbawa ng Unix at C.

Mga link

Ni Margaret Rouse @ WhatIs.com Wikipedia! ( Russian version ) inheritance is polymorphism SOLID (Object Oriented Design) ( Russian version ) Single Responsibility PrincipleArguments against OOPS ( Russian version ) Ano ang OOPS (without the hype) Translation: Varygin D.V.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION