The Timeless Way of Building

ეს ერთ-ერთი ყველაზე გავლენიანი წიგნი იყო ჩემთვის და მინდა მასზე დავწერო 🙂 ძალიან უცნაური მიზეზით გადავაწყდი – პროგრამირების პატერნების თითქმის ყველა წიგნში იყო ციტატა აქედან, არადა Timeless way of building საერთოდ არ ეხება პროგრამირებას, არქიტექტურაზეა (და მარადიულობაზე).
ცნობილი არქიტექტორი, კრისტოფერ ალექსანდერი, აღწერს იდეოლოგიას, თუ როგორ უნდა აშენდეს შენობები, ბაღები, გზები, ქალაქები რომ ნაგებობებმა საუკუნეებს გაუძლოს არსით. საუბრობს არა მხოლოდ შენობებზე, არამედ ცხოვრებაზე.

ჩემდა სამარცხვინოდ უნდა ვაღიარო, სათანადოდ არ ვაფასებდი და პატივს არ ვცემდი ამ სფეროს. ალბათ იმიტომ რომ არქიტექტორებმა გამაბრაზეს. დიახაც, გამაბრაზეს. არ მომწონდა რომ არ ფიქრობდნენ ჩვენზე; რომ ნორმად გახადეს დაბალჭერიანი, ერთნაირი ბინები პატარა ოთახებით და ცოტა ფანჯრებით, პატარა სამზარეულოთი და კიდევ უფრო პატარა აბაზანით, მეზობლების ნაბიჯების ხმით, უბაღეობით და უხეებობით. ოფისები საავადმყოფოებს ან, უარეს შემთხვევაში, ციხეებს დაამსგავსეს, მიწას და სიმწვანეს მოაცილეს.

შეიძლება არ მომწონდეს არქიტექტურა, მაგრამ მეც კი ვხვდები გარემოს რამხელა გავლენა აქვს ჩვენს განწყობაზე, პროდუქტიულობაზე, ენერგიულობაზე – საბოლოო ჯამში ფაქტიურად ჩვენს საქმიანობაზე და მთელს ცხოვრებაზეც. აი ასეთი რთული მისია აკისრიათ არქიტექტორებს. რეალურად მათ უამრავი სოციალური, ეკონომიკური და ფსიქოლოგიური პრობლემის გადაწყვეტა შეუძლიათ.

კრისტოფერის წიგნში ბევრ გემრიელობას შეხვდებით ამ თემაზე. ის წერს თუ რა განასხვავებს კარგ და ცუდ ნაგებობას, კარგ და ცუდ ქალაქს, საუბრობს “თვისებაზე”, რომელსაც “სახელი არ აქვს” – რომელიც განსაზღვრავს იქნება თუ არა გარემო ერთიანი, ჯანმრთელი, ცოცხალი, თვით განვითარებადი – სადაც სიცოცხლე იქნება, სადაც ადამიანებს განვითარების და შემოქმედების სურვილი ექნებათ.

მე მოკლედ და კარგად ვერ გადმოვცემ მის იდეოლოგიას, ამიტომ საერთოდ არ შევეხები. მაგის გარდა იქ იყო უამრავი პატარა პრაქტიკული მომენტიც და რამდენიმე განსაკუთრებით ჩამრჩა:
მაგალითად, ადამიანები ისეთი ოთახებისკენ მიისწრაფიან, რომელთაც ორ მხარეს აქვს ბუნებრივი განათება. ასე სინათლე რამდენიმე მიმართულებით შემოდის და გაცილებით კომფორტულად აღიქმება.
ან, თუ ოთახები სამხრეთისკენ იხედებიან, სახლი განათებული, მზიანი და კარგი ენერგიით სავსეა. მის წინ ეზოში ყოფნა ძალიან სასიამოვნოა, ჩრდილოეთის მხარეს ბაღში კი იშვიათად გახვალთ.
ან კიდევ ძალიან უცნაურად და ცუდად მოგეჩვენებათ ბინის შესასვლელი კარი რომელიც პირდაპირ ქუჩაზეა და შესვლამდე არ ხდება სივრცის ცვლილება, ან სიმაღლით, ან განათებით, ან მანძილით…

რაც მთავარია, კრისტოფერის პატერნებში ყველაფერს თავისი დანიშნულება აქვს და რაღაც მიზანს ემსახურება. ისე იზრდება და ვითარდება ნაგებობები, როგორც ბუნება ქმნის თავის გარემოს. ერთგან ატმის ხეს იხსენებს, რომელიც აგურის კედელზე იყო აზრდილი სამხრეთის მხრიდან. მზე აგურებს ათბობდა, აგურები კი ატმებისთვის ინახავდნენ სითბოს..

მის მაგალითებში ნაგებობები ბუნებასთან ჰარმონიაში არიან, ამასთან დეტალები პრაქტიკული მიზნებიდან გამომდინარეობენ. ზუსტად ამიტომ ამბობს რომ არქიტექტორები შეიძლება ვერ გასწვდნენ ყველას ინდივიდუალურ მოთხოვნებს და ჩვენ ჩვენით შეგვიძლია საკუთარი გარემოს მოწყობა. უკეთ ვიცით როდის სად რა გვჭირდება.

ამ წიგნის მერე მოგინდებათ ოთახი შეცვალოთ, სახლი და ეზო შეცვალოთ, შეიძლება ჩემსავით ოცნებად გაგიხდეთ აშენება.

(არსებობს წიგნის მეორე უზარმაზარი ნაწილიც, რომელიც არქიტექტურილი პატერნებით არის სავსე. თუ რამეს აკეთებთ ახლა, ძალიან გირჩევდით ამ წიგნების ნახვას.)

Vineyard Farmer's Market
Vineyard Farmer’s Market by Christopher Alexander
Vineyard Farmer's Market
Vineyard Farmer’s Market by Christopher Alexander

მილიარდ დოლარიანი შეცდომა

ასეთი სახელი ჰქონდა ტონი ჰოარის პრეზენტაციას 2009 წლის კონფერენციაზე სადაც პროგრამირების ისტორიაში ცუდი გადაწყვეტილებების შესახებ იყო მოხსენებები. მე მხოლოდ შარშან ვნახე და მას შემდეგ კიდევ ბევრმა წყალმა ჩაიარა, მაგრამ პრინციპში დღესაც აქტუალურია ეს საკითხი და მე მგონი ცალსახად ეფექტური გამოსავალი ჯერ ჩამოყალიბებული არ არის.

პრეზენტაცია 1965 წელს გამოგონილი null reference-ს ეხებოდა, რომელიც მილიარდ დოლარიან შეცდომად შეაფასა მისმა შემქნელმა:

“I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.”

რეალურად, მე არ ვფიქრობ რომ თვითონ null reference-ის შექმნა იყო არასწორი, რადგან მის გარეშე ალბათ ძალიან ძნელი იქნებოდა თუნდაც OOP პროგრამირება, გაცილებით ზედმეტი ლოგიკის წერა და უარესი კომპრომისების და ბაგების მოვლა მოგვიწევდა. ამიტომ შეგვიძლია უფრო type checking სისტემებს დავაბრალოთ null-თან დაკავშირებული პრობლემები. ყოველ შემთხვევაში, ჰოარის პრეზენტაციიდანაც დაახლოებით ასეთი აზრი გამოვიტანე.

კონკრეტულად რომ ვთქვათ აი ასეთ პრობლემაზეა საუბარი (ორაკლის საიტიდან ავიღებ მაგალითს):
წარმოვიდგინოთ ჩანაწერი..

String version = computer.getSoundcard().getUSB().getVersion();

როცა ჯავაში აღვწერთ მეთოდს, მას ვუთითებთ დასაბრუნებელ ტიპს. რეალურად დასაბრუნებელი მნიშვნელობა არ არის ამ ტიპის, არამედ ერთ-ერთია სიმრავლიდან { null, ეს ტიპი }

ფაქტიურად ნებისმიერი მეთოდისგან (რომელიც ობიექტს აბრუნებს) შეიძლება null reference მივიღოთ შედეგად და სანამ ამ შედეგს გამოვიყენებთ, შემოწმება გვიწევს.
ზევით აღწერილი კოდი უსაფრთხო რომ იყოს, ასე უნდა ჩაგვეწერა:

String version = "UNKNOWN";
if(computer != null){
    Soundcard soundcard = computer.getSoundcard();
    if(soundcard != null){
        USB usb = soundcard.getUSB();
        if(usb != null){
            version = usb.getVersion();
        }
    }
}

თუმცა, როგორც წესი, უფრო ხშირად ვცდილობთ რომ ასეთი ჩანაწერი თავიდან ავირიდოთ. best practice-ების მიხედვით რეკომენდირებულია მეთოდი ისე ვწეროთ რომ მან არასდროს დააბრუნოს null, არამედ, ან რაღაცა ცარიელი ობიექტი მიიღოს შედეგად ან checked შეცდომა ისროლოს. ასე ნაწერი კოდი გაცილებით გვაზღვევს runtime-ში null pointer შეცდომებისგან.

მხოლოდ რეკომენდაციების იმედზე რომ არ ვიყოთ, ჯავას მერვე ვერსიაში შემოვიდა Optional ტიპი და ასევე @NonNull @Nullable ანოტაციები და ეს რამე რუმეები საშუალებას გვაძლევს მეტად ინფორმატიული იყოს ჩვენი კოდი და ცოტა კომპილაციის დროსაც მოგვეხმაროს. თუ ვიცით რომ რომელიმე ობიექტი შეიძლება null გახდეს, შეგვიძლია ის Optional კლასის საშუალებით შევინახოთ. და მერე გამოყენების დროს გავითვალისწინოთ ეს საშიშროება.

ჯავაში ასე გამოვიდოდა getSoundcard მეთოდის სიგნატურა:

Optional<Soundcard> getSoundcard()

მერე გამოყენებისას უნდა დავწეროთ

Optional<Soundcard> optional = getSoundcard()
if (optional.isPresent()) {
    Soundcard soundcard = optional.get();
    …..
}

ან სხვა უფრო მოსახერხებელი მეთოდების გამოყენება შეიძლება – orElse, ifElse, ifPresent.. ა.შ.

ზოგ ენაში შემოიღეს მოკლე ჩანაწერიც, მაგალითად Swift-ში შეგხვდებოდათ ასეთი რამ:

var version = computer?.soundcard?.USB?.version

ამ ჯაჭვში ერთ ერთი მაინც თუ დააბრუნებს null-ს, მომდევნო getter-ების გამოძახება აღარ გაგრძელდება და მთელი შედეგი null გამოვა.

Groove ენაში არის ელვისის ოპერატორიც 😀 რომელიც ასე გამოიყურება ?:

String version = computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";

და მაგითი default მნიშვნელობა შეგვიძლია შემოვიტანოთ null-ის შემთხვევაში.

ბოლო რამდენიმე თვეა რაც Swift-ზე წერას ვცდილობ. ჯერჯერობით ენა არ არის სრულად ჩამოყალიბებული და ხშირად იცვლება. თუმცა ეს კონცეპტი ალბათ არსად წასვლას არ აპირებს. თავიდან ძალიან გამიჭირდა იმასთან შეგუება, რომ ენა გაიძულებს ცვლადის გამოცხადებისთანავე განსაზღვრო optional იქნება ის თუ არა. თუ კი, მაშინ ყველგან სადაც ამ ცვლადის გამოყენებას შეეცდებით, მისი null-ზე შემოწმება და მნიშვნელობის ე.წ. unwrap მოგიწევთ optional ტიპის ცვლადისგან. კოდი არ დაკომპილირდება სხვა შემთხვევაში.

ამ პოსტში ელდარი უნდა დავთაგო : )) ერთხელ მასთან ვიწუწუნე ამ თემაზე და იმ დღეს დამაფიქრა, შემაცვლევინა აზრი. მერე წავედი და გემრიელად დავარეფაქტორე კოდი. არც ისეთი ცუდი ყოფილა ეს optional ტიპი. რაც დრო გადის, ვხვდები, რომ კარგ საქმეს მიკეთებს და მაიძულებს არ გავახალტურო რაღაცები. ასე რომ ვნახოთ.. იქნებ ჯავაშიც გაგვილამაზონ სინტაქსი თორემ დაიკარგება კაცი ამდენ boilerplate კოდში.