आम्ही याआधीच सिंगलटन ऑब्जेक्टच्या वापराचे पुनरावलोकन केले आहे, परंतु तुम्हाला अद्याप हे समजले नाही की ही रणनीती एक डिझाइन पॅटर्न आहे आणि त्यात सर्वात जास्त वापरली जाणारी एक आहे.

खरं तर, यापैकी बरेच नमुने आहेत आणि ते त्यांच्या विशिष्ट हेतूनुसार वर्गीकृत केले जाऊ शकतात.

नमुना वर्गीकरण

नमुना प्रकार अर्ज
सर्जनशील ऑब्जेक्ट निर्मिती समस्येचे निराकरण करणारा प्रकार
स्ट्रक्चरल नमुने जे आम्हाला आमच्या आर्किटेक्चरमध्ये योग्य आणि विस्तारित वर्ग पदानुक्रम तयार करू देतात
वर्तणूक पॅटर्नचा हा क्लस्टर प्रोग्राममधील ऑब्जेक्ट्समधील सुरक्षित आणि सोयीस्कर परस्परसंवाद सुलभ करतो.

सामान्यतः, एक नमुना तो सोडवलेल्या समस्येद्वारे दर्शविला जातो. जावा सोबत काम करताना आम्हाला बर्‍याचदा आढळणाऱ्या काही नमुन्यांवर एक नजर टाकूया:

नमुना उद्देश
सिंगलटन आम्‍ही या पॅटर्नशी आधीच परिचित आहोत — आम्‍ही याचा वापर वर्ग तयार करण्‍यासाठी आणि प्रवेश करण्‍यासाठी करतो ज्यात एकापेक्षा जास्त उदाहरणे असू शकत नाहीत.
पुनरावृत्ती करणारा आम्ही देखील या एक परिचित आहेत. आम्हाला माहित आहे की हा पॅटर्न आम्हाला कलेक्शन ऑब्जेक्टवर त्याचे अंतर्गत प्रतिनिधित्व न उघडता पुनरावृत्ती करू देतो. हे संग्रहासह वापरले जाते.
अडॅप्टर हा नमुना विसंगत वस्तूंना जोडतो जेणेकरून ते एकत्र काम करू शकतील. मला वाटते की अॅडॉप्टर पॅटर्नचे नाव आपल्याला हे नक्की काय करते याची कल्पना करण्यात मदत करते. वास्तविक जीवनातील एक साधे उदाहरण येथे आहे: वॉल आउटलेटसाठी यूएसबी अडॅप्टर.
टेम्पलेट पद्धत

एक वर्तनात्मक प्रोग्रामिंग पॅटर्न जो एकीकरण समस्येचे निराकरण करतो आणि आपल्याला अल्गोरिदमची रचना न बदलता अल्गोरिदमिक चरण बदलण्याची परवानगी देतो.

अशी कल्पना करा की आमच्याकडे असेंबली चरणांच्या क्रमानुसार कार असेंब्ली अल्गोरिदम आहे:

चेसिस -> बॉडी -> इंजिन -> केबिन इंटीरियर

जर आपण प्रबलित फ्रेम, अधिक शक्तिशाली इंजिन किंवा अतिरिक्त प्रकाशासह इंटीरियर लावले तर आपल्याला अल्गोरिदम बदलण्याची गरज नाही आणि अमूर्त क्रम सारखाच राहतो.

डेकोरेटर हा नमुना वस्तूंना उपयुक्त कार्यक्षमता देण्यासाठी रॅपर तयार करतो. आम्ही या लेखाचा एक भाग म्हणून विचार करू.

Java.io मध्ये, खालील वर्ग नमुने लागू करतात:

नमुना तो java.io मध्ये कुठे वापरला जातो
अडॅप्टर
टेम्पलेट पद्धत
डेकोरेटर

डेकोरेटर नमुना

चला कल्पना करूया की आम्ही घराच्या डिझाइनसाठी मॉडेलचे वर्णन करत आहोत.

सर्वसाधारणपणे, दृष्टीकोन असे दिसते:

सुरुवातीला, आमच्याकडे अनेक प्रकारच्या घरांची निवड आहे. किमान कॉन्फिगरेशन छतासह एक मजला आहे. मग आम्ही अतिरिक्त पॅरामीटर्स बदलण्यासाठी सर्व प्रकारचे डेकोरेटर वापरतो, ज्याचा नैसर्गिकरित्या घराच्या किंमतीवर परिणाम होतो.

आम्ही एक अमूर्त हाऊस वर्ग तयार करतो:

public abstract class House {
	String info;

	public String getInfo() {
    	return info;
	}

	public abstract int getPrice();
}

येथे आमच्याकडे 2 पद्धती आहेत:

  • getInfo() आमच्या घराचे नाव आणि वैशिष्ट्यांबद्दल माहिती देते;
  • getPrice() सध्याच्या घराच्या कॉन्फिगरेशनची किंमत परत करते.

आमच्याकडे मानक गृह अंमलबजावणी देखील आहे - वीट आणि लाकडी:

public class BrickHouse extends House {

	public BrickHouse() {
    	info = "Brick House";
	}

	@Override
	public int getPrice() {
    	return 20_000;
	}
}

public class WoodenHouse extends House {

	public WoodenHouse() {
    	info = "Wooden House";
	}

	@Override
	public int getPrice() {
    	return 25_000;
	}
}

दोन्ही वर्ग हाऊस क्लासचा वारसा घेतात आणि मानक घरासाठी सानुकूल किंमत सेट करून त्याची किंमत पद्धत ओव्हरराइड करतात. आम्ही कन्स्ट्रक्टरमध्ये नाव सेट करतो.

पुढे, आपल्याला डेकोरेटरचे वर्ग लिहावे लागतील. या वर्गांना हाऊस क्लासचा वारसाही मिळेल . हे करण्यासाठी, आम्ही एक अमूर्त डेकोरेटर वर्ग तयार करतो.

तिथेच आपण ऑब्जेक्ट बदलण्यासाठी अतिरिक्त तर्क लावू. सुरुवातीला, कोणतेही अतिरिक्त तर्क नसतील आणि अमूर्त वर्ग रिक्त असेल.

abstract class HouseDecorator extends House {
}

पुढे, आम्ही डेकोरेटर अंमलबजावणी तयार करतो. आम्ही अनेक वर्ग तयार करू जे आम्हाला घरामध्ये अतिरिक्त वैशिष्ट्ये जोडू द्या:

public class SecondFloor extends HouseDecorator {
	House house;

	public SecondFloor(House house) {
    	this.house = house;
	}

	@Override
	public int getPrice() {
    	return house.getPrice() + 20_000;
	}

	@Override
	public String getInfo() {
    	return house.getInfo() + " + second floor";
	}
}
आमच्या घराला दुसरा मजला जोडणारा डेकोरेटर

डेकोरेटर कन्स्ट्रक्टर घर स्वीकारतो जे आम्ही "सजवतो", म्हणजे बदल जोडू. आणि आम्ही getPrice() आणि getInfo() पद्धती ओव्हरराइड करतो, जुन्या घरावर आधारित नवीन अपडेट केलेल्या घराची माहिती देतो.

public class Garage extends HouseDecorator {

	House house;
	public Garage(House house) {
    	this.house = house;
	}

	@Override
	public int getPrice() {
    	return house.getPrice() + 5_000;
	}

	@Override
	public String getInfo() {
    	return house.getInfo() + " + garage";
	}
}
एक डेकोरेटर जो आमच्या घराला गॅरेज जोडतो

आता आम्ही आमचे घर डेकोरेटर्ससह अपडेट करू शकतो. हे करण्यासाठी, आम्हाला एक घर तयार करण्याची आवश्यकता आहे:

House brickHouse = new BrickHouse();

पुढे, आम्ही आमचे सेटघरनवीन डेकोरेटरच्या बरोबरीचे व्हेरिएबल, आमच्या घरात जात आहे:

brickHouse = new SecondFloor(brickHouse);

आमचेघरव्हेरिएबल आता दुसरा मजला असलेले घर आहे.

डेकोरेटर्सचा वापर करणारी प्रकरणे पाहू:

उदाहरण कोड आउटपुट
House brickHouse = new BrickHouse();

  System.out.println(brickHouse.getInfo());
  System.out.println(brickHouse.getPrice());

विटांचे घर

20000

House brickHouse = new BrickHouse();

  brickHouse = new SecondFloor(brickHouse);

  System.out.println(brickHouse.getInfo());
  System.out.println(brickHouse.getPrice());

वीट घर + दुसरा मजला

40000

House brickHouse = new BrickHouse();


  brickHouse = new SecondFloor(brickHouse);
  brickHouse = new Garage(brickHouse);

  System.out.println(brickHouse.getInfo());
  System.out.println(brickHouse.getPrice());

वीट घर + दुसरा मजला + गॅरेज

45000

House woodenHouse = new SecondFloor(new Garage(new WoodenHouse()));

  System.out.println(woodenHouse.getInfo());
  System.out.println(woodenHouse.getPrice());

लाकडी घर + गॅरेज + दुसरा मजला

50000

House woodenHouse = new WoodenHouse();

  House woodenHouseWithGarage = new Garage(woodenHouse);

  System.out.println(woodenHouse.getInfo());
  System.out.println(woodenHouse.getPrice());

  System.out.println(woodenHouseWithGarage.getInfo());
  System.out.println(woodenHouseWithGarage.getPrice());

लाकडी घर

२५०००

लाकडी घर + गॅरेज

30000

हे उदाहरण डेकोरेटरसह ऑब्जेक्ट अपग्रेड करण्याचा फायदा स्पष्ट करते. म्हणून आम्ही बदलले नाहीलाकडी घरऑब्जेक्ट स्वतः, परंतु त्याऐवजी जुन्यावर आधारित नवीन ऑब्जेक्ट तयार केला. येथे आपण पाहू शकतो की फायद्यांसह तोटे देखील येतात: आम्ही प्रत्येक वेळी मेमरीमध्ये एक नवीन ऑब्जेक्ट तयार करतो, मेमरी वापर वाढवतो.

आमच्या प्रोग्रामचा हा UML आकृती पहा:

डेकोरेटरमध्ये एक अतिशय सोपी अंमलबजावणी असते आणि ते डायनॅमिकरित्या बदलते, त्यांना अपग्रेड करते. डेकोरेटर त्यांच्या कन्स्ट्रक्टरद्वारे ओळखले जाऊ शकतात, जे सध्याच्या वर्गाप्रमाणे समान अमूर्त प्रकार किंवा इंटरफेसचे पॅरामीटर्स ऑब्जेक्ट्स म्हणून घेतात. Java मध्ये, हा नमुना I/O वर्गांमध्ये मोठ्या प्रमाणावर वापरला जातो.

उदाहरणार्थ, आम्ही आधीच नमूद केल्याप्रमाणे, java.io.InputStream , OutputStream , Reader आणि Writer च्या सर्व उपवर्गांमध्ये एक कन्स्ट्रक्टर असतो जो समान वर्गांच्या वस्तू स्वीकारतो.