8. गोल्डन हातोडा
सोनेरी हातोडा हा एक विशिष्ट उपाय सार्वत्रिकपणे लागू आहे या विश्वासाने परिभाषित केलेला विरोधी नमुना आहे. उदाहरणे:-
एखाद्या समस्येचा सामना केल्यानंतर आणि परिपूर्ण समाधानासाठी नमुना शोधल्यानंतर, प्रोग्रामर विशिष्ट प्रकरणांसाठी योग्य उपाय शोधण्याऐवजी, वर्तमान आणि भविष्यातील सर्व प्रकल्पांवर लागू करून, सर्वत्र हा नमुना चिकटवण्याचा प्रयत्न करतो.
-
काही विकासकांनी एकदा विशिष्ट परिस्थितीसाठी कॅशेचे स्वतःचे प्रकार तयार केले (कारण दुसरे काहीही योग्य नव्हते). नंतर, पुढील प्रकल्पात ज्यामध्ये विशेष कॅशे लॉजिक समाविष्ट नव्हते, त्यांनी तयार लायब्ररी (उदाहरणार्थ, Ehcache) वापरण्याऐवजी त्यांचे प्रकार पुन्हा वापरले. परिणामी बग आणि विसंगतींचा समूह, तसेच बराच वेळ वाया गेला आणि नसा तळल्या गेल्या.
या विरोधी पॅटर्नला कोणीही पडू शकते. तुम्ही नवशिक्या असल्यास, तुम्हाला डिझाइन पॅटर्नबद्दल माहिती नसेल. हे तुम्हाला सर्व समस्यांचे निराकरण करण्याचा प्रयत्न करण्यास प्रवृत्त करू शकते ज्या पद्धतीने तुम्ही प्रभुत्व मिळवले आहे. जर आपण व्यावसायिकांबद्दल बोलत आहोत, तर आम्ही याला व्यावसायिक विकृती किंवा नर्डव्ह्यू म्हणतो. तुमच्याकडे तुमचे स्वतःचे पसंतीचे डिझाईन नमुने आहेत आणि योग्य नमुने वापरण्याऐवजी, तुम्ही तुमचे आवडते वापरता, असे गृहीत धरून की भूतकाळातील योग्य तंदुरुस्त भविष्यात समान परिणामाची हमी देते.
ही अडचण अतिशय दुःखद परिणाम देऊ शकते — वाईट, अस्थिर आणि अंमलबजावणी टिकवून ठेवण्यास कठीण ते प्रकल्पाच्या पूर्ण अपयशापर्यंत. ज्याप्रमाणे सर्व रोगांसाठी एकच गोळी नाही, त्याचप्रमाणे सर्व प्रसंगांसाठी एकच रचना नाही.
9. अकाली ऑप्टिमायझेशन
अकाली ऑप्टिमायझेशन एक विरोधी नमुना आहे ज्याचे नाव स्वतःसाठी बोलते.10. स्पेगेटी कोड
स्पेगेटी कोड हा कोड द्वारे परिभाषित केलेला अँटी-पॅटर्न आहे जो खराब संरचित, गोंधळात टाकणारा आणि समजण्यास कठिण आहे, ज्यामध्ये सर्व प्रकारच्या शाखा आहेत, जसे की रॅपिंग अपवाद, परिस्थिती आणि लूप. पूर्वी, गोटो ऑपरेटर हा या अँटी-पॅटर्नचा मुख्य सहयोगी होता. गोटो विधाने यापुढे वापरली जात नाहीत, ज्यामुळे अनेक संबंधित अडचणी आणि समस्या आनंदाने दूर होतात.
public boolean someDifficultMethod(List<String> XMLAttrList) {
...
int prefix = stringPool.getPrefixForQName(elementType);
int elementURI;
try {
if (prefix == -1) {
...
if (elementURI != -1) {
stringPool.setURIForQName(...);
}
} else {
...
if (elementURI == -1) {
...
}
}
} catch (Exception e) {
return false;
}
if (attrIndex != -1) {
int index = attrList.getFirstAttr(attrIndex);
while (index != -1) {
int attName = attrList.getAttrName(index);
if (!stringPool.equalNames(...)){
...
if (attPrefix != namespacesPrefix) {
if (attPrefix == -1) {
...
} else {
if (uri == -1) {
...
}
stringPool.setURIForQName(attName, uri);
...
}
if (elementDepth >= 0) {
...
}
elementDepth++;
if (elementDepth == fElementTypeStack.length) {
...
}
...
return contentSpecType == fCHILDRENSymbol;
}
}
}
}
}
हे भयानक दिसते, नाही का? दुर्दैवाने, हा सर्वात सामान्य अँटी-पॅटर्न आहे :( असा कोड लिहिणाऱ्या व्यक्तीला देखील भविष्यात तो समजू शकणार नाही. कोड पाहणारे इतर विकासक विचार करतील, "ठीक आहे, जर ते कार्य करत असेल तर ठीक आहे — त्याला हात न लावणे चांगले आहे." बर्याचदा, पद्धत सुरुवातीला सोपी आणि अतिशय पारदर्शक असते, परंतु नवीन आवश्यकता जोडल्या गेल्यामुळे, पद्धत हळूहळू अधिकाधिक सशर्त विधानांनी जोडली जाते आणि तिला अशा प्रकारे राक्षसी बनवते. जर अशी पद्धत दिसते, तुम्हाला ते पूर्णपणे किंवा कमीतकमी सर्वात गोंधळात टाकणारे भाग रिफॅक्टर करणे आवश्यक आहे. सामान्यतः, प्रोजेक्ट शेड्यूल करताना, रिफॅक्टरिंगसाठी वेळ दिला जातो, उदाहरणार्थ, स्प्रिंट वेळेच्या 30% रिफॅक्टरिंग आणि चाचण्यांसाठी. अर्थात, हे गृहीत धरते की तिथे गर्दी नसते (पण असे कधी होते).येथे _
11. जादूची संख्या
मॅजिक नंबर्स हा एक अँटी-पॅटर्न आहे ज्यामध्ये सर्व प्रकारचे स्थिरांक त्यांच्या उद्देश किंवा अर्थाचे कोणतेही स्पष्टीकरण न देता प्रोग्राममध्ये वापरले जातात. म्हणजेच, त्यांना सामान्यतः खराब नाव दिले जाते किंवा अत्यंत प्रकरणांमध्ये, टिप्पण्या काय आहेत किंवा का आहेत हे स्पष्ट करणारी कोणतीही टिप्पणी नाही. स्पॅगेटी कोड प्रमाणे, हे सर्वात सामान्य अँटी-नमुन्यांपैकी एक आहे. ज्याने कोड लिहिला नाही त्याला जादुई संख्यांबद्दल किंवा ते कसे कार्य करतात याबद्दल काही सुगावा असू शकतो किंवा नसू शकतो (आणि कालांतराने, लेखक स्वत: त्यांना समजावून सांगू शकणार नाही). परिणामी, नंबर बदलणे किंवा काढून टाकल्याने कोड जादूने सर्व एकत्र काम करणे थांबवतो. उदाहरणार्थ, 36 आणि 73. या अँटी-पॅटर्नचा सामना करण्यासाठी, मी कोड पुनरावलोकनाची शिफारस करतो. कोडच्या संबंधित विभागांमध्ये सहभागी नसलेल्या विकसकांनी तुमचा कोड पाहिला जाणे आवश्यक आहे. त्यांचे डोळे ताजे असतील आणि त्यांना प्रश्न असतील: हे काय आहे आणि तुम्ही असे का केले? आणि नक्कीच, आपल्याला स्पष्टीकरणात्मक नावे वापरण्याची किंवा टिप्पण्या सोडण्याची आवश्यकता आहे.12. कॉपी आणि पेस्ट प्रोग्रामिंग
कॉपी-अँड-पेस्ट प्रोग्रामिंग एक अँटी-पॅटर्न आहे ज्यामध्ये एखाद्याचा कोड विचारहीनपणे कॉपी आणि पेस्ट केला जातो, ज्यामुळे कदाचित अनपेक्षित दुष्परिणाम होतात. उदाहरणार्थ, गणितीय गणना किंवा जटिल अल्गोरिदमसह कॉपी आणि पेस्ट करण्याच्या पद्धती ज्या आम्हाला पूर्णपणे समजत नाहीत. हे आमच्या विशिष्ट प्रकरणासाठी कार्य करू शकते, परंतु इतर काही परिस्थितींमध्ये ते त्रास देऊ शकते. समजा मला अॅरेमधील कमाल संख्या निश्चित करण्यासाठी पद्धत हवी आहे. इंटरनेटच्या सभोवताली गोंधळ घालताना मला हा उपाय सापडला:
public static int max(int[] array) {
int max = 0;
for(int i = 0; i < array.length; i++) {
if (Math.abs(array[i]) > max){
max = array[i];
}
}
return max;
}
आम्हाला 3, 6, 1, 4, आणि 2 या आकड्यांचा अॅरे मिळतो आणि पद्धत 6 देते. छान, चला ते ठेवूया! पण नंतर आपल्याला 2.5, -7, 2, आणि 3 असलेली एक अॅरे मिळेल आणि नंतर आपला परिणाम -7 असेल. आणि हा परिणाम चांगला नाही. येथे समस्या अशी आहे की Math.abs() परिपूर्ण मूल्य परत करते. याकडे दुर्लक्ष केल्याने आपत्ती येते, परंतु केवळ विशिष्ट परिस्थितींमध्ये. समाधानाच्या सखोल आकलनाशिवाय, अशी अनेक प्रकरणे आहेत जी तुम्ही सत्यापित करू शकणार नाही. कॉपी केलेला कोड देखील अनुप्रयोगाच्या अंतर्गत संरचनेच्या पलीकडे जाऊ शकतो, शैलीत्मक आणि अधिक मूलभूत, आर्किटेक्चरल स्तरावर. असा कोड वाचणे आणि राखणे अधिक कठीण होईल. आणि अर्थातच, आपण हे विसरू नये की दुसऱ्याच्या कोडची सरळ कॉपी करणे हा एक विशेष प्रकारचा चोरी आहे.
13. चाक पुन्हा शोधणे
चाक पुन्हा शोधणे हा अँटी-पॅटर्न आहे, ज्याला कधीकधी स्क्वेअर व्हील पुन्हा शोधणे असेही म्हणतात. थोडक्यात, हा साचा वर विचारात घेतलेल्या कॉपी-पेस्ट-विरोधी पॅटर्नच्या विरुद्ध आहे. या अँटी-पॅटर्नमध्ये, विकसक स्वतःच्या त्याच्या समस्येसाठी त्याच्या सोल्यूशनची अंमलबजावणी करतो जिच्यासाठी उपाय आधीच अस्तित्त आहेत. काहीवेळा हे विद्यमान उपाय प्रोग्रामरच्या शोधापेक्षा चांगले असतात. बर्याचदा, यामुळे वेळ गमावला जातो आणि उत्पादकता कमी होते: प्रोग्रामरला अजिबात उपाय सापडत नाही किंवा सर्वोत्तम उपाय शोधू शकत नाही. असे म्हटले आहे की, आम्ही स्वतंत्र समाधान तयार करण्याची शक्यता नाकारू शकत नाही, कारण असे करणे म्हणजे कॉपी आणि पेस्ट प्रोग्रामिंगचा थेट मार्ग आहे. प्रोग्रामरला विशिष्ट प्रोग्रॅमिंग कार्यांद्वारे मार्गदर्शन केले पाहिजे जे सक्षमपणे सोडवण्याकरता उद्भवतात, मग ते तयार समाधान वापरून किंवा सानुकूल उपाय तयार करून. खूप वेळा, हा अँटी-पॅटर्न वापरण्याचे कारण फक्त घाई आहे. याचा परिणाम म्हणजे रेडीमेड सोल्यूशन्सचे (शोध) उथळ विश्लेषण. स्क्वेअर व्हील पुन्हा शोधणे हे एक प्रकरण आहे जेथे विचाराधीन अँटी-पॅटर्नचा नकारात्मक परिणाम होतो. म्हणजेच, प्रकल्पाला सानुकूल समाधान आवश्यक आहे, आणि विकसक ते तयार करतो, परंतु वाईटरित्या. त्याच वेळी, एक चांगला पर्याय आधीपासूनच अस्तित्वात आहे आणि इतर ते यशस्वीरित्या वापरत आहेत. तळ ओळ: बराच वेळ गमावला आहे. प्रथम, आम्ही असे काहीतरी तयार करतो जे कार्य करत नाही. मग आम्ही ते रिफॅक्टर करण्याचा प्रयत्न करतो आणि शेवटी आम्ही ते आधीपासून अस्तित्वात असलेल्या एखाद्या गोष्टीने बदलतो. एक उदाहरण म्हणजे तुमची स्वतःची सानुकूल कॅशे अंमलात आणणे जेव्हा भरपूर अंमलबजावणी आधीच अस्तित्वात असते. प्रोग्रामर म्हणून तुम्ही कितीही हुशार असलात, तरी तुम्ही हे लक्षात ठेवायला हवे की स्क्वेअर व्हील पुन्हा शोधणे हा किमान वेळेचा अपव्यय आहे. आणि, जसे तुम्हाला माहिती आहे, वेळ हा सर्वात मौल्यवान स्त्रोत आहे.14. यो-यो समस्या
यो -यो समस्या ही एक अँटी-पॅटर्न आहे ज्यामध्ये अत्याधिक विखंडन (उदाहरणार्थ, जास्त प्रमाणात उपविभाजित इनहेरिटेन्स चेन) मुळे ऍप्लिकेशनची रचना जास्त क्लिष्ट आहे. "यो-यो समस्या" उद्भवते जेव्हा तुम्हाला एखादा प्रोग्राम समजून घेण्याची आवश्यकता असते ज्याचा वारसा श्रेणीक्रम लांब आणि गुंतागुंतीचा असतो, ज्यामुळे खोलवर नेस्टेड मेथड कॉल तयार होतात. परिणामी, प्रोग्रामच्या वर्तनाची तपासणी करण्यासाठी प्रोग्रामरना अनेक भिन्न वर्ग आणि पद्धतींमध्ये नेव्हिगेट करणे आवश्यक आहे. या अँटी-पॅटर्नचे नाव टॉयच्या नावावरून आले आहे. उदाहरण म्हणून, खालील वारसा साखळी पाहू: आमच्याकडे एक तंत्रज्ञान इंटरफेस आहे:
public interface Technology {
void turnOn();
}
ट्रान्सपोर्ट इंटरफेसला त्याचा वारसा मिळतो:
public interface Transport extends Technology {
boolean fillUp();
}
आणि मग आमच्याकडे दुसरा इंटरफेस आहे, ग्राउंड ट्रान्सपोर्ट:
public interface GroundTransportation extends Transport {
void startMove();
void brake();
}
आणि तिथून, आम्ही एक अमूर्त कार वर्ग मिळवतो:
public abstract class Car implements GroundTransportation {
@Override
public boolean fillUp() {
/* some implementation */
return true;
}
@Override
public void turnOn() {
/* some implementation */
}
public boolean openTheDoor() {
/* some implementation */
return true;
}
public abstract void fixCar();
}
पुढील अमूर्त फोक्सवॅगन वर्ग आहे:
public abstract class Volkswagen extends Car {
@Override
public void startMove() {
/* some implementation */
}
@Override
public void brake() {
/* some implementation */
}
}
आणि शेवटी, एक विशिष्ट मॉडेल:
public class VolkswagenAmarok extends Volkswagen {
@Override
public void fixCar(){
/* some implementation */
}
}
ही साखळी आम्हाला यासारख्या प्रश्नांची उत्तरे शोधण्यास भाग पाडते:
-
किती पद्धती आहेत
VolkswagenAmarok
? -
जास्तीत जास्त अमूर्तता प्राप्त करण्यासाठी प्रश्नचिन्हाच्या ऐवजी कोणता प्रकार घातला पाहिजे:
? someObj = new VolkswagenAmarok(); someObj.brake();
15. अपघाती गुंतागुंत
अनावश्यक गुंतागुंत हा एक विरोधी नमुना आहे ज्यामध्ये अनावश्यक गुंतागुंत समाधानासाठी सादर केली जाते.
public void createDescriptionForElement(ServiceType type, Long languageId, Long serviceId, String description)throws Exception {
switch (type){
case CAR:
jdbcTemplate.update(CREATE_RELATION_WITH_CAR, languageId, serviceId, description);
case USER:
jdbcTemplate.update(CREATE_RELATION_WITH_USER, languageId, serviceId, description);
case FILE:
jdbcTemplate.update(CREATE_RELATION_WITH_FILE, languageId, serviceId, description);
case PLAN:
jdbcTemplate.update(CREATE_RELATION_WITH_PLAN, languageId, serviceId, description);
case CUSTOMER:
jdbcTemplate.update(CREATE_RELATION_WITH_CUSTOMER, languageId, serviceId, description);
default:
throw new Exception();
}
}
आणि त्यानुसार, आमच्याकडे हे enum आहे:
public enum ServiceType {
CAR(),
USER(),
FILE(),
PLAN(),
CUSTOMER()
}
सर्व काही सोपे आणि चांगले आहे असे दिसते... परंतु इतर पद्धतींचे काय? switch
खरंच, त्या सर्वांकडे विधानांचा एक समूह आणि जवळजवळ एकसारख्या डेटाबेस प्रश्नांचा एक समूह देखील असेल , ज्यामुळे आमचा वर्ग मोठ्या प्रमाणात गुंतागुंतीचा आणि फुगवला जाईल. हे सर्व कसे सोपे केले जाऊ शकते? चला आमचे enum थोडे अपग्रेड करूया:
@Getter
@AllArgsConstructor
public enum ServiceType {
CAR("cars_descriptions", "car_id"),
USER("users_descriptions", "user_id"),
FILE("files_descriptions", "file_id"),
PLAN("plans_descriptions", "plan_id"),
CUSTOMER("customers_descriptions", "customer_id");
private String tableName;
private String columnName;
}
आता प्रत्येक प्रकाराला त्याच्या सारणीच्या मूळ फील्डची नावे आहेत. परिणामी, वर्णन तयार करण्याची पद्धत बनते:
private static final String CREATE_RELATION_WITH_SERVICE = "INSERT INTO %s(language_id, %s, description) VALUES (?, ?, ?)";
public void createDescriptionForElement(ServiceType type, Long languageId, Long serviceId, String description) {
jdbcTemplate.update(String.format(CREATE_RELATION_WITH_SERVICE, type.getTableName(), type.getColumnName()), languageId, serviceId, description);
}
सोयीस्कर, साधे आणि संक्षिप्त, तुम्हाला वाटत नाही का? चांगल्या डेव्हलपरचे संकेत तो किंवा ती किती वेळा पॅटर्न वापरतो हे नाही, तर तो किंवा ती किती वेळा अँटी-पॅटर्न टाळतो. अज्ञान हा सर्वात वाईट शत्रू आहे, कारण आपल्याला आपल्या शत्रूंना दृष्टीने ओळखणे आवश्यक आहे. बरं, आज माझ्याकडे एवढंच आहे. धन्यवाद, प्रत्येकजण! :)
GO TO FULL VERSION