Vasaris 23, 2008Objektinis programavimas (OOP)
Vakar vienas mano tinklaraščio skaitytojas pasidžiaugė mano straipsnių apie programavimą gausa ir įdomumu, bei paprašė plačiau papasakoti apie objektinį programavimą ir jo teikiamus privalumus. Kadangi pereiti nuo bet kokio programavimo iki tvarkingo (nebūtinai objektinio) programavimo pradedantiesiems dažnai būna sunku, tai aš pabandysiu paaiškinti kas yra objektas, kodėl programuotojai savo kodą skirsto į objektus ir kaip visą tai galima panaudoti praktikoje. Be to, šis straipsnis nebus visiškai nukreiptas į programuotojus, todėl jis turėtų pasirodyti įdomus ir kitiems, kompiuteriais besidomintiems, skaitytojams - jame nagrinėsiu ne programavimo kalbų subtilybes, o aiškinsiu bendrą objektinio programavimo sampratą.
Kas yra objektas? Į šį klausimą būtina žinoti atsakymą norint suvokti objektinio programavimo esmę. Pradėkime nuo to, kad objektu galima laikyti bet kokį realų ar įsivaizduojamą kūną, pvz.: katę, namą, knygą, mašiną ir t.t. yra objektai. Žinoma programavime objektai dažniausiai atspindi loginį kūną ar duomenų struktūrą, tačiau vis tiek objektai programavime yra panašūs į realaus gyvenimo objektus. Turbūt jums kilo klausimas, o kokia prasmė skirstyti kodą į objektus? Pirmiausia, objektas apibrėžiamas įvairias parametrais, iš kurių svarbiausi yra jo funkcijos arba veiksmai, kuriuos galima atlikti su objektu. Įsivaizduokime realų objektą knygų lentyną, kurią apibrėžėme jos talpa. Su knygų lentyna galime atlikti šiuos veiksmus: įdėti knygą, rasti knygą, paimti rastą knygą, perkelti rastą knygą, suskaičiuoti knygas ir pan. Matome, kad mūsų objektas yra konkretus daiktas, kuris turi keletą parametrų (dydį, spalvą ir pan.) ir apibrėžtus veiksmus, kuriuos galime su juo atlikti.
Objektai visose kalbose apibrėžiami vienodai - klasėmis. Klasė, tai rinkinys funkcijų bei kintamųjų pagal kuriuos ir sukuriamas objektas. Nemažai pradedančiųjų programuotojų galvoja, kad klasė ir yra objektas, tačiau tai nėra tiesa - klasė yra tik objekto struktūros aprašas ir iš vienos klasės galima sukurti neribotą kiekį objektų. Kartais žmonės sutrinka ir dėl to, kad klasė gali būti panaudojama keliems objektams, tačiau tai yra gana aišku, nes juk mes galime naudoti ne vieną knygų lentyną - vietoje pirmajame pavyzdyje naudotos knygų lentynos galime naudoti tris lentynas. Visos trys lentynos gali būti skirtingos, tačiau visų jų funkcionalumas (veiksmai su jomis) bus apibrėžtas vienodai. Taigi galime drąsiai sakyti, kad objektas yra realių kūnų atitikmuo programavime ir kiekvienas objektas apibrėžiamas veiksmais, kuriuos su juo galima atlikti (funkcijos) bei savybėmis (kintamieji).
Programavime objektai naudingi tuo, kad paprastas kintamasis savyje talpina ne tik konkrečią reikšmę, bet ir visą spektrą veiksmų. Jeigu norite suprogramuoti rašytojų paieškos algoritmą, kuris gražina visus rašytojus, kurių vardas atitinka konkrečią reikšmę, tai labiausiai tikėtina, kad rezultatus gražinsite kaip asociatyvų dvimatį masyvą. Toks sprendimas yra pateisinimas ir teisingas, tačiau norint pasiekti maksimalų optimalumą reikėtų gražinti vienmatį masyvą, kuriame kiekvienas rašytojas būtų apibrėžtas ne asociatyviu vienmačiu masyvu, o konkrečiu rašytojo objektu. Jei rezultatus gražinate masyvu, tai norėdami atlikti papildomus veiksmus su rašytojais jūs turėsite dirbti su masyvo reikšmėmis, tačiau jei naudosite objektus, tai su rezultatais galėsite dirbti tiesiogiai. Pasižiūrėkite pavyzdį (PHP):
Funkcinis programavimas
$writers = getWriters(); //Gauname rašytojus
foreach ($writers as $writer)
{
print $writer['first_name'] . $writer['last_name'];
}
Objektinis programavimas
$writers = getWriters(); //Gauname rašytojus
foreach ($writers as $writer)
{
$writer->printName();
}
Antrasis kodas yra geresnis, nes norėdami išvesti rašytojo vardą ir pavardę mes neturime žinoti kokiais masyvo elementais jie žymimi. Programuojant objektiškai mums nebūtina žinoti kaip saugomi duomenys objekto viduje - mums užtenka žinoti funkcijų vardus, kuriais galima iškviesti konkrečius veiksmus. Tai patogu tuo, kad mūsų pavyzdinėje rašytojo klasėje pakeitus rašytojo vardo saugojimo būdą mums nereikės perrašinėti kodo klasės išorėje - visa programa nesikreipia į duomenys tiesiogiai, todėl pakitimai duomenų struktūroje neturės įtakos programos darbui. Žinoma yra dar daug kitų objektinio programavimo pliusų - kodo per-panaudojimas, paveldėjimas, abstrakcijos ir interfeisai, statiniai metodai ir t.t., tačiau mano manymu šiuos dalykus reikia nagrinėti tik tada, kai yra iš esmės suprantama objektinio programavimo prasmė bei tvarka. O be to, labai svarbu, kad objektinis programavimas nėra privalomas ir tai tik vienas iš būdų programuoti, kuris nebūtina yra privalomas ir tai, kad jūs programuojate objektiškai nebūtinai reiškia, kad jūs programuojate gerai.
Be abejo aš tikrai nerodysiu kaip reikia aprašyti klases ar kurti objektus - internete ir knygose yra daugybė pavyzdžių ir pats objekto suprogramavimas nėra sudėtingas suvokiant objektinio programavimo esmę. Kai aš mokiausi programuoti objektiškai, tai turbūt didžiąją dalį laiko praleidau studijuodamas teorinę medžiagą, o ne konkrečios programavimo kalbos subtilybes - aprašyti klasę galima išmokti perskaičius vieną knygos paragrafą, tačiau suvokti objektų prasmę gali pareikalauti žymiai daugiau laiko. Tikiuosi visiems pradedantiesiems šis straipsnis bus naudingas ir informatyvus, o jei kyla klausimų, tai galite drąsiai man rašyti ir aš pasistengsiu atsakyti į visus jūsų klausimus.
Patiko ką perskaitei? Užsiprenumeruok RSS srautą ir visada gauk mano naujausius įrašus pats pirmas! Tai ne tik, kad yra be galo patogu, tačiau ir leis tau nepraleisti nei vieno mano įrašo. Jei kiltų problemų - rašyk.



2008-02-23 17:01:48
Tai antram pavyzdį neturėtų būt $writers = new getWriters(); ?
2008-02-23 18:37:25
Reikėjo šiek tiek praktiškesnio pavyzdžio:
$asterisk = new Dude();
$asterisk->gravity = 999999;
$asterisk->jump();
# OMFG!
2008-02-23 20:33:08
asterisk, argi getWriters galėtų būti objektas? :) Manau būtų šiek tiek logiškesnis pavadinimas… getWriters tiesiog funkcija, kuri gražina rezultatus ir ji nebūtinai priklauso objektui.
2008-02-23 21:18:21
Siūlau geresni varianta:
[code]
$writers = Writer.FetchAll(); // statinis metodas Writer klases
foreach ($writers as $writer) {
print $writer; // naudoja __toString() metoda
}
// arba
$writer = new Writer(”Jonas”, “Kapitonas”);
$writer.Save();
print $writer;
[/code]
2008-02-23 21:19:45
oj sumaisiau PHP su C# :)
taska (.) reikia pakeisti i rodykle (->)
$writers = Writer->FetchAll();
2008-02-23 21:20:47
dar viena klaida :D
staitnis metodas su :: daromas
galutinis variantas:
$writers = Writer::FetchAll();
2008-02-24 13:53:05
Objektinis programavimas nėra vienintelis ir pats teisingiausias būdas programuoti. Viskas priklauso nuo užduoties. Rašant neinteraktyvias aplikacijas, pavyzdžiui kaip serverinę internetinio puslapio dalį, neverta programuoti objektiškai, nes programa vykdoma pagal apibrėžtą scenarijų. Palengvinti tokių programų rašymą buvo sugalvotos skriptinimo kalbos, kurios kūrimo pradžioje neturėjo nieko bendro su objektiniu programavimu. Vėliau kūrėjai stengdamiesi padaryti kalbą kuo populiaresnia pridėjo begalia naujų „feature’ų“. Tai neliko nepastebėta „jaunųjų programuotojų“, kurie labai mėgsta reikštis internete. Kadangi būdami jauni ir imlūs naujomės (nesvarbu ar tai šūdas ar medus, svarbu būti „moderniu“), jie pradėjo naudoti objektinį programavimą kur tik begali. Tuoj pat atsirado visokie Ruby on rails ir panašaus plauko karkasai, kurie paviliojo „jaunėlius“ skambiu šūkiu: „Atlik darbą nieko nedarydamas“.
2008-02-24 13:57:11
Sorry už sarkazmą, bet kitaip neišėjo. Jei su manim nesutinkate, pasistengsiu pateikti argumentų :)
2008-02-24 17:57:36
Ačiū, Juozai, kad parašiai straipsnį. Bet, tokiu panašių straipnsnių esu sakitęs. :) Kolkas 98% pritariu Giedriui. Dabar vos kaip ne mada užėjusi, naudoji OOP - ‘šustras programeris’. Žinoma, neteigiu, kad aš teisus. Vien dėl to tavęs ir prašiau, kad parašytum šį sraipsnį.
Tačiau, kolkas neradau savo koduose kur galėčiau panaudoti OOP. Tai yra dėl to, kad aš jo nesuprantu. Sintaksę ir pan., paskaitęs manualą suprantu. Bet naudos, kodėl turėčiau naudoti OOP - ne. Žinoma, kolkas aš tik mokausi programuoti, mano skriptai nėra puikūs, skaitomumo, Gen. time atžvilgiu, gal būt todėl dar nenaudojų OOP, gal kada ’subręsiu’. :) Nežinau, noriu perkąsti tą OOP, bet nesuprantu… Tikrai, kiek skaičiau, budavo tokie argumentai ‘gerai skaitomas kodas’,'patogus kodas’ ir tt ir pan. Na nežinau, kolkas man nesuprantamas dalykas OOP… :)
2008-02-24 21:36:01
Aš naudoju OOP, nes:
1. Kodas yra tikrai organizuotesnis ir aiškesnis, nei dirbant vien su funkcijom
2. Yra galimybė praplėsti kitų kodą naudojant klasių paveldėjimą
3. Yra galimybė praplėsti pačio kodą naudojant abstrakcijas
4. Taip programuodamas tikriausiai lengviau susirasiu darbą
5. Taip man tiesiog patinka programuoti nes objektai yra natūralus dalykas
Ir t.t. na tiesiog man taip patinka, taip yra patogu ir taip daro daug kas. Taip, aš blogas, darau blogai kaip ir kiti daro blogai, bet man tai tiesiog patinka. Patinka dėl visų išvardintų priežasčių ir turbūt dėl daugelio kitų, kurių tiesiog neprisiminiau.
2008-02-26 00:42:48
Dėl OOP tai va neblogas straipsniukas: http://atviras.lt/forumas/mwf/topic_show.pl?tid=211
MVC yra naudingas dalykas ;)
Aišku ne visais atvejais reikalingas tas OOP ir MVC.
Beje su OOP kodas nepasidaro aiškesnis tik tiek, kad organizuotesnis. Taip pat lengviau surast kur kokios dalys yra.
2008-04-03 19:48:25
Labai buciau dekinga jei atsirastu nors truputelis informacijos apie abstrakcija … labai buciau dekinga …
2008-04-18 22:26:39
php:istai .)
Writer.find(:all).each {|writer| puts writer.name}
vat jums tikras objektinis
2008-07-14 23:56:15
Nu nesupratau man yra klausimas.
Tai jei as rasau gera ir trumpa vienos eilutes programa tokia:
perl -ne ‘@a=split”";for(@a){printf”%02x “,ord;print”\n”unless++$c % 20}’ byla.3da
Tai cia jau objektinis programavimas ar dar ne?