8. گولڊن هامر
هڪ گولڊن هامر هڪ مخالف نمونو آهي جيڪو اعتماد سان بيان ڪيو ويو آهي ته هڪ خاص حل عالمي طور تي لاڳو ٿئي ٿو. مثال:-
ڪنهن مسئلي کي منهن ڏيڻ ۽ صحيح حل لاءِ هڪ نمونو ڳولڻ کان پوءِ، هڪ پروگرامر ڪوشش ڪندو آهي ته هن نموني کي هر جڳهه تي، ان کي موجوده ۽ مستقبل جي سڀني منصوبن تي لاڳو ڪري، مخصوص ڪيسن لاءِ مناسب حل ڳولڻ بدران.
-
ڪجهه ڊولپرز هڪ ڀيرو هڪ مخصوص صورتحال لاءِ ڪيش جو پنهنجو مختلف قسم ٺاهيو (ڇاڪاڻ ته ٻيو ڪجهه به مناسب نه هو). بعد ۾، ايندڙ پروجيڪٽ تي جنهن ۾ ڪا خاص ڪيش منطق شامل نه هئي، انهن تيار ڪيل لائبريرين (مثال طور، Ehcache). نتيجو اهو ٿيو ته ڪيئي بگاڙ ۽ ناانصافيون، گڏو گڏ تمام گهڻو وقت ضايع ۽ ٿڪيل اعصاب.
ڪو به ماڻهو هن مخالف نموني لاء گر ٿي سگهي ٿو. جيڪڏهن توهان شروعاتي آهيو، توهان شايد ڊزائن جي نمونن بابت ڄاڻ نه هوندا. اهو شايد توهان کي سڀني مسئلن کي حل ڪرڻ جي ڪوشش ڪري سگهي ٿو هڪ طريقي سان جيڪو توهان حاصل ڪيو آهي. جيڪڏهن اسان پروفيسر جي باري ۾ ڳالهائي رهيا آهيون، ته پوء اسين هن کي پروفيشنل خرابي يا nerdview سڏين ٿا. توھان وٽ توھان جي پنھنجي پسند جي ڊيزائن جا نمونا آھن، ۽ صحيح ھڪڙي استعمال ڪرڻ جي بدران، توھان پنھنجي پسنديده استعمال ڪريو، فرض ڪريو ته ماضي ۾ ھڪڙو سٺو فٽ مستقبل ۾ ساڳئي نتيجن جي ضمانت ڏئي ٿو.
اهو نقصان تمام ڏکوئيندڙ نتيجا پيدا ڪري سگهي ٿو - خراب، غير مستحڪم، ۽ عملدرآمد کي برقرار رکڻ ڏکيو کان وٺي منصوبي جي مڪمل ناڪامي تائين. جيئن سڀني بيمارين لاءِ ڪا به هڪ گولي ناهي، تيئن سڀني موقعن لاءِ ڪو هڪ نمونو ناهي.
9. وقت کان اڳ جي اصلاح
وقت کان اڳ واري اصلاح هڪ مخالف نموني آهي جنهن جو نالو پاڻ لاء ڳالهائيندو آهي.10. اسپگيٽي ڪوڊ
Spaghetti ڪوڊ ھڪڙو ضد نمونو آھي جيڪو ڪوڊ جي ذريعي بيان ڪيو ويو آھي جيڪو ناقص جوڙجڪ، مونجهارو، ۽ سمجھڻ ڏکيو آھي، جنھن ۾ سڀني قسمن جي برانچنگ شامل آھي، جھڙوڪ ريپنگ استثنا، حالتون ۽ لوپس. اڳي، گٽو آپريٽر هن مخالف نموني جي مکيه اتحادي هو. گوٽو بيان حقيقت ۾ هاڻي استعمال نه ڪيا ويا آهن، جيڪي خوشيء سان ڪيترن ئي لاڳاپيل مشڪلاتن ۽ مسئلن کي ختم ڪري ڇڏيندا آهن.
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. يو-يو مسئلو
yo -yo مسئلو هڪ مخالف نمونو آهي جنهن ۾ ايپليڪيشن جي جوڙجڪ تمام گهڻي پيچيدگي جي ڪري تمام گهڻو پيچيدو آهي (مثال طور، هڪ انتهائي ذيلي تقسيم وراثت جو سلسلو). "yo-yo مسئلو" تڏهن پيدا ٿئي ٿو جڏهن توهان کي هڪ پروگرام کي سمجهڻ جي ضرورت آهي جنهن جي وراثت واري درجه بندي ڊگھي ۽ پيچيده آهي، ٺاهيل طريقي سان ٺاهيل طريقي سان ڪالون. نتيجي طور، پروگرامرن کي پروگرام جي رويي کي معائنو ڪرڻ لاء ڪيترن ئي مختلف طبقن ۽ طريقن جي وچ ۾ نيويگيٽ ڪرڻ جي ضرورت آهي. هن مخالف نموني جو نالو رانديڪن جي نالي کان اچي ٿو. مثال طور، اچو ته ھيٺ ڏنل وراثت واري زنجير تي نظر رکون: اسان وٽ ٽيڪنالاجي انٽرفيس آھي.
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();
}
}
۽ ان جي مطابق، اسان وٽ ھي اينيم آھي:
public enum ServiceType {
CAR(),
USER(),
FILE(),
PLAN(),
CUSTOMER()
}
سڀ ڪجھ سادو ۽ سٺو لڳي ٿو... پر ٻين طريقن بابت ڇا؟ درحقيقت، انهن سڀني وٽ switch
بيانن جو هڪ گروپ ۽ تقريبن هڪجهڙائي واري ڊيٽابيس جي سوالن جو هڪ گروپ هوندو، جنهن جي نتيجي ۾ اسان جي طبقي کي تمام گهڻو پيچيدگي ۽ ڦهلائي ڇڏيندو. اهو سڀ ڪجهه ڪيئن آسان ٿي سگهي ٿو؟ اچو ته اسان جي اينوم کي ٿورو وڌايو:
@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