विकास म्हणजे नवीन आणि उपयुक्त काहीतरी पुनरावृत्तीने (iterative) तयार करणे.
जेव्हा आपण विकासाचा विचार करतो, तेव्हा नवीन उत्पादन विकास आपल्या मनात येतो. हे वैयक्तिक उत्पादने तयार करणाऱ्या उत्पादनापेक्षा (manufacturing) वेगळे आहे; त्याऐवजी, यात उत्पादनांसाठी डिझाइन स्पेसिफिकेशन्स किंवा मोल्ड्स (साचे) तयार करणे समाविष्ट आहे.
त्यामुळे, नवीन उत्पादन विकासाद्वारे तयार केलेले ब्लूप्रिंट्स किंवा मोल्ड्स कारखान्यांमध्ये अनेक समान उत्पादने तयार करण्यासाठी वारंवार वापरले जातात.
वैयक्तिक क्षमता विकसित करणे किंवा समाज आणि राष्ट्रे विकसित करणे यांसारखे उपयोग देखील आहेत. याचा अर्थ केवळ आपल्याकडे असलेल्या गोष्टींमध्ये वाढ होणे नव्हे, तर विकसित क्षमतांचा वारंवार वापर करण्याची आणि त्यांचा लाभ घेण्याची क्षमता असणे.
व्यक्ती आणि समाजाची आर्थिक शक्ती आर्थिक परिस्थितीमुळे चढ-उतार होऊ शकते, परंतु विकसित क्षमता मूलभूतपणे कायमस्वरूपी असतात.
त्या कमी झाल्या तरी, आर्थिक समृद्धीतील चढ-उतारांऐवजी ती घट मानली जाते.
याशिवाय, तंत्रज्ञान आणि ज्ञानाचा विकास देखील आहे. व्यक्ती किंवा विशिष्ट समाजाच्या क्षमतेपेक्षा वेगळे, यात सहजपणे सामायिक (shareable) होण्याची क्षमता असते.
आणि या विकासाचे परिणाम असलेल्या उत्पादने, क्षमता, ज्ञान आणि तंत्रज्ञान यांपैकी काही पुढील विकासासाठी योगदान देऊ शकतात.
अशा उपयुक्त निष्पत्ती विकसित करून, विकासाची व्याप्ती वाढते आणि कार्यक्षमता व गुणवत्ता सुधारते.
एआय-आधारित सॉफ्टवेअर विकास
सामान्यतः, विकासासाठी बराच वेळ आणि मोठा प्रयत्न लागतो. विशेषतः जेव्हा समाज प्रगत होतो आणि विविध गोष्टी अधिक अत्याधुनिक होतात, तेव्हा नवीन गोष्टी तयार करणे आणखी कठीण होते.
तथापि, जनरेटिव्ह एआयच्या आगमनामुळे, ही परिस्थिती बदलत आहे. सध्या, जनरेटिव्ह एआयच्या उच्च प्रोग्रामिंग क्षमतेमुळे सॉफ्टवेअर विकासामध्ये मोठे बदल होत आहेत.
या परिस्थितीत, जनरेटिव्ह एआयवर आधारित स्वायत्त एजंट्स (autonomous agents) सॉफ्टवेअर अभियंते म्हणून सॉफ्टवेअर विकासाच्या केंद्रस्थानी येतील अशी भविष्यातील कल्पना आता प्रत्यक्षात येत आहे.
आपण सध्या संक्रमणकालीन टप्प्यात आहोत. आपण जनरेटिव्ह एआयवर पूर्णपणे विकास सोपवू शकत नसलो तरी, जनरेटिव्ह एआयचा कौशल्याने वापर केल्यास सॉफ्टवेअर विकासाला मोठ्या प्रमाणात पुढे नेले जाऊ शकते.
याला एआय-आधारित सॉफ्टवेअर विकास (AI-driven software development) असे म्हणतात.
विकासाभिमुख विकास
जेव्हा जनरेटिव्ह एआय सॉफ्टवेअर विकासाला अधिक कार्यक्षम बनवते, तेव्हा ते केवळ अंतिम लक्ष्य सॉफ्टवेअरच्या विकासालाच नव्हे, तर विकासात मदत करणाऱ्या सॉफ्टवेअरच्या विकासालाही सुव्यवस्थित करू शकते.
आधी नमूद केल्याप्रमाणे, विकासाला सुलभ करणारे आउटपुट त्याची व्याप्ती वाढवतात आणि कार्यक्षमता व गुणवत्ता सुधारण्यास मदत करतात. शिवाय, जर ते प्रभावीपणे तयार केले गेले, तर ते इतर विकास प्रकल्पांमध्ये पुन्हा वापरले जाऊ शकतात.
म्हणून, सॉफ्टवेअर विकास प्रक्रियेदरम्यान विकासाला मदत करणारे सॉफ्टवेअर विकसित केल्याने, एकूण कार्यक्षमता वाढवता येते आणि हे संसाधने भविष्यातील विकासासाठी वापरता येतात.
परंपरेनुसार, असे सहायक सॉफ्टवेअर विकसित करणे ही एक सामान्य पद्धत होती, परंतु त्यासाठी स्वतःचा विकास वेळ आणि प्रयत्न लागत असे, ज्यासाठी काळजीपूर्वक विचार आणि केंद्रित अंमलबजावणी आवश्यक होती.
जनरेटिव्ह एआयचा वापर करून, मनात येणाऱ्या लहान कामांना स्वयंचलित करण्यासाठी साधे सॉफ्टवेअर त्वरित तयार करता येते. जर कामामध्ये स्पष्ट प्रक्रिया समाविष्ट असेल, तर जनरेटिव्ह एआय जवळजवळ कोणतीही चूक न करता अचूक प्रोग्राम तयार करू शकते.
परिणामी, सॉफ्टवेअर विकास प्रक्रियेदरम्यान विकासाला मदत करणारे सॉफ्टवेअर विकसित करणे पूर्वीपेक्षा सोपे झाले आहे.
आणि, याबद्दल सखोल विचार केल्यास, एक विकास शैली उदयास येते जिथे विकासासाठी उपयुक्त साधने प्रक्रियेदरम्यान सतत तयार केली जातात, ज्यामुळे विकास पद्धतीतच बदल होतो.
याला आपण "विकासाभिमुख विकास" (developmental development) असे म्हणू.
विकासाभिमुख विकास सरावण्यासाठी, एखाद्याला स्वतःच्या सॉफ्टवेअर विकासाचे वस्तुनिष्ठपणे निरीक्षण करण्याची सवय असणे आवश्यक आहे, ज्यात सॉफ्टवेअरद्वारे कोणते भाग हाताळले जाऊ शकतात आणि कोणते भाग केवळ मानवाद्वारे हाताळले जाऊ शकतात याचा विचार करणे, तसेच असे सहायक सॉफ्टवेअर विकसित करण्याचे कौशल्य असणे आवश्यक आहे.
याव्यतिरिक्त, जनरेटिव्ह एआयला या सॉफ्टवेअर साधनांमध्ये समाविष्ट केले जाऊ शकते. सॉफ्टवेअरमध्ये ते एम्बेड (embed) केल्याने, जनरेटिव्ह एआय एजंट्सच्या विपरीत, प्रक्रियेची व्याप्ती काही प्रमाणात कमी केली जाऊ शकते आणि मार्ग परिभाषित केले जाऊ शकतात.
एआय एजंट्स प्रॉम्प्ट्सद्वारे (prompts) समान परिणाम साध्य करू शकतात, परंतु एम्बेड केलेले जनरेटिव्ह एआय असलेले सॉफ्टवेअर प्रोग्राम्स आणि प्रॉम्प्ट्स दोन्ही एकत्र करून अचूकता अधिक सहजपणे वाढवू शकते.
जर अशा विकासाभिमुख विकासाचा सराव केला गेला, तर पहिल्या प्रकल्पाच्या तुलनेत दुसऱ्या प्रकल्पात गुणवत्ता आणि खर्च या दोन्हीमध्ये सुधारणा दिसून येईल. शिवाय, प्रत्येक त्यानंतरच्या प्रकल्पासह—तिसऱ्या, चौथ्या आणि पुढील—सुधारणा सतत वाढत जातील.
हे केवळ जनरेटिव्ह एआय वापरून सॉफ्टवेअर विकसित करण्यापेक्षा पूर्णपणे वेगळे आहे. जनरेटिव्ह एआय साधनांवर केवळ प्रभुत्व मिळवणाऱ्या टीम्समध्ये आणि विकासाभिमुख विकासाचा सराव करणाऱ्या टीम्समध्ये कालांतराने मोठी दरी निर्माण होईल.
रिफॅक्टरिंग-आधारित चाचणी (Refactoring-Driven Testing)
टेस्ट-ड्रिव्हन डेव्हलपमेंट (TDD) नावाची एक संकल्पना आहे, जिथे स्पेसिफिकेशन्सवर आधारित चाचण्या (tests) प्रथम डिझाइन केल्या जातात आणि नंतर त्या चाचण्या यशस्वी करण्यासाठी सॉफ्टवेअर विकसित केले जाते.
सुरुवातीला, मलाही वाटले होते की जनरेटिव्ह एआयचा वापर करून, स्वयंचलित चाचणीसाठी (automated testing) चाचणी प्रोग्राम विकसित करणे सोपे होईल, ज्यामुळे टीडीडी (TDD) शक्य होईल.
तथापि, जेव्हा मी विकासाभिमुख विकास (developmental development) प्रत्यक्षात आणण्यास सुरुवात केली, तेव्हा मला असे वाटू लागले की अंमलबजावणी करण्यापूर्वी चाचण्यांचा विचार करणे हा नेहमीच सर्वात योग्य दृष्टिकोन नाही.
विशेषतः वेब ऍप्लिकेशन्ससारख्या सॉफ्टवेअरसाठी, ज्यामध्ये उपयोगिता (usability) आणि व्हिज्युअल डिझाइन (visual design) यांसारख्या व्यक्तिनिष्ठ पैलूंचा समावेश असतो, ज्यांच्याशी थेट संवाद साधला जातो, तेव्हा मला जाणवले की सॉफ्टवेअर प्रत्यक्ष चालवून आणि त्याच्याशी संवाद साधणे हे सविस्तर चाचण्यांपेक्षा अधिक महत्त्वाचे आहे.
कारण, जर सॉफ्टवेअरशी संवाद साधल्यानंतर UI/UX स्तरावर (User Interface/User Experience) लक्षणीय असमाधान असेल, तर फ्रेमवर्क, मूलभूत आर्किटेक्चर, डेटा मॉडेल किंवा वापर प्रकरणे (use cases) यासारख्या मूलभूत भागांमध्ये बदल करण्याची शक्यता असते.
माझ्या सध्याच्या वैयक्तिक सॉफ्टवेअर विकास प्रकल्पात, मला वैशिष्ट्यांच्या लवचिकतेमध्ये (feature flexibility) आणि कार्यक्षमतेमध्ये (performance) समस्या आढळल्या आणि शेवटी मी दोन फ्रेमवर्क बदलून भिन्न वापरले.
कार्यक्षम नसलेल्या मेमरी वापरामुळे मला काही क्षेत्रांमध्ये प्रक्रियांचे पूर्णपणे पुनरावलोकन करावे लागले.
रिफॅक्टरिंगच्या (refactoring) याच क्षणांमध्ये चाचणीचा विचार प्रथम जागरूकपणे केला जातो.
जर हे विकासाच्या सुरुवातीच्या टप्प्यात असेल, किंवा कार्ये आणि वैशिष्ट्ये लक्षणीयरीत्या बदलणार असतील, तर चाचण्या अनावश्यक असू शकतात.
तथापि, जर विकास आधीच बराच प्रगत झाला असेल आणि तपासण्यासाठी अनेक गोष्टी असतील, तर रिफॅक्टरिंगमुळे कार्यात्मक दोष (functional defects) किंवा त्रुटी (omissions) आल्या नाहीत याची खात्री करण्यासाठी चाचण्या आवश्यक असतील.
म्हणून, जेव्हा विकास एका विशिष्ट मर्यादेपर्यंत प्रगती करतो आणि रिफॅक्टरिंग आवश्यक होते तेव्हा चाचणी प्रोग्राम तयार करण्याचा दृष्टिकोन वाईट नाही.
या टप्प्यावर, सर्व कोडसाठी चाचण्या तयार करणे महत्त्वाचे नाही, तर भविष्यात फारसा बदल होण्याची शक्यता नसलेल्या परिपक्व भागांच्या चाचणीवर लक्ष केंद्रित करणे महत्त्वाचे आहे, तर अस्थिर भागांना स्वयंचलित चाचण्यांशिवाय सोडून द्यावे.
याला रिफॅक्टरिंग-आधारित चाचणी (Refactoring-Driven Testing) असे म्हणता येईल.
निष्कर्ष
जनरेटिव्ह एआय सॉफ्टवेअर विकासात मोठे बदल घडवून आणत आहे.
माझ्या मागील एका लेखात, मी "ओम्नी-डायरेक्शनल इंजिनियर" (Omni-directional Engineer) बनण्याच्या महत्त्वाविषयी लिहिले होते, जो पारंपरिक फुल-स्टॅक इंजिनियरपेक्षा पुढे जाऊन विविध डोमेन, इन्फ्रास्ट्रक्चर्स आणि एक्झिक्यूशन एन्व्हायर्नमेंट्सना एकत्रित करून सिस्टिम्स विकसित करण्यास सक्षम असतो.
मी असाही एक लेख लिहिला होता ज्यात असे सुचवले होते की आपण "अनुभव आणि वर्तणूक-केंद्रित विकासाच्या" (Experience & Behavior-centric Development) युगात प्रवेश करत आहोत, जिथे लक्ष स्पेसिफिकेशन्सला अंमलबजावणीशी जुळवण्यावर नसून, सॉफ्टवेअरच्या वर्तणुकीद्वारे वापरकर्त्याचा अनुभव सुधारण्यावर आहे.
विकासाभिमुख विकास (Developmental development) आणि रिफॅक्टरिंग-आधारित चाचणी (refactoring-driven testing) हेच सॉफ्टवेअर विकासातील या नवीन क्षितिजांकडे घेऊन जातात.