├── Lecture 11 ├── UML.png ├── Java Code │ └── Tomato │ │ ├── strategies │ │ ├── PaymentStrategy.java │ │ ├── UpiPaymentStrategy.java │ │ └── CreditCardPaymentStrategy.java │ │ ├── factories │ │ ├── OrderFactory.java │ │ ├── NowOrderFactory.java │ │ └── ScheduledOrderFactory.java │ │ ├── utils │ │ └── TimeUtils.java │ │ ├── models │ │ ├── DeliveryOrder.java │ │ ├── PickupOrder.java │ │ ├── User.java │ │ ├── MenuItem.java │ │ ├── Restaurant.java │ │ ├── Cart.java │ │ └── Order.java │ │ ├── folderStructure.txt │ │ ├── managers │ │ ├── OrderManager.java │ │ └── RestaurantManager.java │ │ ├── services │ │ └── NotificationService.java │ │ └── Main.java └── C++ Code │ └── Tomato │ ├── strategies │ ├── PaymentStrategy.h │ ├── UpiPaymentStrategy.h │ └── CreditCartPaymentStrategy.h │ ├── utils │ └── TimeUtils.h │ ├── factories │ ├── OrderFactory.h │ ├── NowOrderFactory.h │ └── ScheduledOrderFactory.h │ ├── models │ ├── DeliveryOrder.h │ ├── PickupOrder.h │ ├── MenuItem.h │ ├── User.h │ ├── Cart.h │ ├── Restaurant.h │ └── Order.h │ ├── folderStructure.txt │ ├── managers │ ├── OrderManager.h │ └── RestaurantManager.h │ ├── services │ └── NotificationService.h │ └── main.cpp ├── Lecture 14 └── UML.jpeg ├── Lecture 18 ├── UML.pdf ├── C++ Code │ └── MusicPlayerSystem │ │ └── MusicPlayerApplication │ │ ├── enums │ │ ├── DeviceType.hpp │ │ └── PlayStrategyType.hpp │ │ ├── device │ │ ├── IAudioOutputDevice.hpp │ │ ├── WiredSpeakerAdapter.hpp │ │ ├── HeadphonesAdapter.hpp │ │ └── BluetoothSpeakerAdapter.hpp │ │ ├── external │ │ ├── HeadphonesAPI.hpp │ │ ├── WiredSpeakerAPI.hpp │ │ └── BluetoothSpeakerAPI.hpp │ │ ├── strategies │ │ ├── PlayStrategy.hpp │ │ ├── SequentialPlayStrategy.hpp │ │ └── RandomPlayStrategy.hpp │ │ ├── models │ │ ├── Song.hpp │ │ └── Playlist.hpp │ │ ├── factories │ │ └── DeviceFactory.hpp │ │ ├── managers │ │ ├── StrategyManager.hpp │ │ ├── PlaylistManager.hpp │ │ └── DeviceManager.hpp │ │ ├── folderstructure.txt │ │ ├── core │ │ └── AudioEngine.hpp │ │ └── main.cpp └── Java Code │ └── MusicPlayerSystem │ └── MusicPlayerApplication │ ├── enums │ ├── DeviceType.java │ └── PlayStrategyType.java │ ├── device │ ├── IAudioOutputDevice.java │ ├── HeadphonesAdapter.java │ ├── WiredSpeakerAdapter.java │ └── BluetoothSpeakerAdapter.java │ ├── external │ ├── HeadphonesAPI.java │ ├── WiredSpeakerAPI.java │ └── BluetoothSpeakerAPI.java │ ├── strategies │ ├── PlayStrategy.java │ ├── SequentialPlayStrategy.java │ └── RandomPlayStrategy.java │ ├── models │ ├── Song.java │ └── Playlist.java │ ├── factories │ └── DeviceFactory.java │ ├── managers │ ├── StrategyManager.java │ ├── PlaylistManager.java │ └── DeviceManager.java │ ├── folderStructure.txt │ └── core │ └── AudioEngine.java ├── Lecture 26 └── UML.jpeg ├── Lecture 27 └── UML.jpeg ├── Lecture 31 ├── UML.jpeg ├── Requirements.jpeg └── Simplify Transactions.jpeg ├── Lecture 33 └── UML.jpeg ├── Lecture 34 └── UML.jpeg ├── Lecture 37 └── UML.jpeg ├── Lecture 01 └── Notes.pdf ├── Lecture 02 └── Notes.pdf ├── Lecture 03 ├── notes.pdf ├── C++ Code │ └── StaticPolymorphism.cpp └── Java Code │ └── StaticPolymorphism.java ├── Lecture 04 └── notes.pdf ├── Lecture 06 ├── notes.pdf ├── C++ Code │ ├── LSP-Rules │ │ ├── SingatureRules │ │ │ ├── MethodArgumentRule.cpp │ │ │ ├── ReturnTypeRule.cpp │ │ │ └── ExceptionRule.cpp │ │ ├── MethodRules │ │ │ ├── PreConditions.cpp │ │ │ └── PostConditions.cpp │ │ └── PropertiesRules │ │ │ ├── ClassInvariants.cpp │ │ │ └── HistoryConstraint.cpp │ ├── DIP │ │ ├── DIP_violated.cpp │ │ └── DIP_followed.cpp │ └── ISP │ │ ├── ISP_followed.cpp │ │ └── ISP_violated.cpp └── Java Code │ ├── LSP-Rules │ ├── SingatureRules │ │ ├── MethodArgumentRule.java │ │ ├── ReturnTypeRule.java │ │ └── ExceptionRule.java │ ├── MethodRules │ │ ├── PreConditions.java │ │ └── PostConditions.java │ └── PropertiesRules │ │ ├── ClassInvariants.java │ │ └── HistoryConstraint.java │ ├── DIP │ ├── DIPViolated.java │ └── DIPFollowed.java │ └── ISP │ ├── ISPFollowed.java │ └── ISPViolated.java ├── Lecture 40 └── Notes.pdf ├── Lecture 07 ├── standardUml.png ├── C++ Code │ └── BadDesign │ │ └── DocumentEditor.cpp └── Java Code │ └── Bad Design │ └── DocumentEditorClient.java ├── Lecture 08 └── Standard UML.png ├── Lecture 12 ├── Standard UML.jpg └── Java Code │ └── ObserverDesignPattern.java ├── Lecture 15 ├── Example UML.jpg └── Standard UML.jpg ├── Lecture 16 ├── Example UML.jpeg ├── Standard UML.jpeg ├── Java Code │ └── AdapterPattern.java └── C++ Code │ └── AdpaterPattern.cpp ├── Lecture 17 ├── Example UML.jpeg ├── Standard UML.jpeg ├── C++ Code │ └── FacadePattern.cpp └── Java Code │ └── FacadePattern.java ├── Lecture 19 ├── Example UML.jpeg └── Standard UML.jpeg ├── Lecture 21 ├── Proxy Notes.pdf ├── Java Code │ ├── VirtualProxy.java │ ├── RemoteProxy.java │ └── ProtectionProxy.java └── C++ Code │ ├── RemoteProxy.cpp │ ├── VirtualProxy.cpp │ └── ProtectionProxy.cpp ├── Lecture 23 └── Notes │ ├── UML.jpeg │ └── Requirements.jpeg ├── Lecture 24 └── Notes │ ├── UML.jpeg │ └── Requirements.jpeg ├── Lecture 29 ├── Example UML.jpeg └── Standard UML.jpeg ├── Lecture 32 ├── Example UML.jpeg ├── Standard UML.jpeg └── StateMachineDiagram.jpeg ├── Lecture 35 ├── Standard UML.jpg ├── C++ Code │ └── WithoutMediator.cpp └── Java Code │ └── WithoutMediator.java ├── Lecture 38 ├── Example UML.jpeg └── Standard UML.jpeg ├── Lecture 13 ├── Standard UML.jpeg ├── Java Code │ └── DecoratorPattern.java └── C++ Code │ └── DecoratorPattern.cpp ├── Lecture 20 └── Standard UML.jpeg ├── Lecture 22 └── Stanbdard UML.jpeg ├── Lecture 30 └── Standard UML.jpeg ├── Lecture 36 ├── Standard UML.jpeg ├── Java Code │ ├── WithoutPrototype.java │ └── PrototypePattern.java └── C++ Code │ ├── WithoutPrototype.cpp │ └── PrototypePattern.cpp ├── Lecture 39 └── Standard UML.jpeg ├── Hackathon 01 └── Problem Statement.pdf ├── Lecture 25 ├── Notes │ ├── Example UML.jpeg │ └── Standard UML.jpeg ├── Java Code │ └── BridgePattern.java └── C++ Code │ └── BridgePattern.cpp ├── Lecture 28 ├── Notes │ ├── Conclusions.jpeg │ ├── Standard UML1.jpeg │ └── Standard UML2.jpeg └── Java Code │ ├── stepBuilder │ └── Main.java │ ├── simpleBuilder │ └── Main.java │ └── builderWithDirector │ ├── HttpRequestDirector.java │ └── Main.java ├── PracticeProblems ├── PracticeProblem1.pdf └── PracticeProblem2.pdf ├── README.md ├── Lecture 10 ├── Java Code │ ├── NoSingleton.java │ ├── SimpleSingleton.java │ ├── ThreadSafeEagerSingleton.java │ ├── ThreadSafeLockingSingleton.java │ └── ThreadSafeDoubleLockingSingleton.java └── C++ Code │ ├── NoSingleton.cpp │ ├── ThreadSafeEagerSingleton.cpp │ ├── SimpleSingleton.cpp │ ├── ThreadSafeLockingSingleton.cpp │ └── ThreadSafeDoubleLockingSingleton.cpp ├── Lecture 09 ├── C++ Code │ └── SimpleFactory.cpp └── Java Code │ └── SimpleFactory.java └── Lecture 05 ├── C++ Code ├── SRP │ ├── SRP_violated.cpp │ └── SRP_followed.cpp └── OCP │ └── OCP_violated.cpp └── Java Code ├── SRP ├── SRPViolated.java └── SRPFollowed.java └── OCP ├── OCPViolated.java └── OCPFollowed.java /Lecture 11/UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 11/UML.png -------------------------------------------------------------------------------- /Lecture 14/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 14/UML.jpeg -------------------------------------------------------------------------------- /Lecture 18/UML.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 18/UML.pdf -------------------------------------------------------------------------------- /Lecture 26/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 26/UML.jpeg -------------------------------------------------------------------------------- /Lecture 27/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 27/UML.jpeg -------------------------------------------------------------------------------- /Lecture 31/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 31/UML.jpeg -------------------------------------------------------------------------------- /Lecture 33/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 33/UML.jpeg -------------------------------------------------------------------------------- /Lecture 34/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 34/UML.jpeg -------------------------------------------------------------------------------- /Lecture 37/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 37/UML.jpeg -------------------------------------------------------------------------------- /Lecture 01/Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 01/Notes.pdf -------------------------------------------------------------------------------- /Lecture 02/Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 02/Notes.pdf -------------------------------------------------------------------------------- /Lecture 03/notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 03/notes.pdf -------------------------------------------------------------------------------- /Lecture 04/notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 04/notes.pdf -------------------------------------------------------------------------------- /Lecture 06/notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 06/notes.pdf -------------------------------------------------------------------------------- /Lecture 40/Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 40/Notes.pdf -------------------------------------------------------------------------------- /Lecture 07/standardUml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 07/standardUml.png -------------------------------------------------------------------------------- /Lecture 08/Standard UML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 08/Standard UML.png -------------------------------------------------------------------------------- /Lecture 12/Standard UML.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 12/Standard UML.jpg -------------------------------------------------------------------------------- /Lecture 15/Example UML.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 15/Example UML.jpg -------------------------------------------------------------------------------- /Lecture 15/Standard UML.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 15/Standard UML.jpg -------------------------------------------------------------------------------- /Lecture 16/Example UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 16/Example UML.jpeg -------------------------------------------------------------------------------- /Lecture 17/Example UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 17/Example UML.jpeg -------------------------------------------------------------------------------- /Lecture 19/Example UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 19/Example UML.jpeg -------------------------------------------------------------------------------- /Lecture 21/Proxy Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 21/Proxy Notes.pdf -------------------------------------------------------------------------------- /Lecture 23/Notes/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 23/Notes/UML.jpeg -------------------------------------------------------------------------------- /Lecture 24/Notes/UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 24/Notes/UML.jpeg -------------------------------------------------------------------------------- /Lecture 29/Example UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 29/Example UML.jpeg -------------------------------------------------------------------------------- /Lecture 32/Example UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 32/Example UML.jpeg -------------------------------------------------------------------------------- /Lecture 35/Standard UML.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 35/Standard UML.jpg -------------------------------------------------------------------------------- /Lecture 38/Example UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 38/Example UML.jpeg -------------------------------------------------------------------------------- /Lecture 13/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 13/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 16/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 16/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 17/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 17/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 19/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 19/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 20/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 20/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 22/Stanbdard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 22/Stanbdard UML.jpeg -------------------------------------------------------------------------------- /Lecture 29/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 29/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 30/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 30/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 31/Requirements.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 31/Requirements.jpeg -------------------------------------------------------------------------------- /Lecture 32/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 32/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 36/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 36/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 38/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 38/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 39/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 39/Standard UML.jpeg -------------------------------------------------------------------------------- /Hackathon 01/Problem Statement.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Hackathon 01/Problem Statement.pdf -------------------------------------------------------------------------------- /Lecture 23/Notes/Requirements.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 23/Notes/Requirements.jpeg -------------------------------------------------------------------------------- /Lecture 24/Notes/Requirements.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 24/Notes/Requirements.jpeg -------------------------------------------------------------------------------- /Lecture 25/Notes/Example UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 25/Notes/Example UML.jpeg -------------------------------------------------------------------------------- /Lecture 25/Notes/Standard UML.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 25/Notes/Standard UML.jpeg -------------------------------------------------------------------------------- /Lecture 28/Notes/Conclusions.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 28/Notes/Conclusions.jpeg -------------------------------------------------------------------------------- /Lecture 28/Notes/Standard UML1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 28/Notes/Standard UML1.jpeg -------------------------------------------------------------------------------- /Lecture 28/Notes/Standard UML2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 28/Notes/Standard UML2.jpeg -------------------------------------------------------------------------------- /Lecture 31/Simplify Transactions.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 31/Simplify Transactions.jpeg -------------------------------------------------------------------------------- /Lecture 32/StateMachineDiagram.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/Lecture 32/StateMachineDiagram.jpeg -------------------------------------------------------------------------------- /PracticeProblems/PracticeProblem1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/PracticeProblems/PracticeProblem1.pdf -------------------------------------------------------------------------------- /PracticeProblems/PracticeProblem2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adityatandon15/LLD/HEAD/PracticeProblems/PracticeProblem2.pdf -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/strategies/PaymentStrategy.java: -------------------------------------------------------------------------------- 1 | package strategies; 2 | 3 | public interface PaymentStrategy { 4 | void pay(double amount); 5 | } 6 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/enums/DeviceType.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class DeviceType { 4 | BLUETOOTH, 5 | WIRED, 6 | HEADPHONES 7 | }; -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/enums/PlayStrategyType.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class PlayStrategyType { 4 | SEQUENTIAL, 5 | RANDOM, 6 | CUSTOM_QUEUE 7 | }; -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/enums/DeviceType.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.enums; 2 | 3 | 4 | public enum DeviceType { 5 | BLUETOOTH, 6 | WIRED, 7 | HEADPHONES 8 | } 9 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/enums/PlayStrategyType.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.enums; 2 | 3 | 4 | public enum PlayStrategyType { 5 | SEQUENTIAL, 6 | RANDOM, 7 | CUSTOM_QUEUE 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LLD 2 | All Codes and Notes for System Design (LLD) Playlist of Coder Army. 3 | Absolutely Free on Coder Army Youtube Channel. 4 | 5 | Playlist Link : https://youtube.com/playlist?list=PLQEaRBV9gAFvzp6XhcNFpk1WdOcyVo9qT&si=Ihevlxfa3nczoXp0 6 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/device/IAudioOutputDevice.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.device; 2 | 3 | import MusicPlayerApplication.models.Song; 4 | 5 | public interface IAudioOutputDevice { 6 | void playAudio(Song song); 7 | } 8 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/device/IAudioOutputDevice.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../models/Song.hpp" 3 | 4 | class IAudioOutputDevice { 5 | public: 6 | virtual ~IAudioOutputDevice() {} 7 | virtual void playAudio(Song* song) = 0; 8 | }; -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/external/HeadphonesAPI.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.external; 2 | 3 | public class HeadphonesAPI { 4 | public void playSoundViaJack(String data) { 5 | System.out.println("[Headphones] Playing: " + data); 6 | // mimics playing music 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/external/WiredSpeakerAPI.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.external; 2 | 3 | 4 | public class WiredSpeakerAPI { 5 | public void playSoundViaCable(String data) { 6 | System.out.println("[WiredSpeaker] Playing: " + data); 7 | // mimics playing music 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/external/BluetoothSpeakerAPI.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.external; 2 | 3 | public class BluetoothSpeakerAPI { 4 | public void playSoundViaBluetooth(String data) { 5 | System.out.println("[BluetoothSpeaker] Playing: " + data); 6 | // mimics playing music 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/strategies/PaymentStrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef PAYMENT_STRATEGY_H 2 | #define PAYMENT_STRATEGY_H 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class PaymentStrategy { 9 | public: 10 | virtual void pay(double amount) = 0; 11 | virtual ~PaymentStrategy() {} 12 | }; 13 | 14 | #endif // PAYMENT_STRATEGY_H 15 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/external/HeadphonesAPI.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class HeadphonesAPI { 8 | public: 9 | void playSoundViaJack(const string& data) { 10 | cout << "[Headphones] Playing: " << data << "\n"; 11 | // mimics playing music 12 | } 13 | }; -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/factories/OrderFactory.java: -------------------------------------------------------------------------------- 1 | package factories; 2 | 3 | import java.util.List; 4 | import models.*; 5 | import strategies.*; 6 | 7 | public interface OrderFactory { 8 | Order createOrder(User user, Cart cart, Restaurant restaurant, List menuItems, 9 | PaymentStrategy paymentStrategy, double totalCost, String orderType); 10 | } -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/external/WiredSpeakerAPI.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class WiredSpeakerAPI { 8 | public: 9 | void playSoundViaCable(const string& data) { 10 | cout << "[WiredSpeaker] Playing: " << data << "\n"; 11 | // mimics playing music 12 | } 13 | }; -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/utils/TimeUtils.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.format.DateTimeFormatter; 5 | 6 | public class TimeUtils { 7 | public static String getCurrentTime() { 8 | LocalDateTime now = LocalDateTime.now(); 9 | return now.format(DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy")); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Lecture 10/Java Code/NoSingleton.java: -------------------------------------------------------------------------------- 1 | public class NoSingleton { 2 | public NoSingleton() { 3 | System.out.println("Singleton Constructor called. New Object created."); 4 | } 5 | 6 | public static void main(String[] args) { 7 | NoSingleton s1 = new NoSingleton(); 8 | NoSingleton s2 = new NoSingleton(); 9 | 10 | System.out.println(s1 == s2); 11 | } 12 | } -------------------------------------------------------------------------------- /Lecture 10/C++ Code/NoSingleton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class NoSingleton { 6 | public: 7 | NoSingleton() { 8 | cout << "Singleton Constructor called. New Object created." << endl; 9 | } 10 | }; 11 | 12 | int main() { 13 | NoSingleton* s1 = new NoSingleton(); 14 | NoSingleton* s2 = new NoSingleton(); 15 | 16 | cout << (s1 == s2) << endl; 17 | } -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/external/BluetoothSpeakerAPI.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class BluetoothSpeakerAPI { 8 | public: 9 | void playSoundViaBluetooth(const string& data) { 10 | cout << "[BluetoothSpeaker] Playing: " << data << "\n"; 11 | // mimics playing music 12 | } 13 | }; -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/strategies/UpiPaymentStrategy.java: -------------------------------------------------------------------------------- 1 | package strategies; 2 | 3 | public class UpiPaymentStrategy implements PaymentStrategy { 4 | private String mobile; 5 | 6 | public UpiPaymentStrategy(String mob) { 7 | this.mobile = mob; 8 | } 9 | 10 | @Override 11 | public void pay(double amount) { 12 | System.out.println("Paid ₹" + amount + " using UPI (" + mobile + ")"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/strategies/PlayStrategy.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.strategies; 2 | 3 | import MusicPlayerApplication.models.Playlist; 4 | import MusicPlayerApplication.models.Song; 5 | 6 | public interface PlayStrategy { 7 | void setPlaylist(Playlist playlist); 8 | Song next(); 9 | boolean hasNext(); 10 | Song previous(); 11 | boolean hasPrevious(); 12 | default void addToNext(Song song) {} 13 | } 14 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/strategies/CreditCardPaymentStrategy.java: -------------------------------------------------------------------------------- 1 | package strategies; 2 | 3 | public class CreditCardPaymentStrategy implements PaymentStrategy { 4 | private String cardNumber; 5 | 6 | public CreditCardPaymentStrategy(String card) { 7 | this.cardNumber = card; 8 | } 9 | 10 | @Override 11 | public void pay(double amount) { 12 | System.out.println("Paid ₹" + amount + " using Credit Card (" + cardNumber + ")"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/utils/TimeUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef TIME_UTILS_H 2 | #define TIME_UTILS_H 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class TimeUtils { 9 | public: 10 | static string getCurrentTime() { 11 | time_t now = time(0); 12 | char* dt = ctime(&now); 13 | string s(dt); 14 | if (!s.empty() && s.back() == '\n') 15 | s.pop_back(); 16 | return s; 17 | } 18 | }; 19 | 20 | #endif // TIME_UTILS_H 21 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/strategies/PlayStrategy.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../models/Song.hpp" 4 | #include "../models/Playlist.hpp" 5 | 6 | using namespace std; 7 | 8 | class PlayStrategy { 9 | public: 10 | virtual ~PlayStrategy() {} 11 | virtual void setPlaylist(Playlist* playlist) = 0; 12 | virtual Song* next() = 0; 13 | virtual bool hasNext() = 0; 14 | virtual Song* previous() = 0; 15 | virtual bool hasPrevious() = 0; 16 | virtual void addToNext(Song* song) {} 17 | }; -------------------------------------------------------------------------------- /Lecture 28/Java Code/stepBuilder/Main.java: -------------------------------------------------------------------------------- 1 | package stepBuilder; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | HttpRequest stepRequest = HttpRequest.HttpRequestStepBuilder.getBuilder() 6 | .withUrl("https://api.example.com/products") 7 | .withMethod("POST") 8 | .withHeader("Content-Type", "application/json") 9 | .withBody("{\"product\": \"Laptop\", \"price\": 49999}") 10 | .withTimeout(45) 11 | .build(); 12 | 13 | stepRequest.execute(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/models/DeliveryOrder.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | public class DeliveryOrder extends Order { 4 | private String userAddress; 5 | 6 | public DeliveryOrder() { 7 | userAddress = ""; 8 | } 9 | 10 | @Override 11 | public String getType() { 12 | return "Delivery"; 13 | } 14 | 15 | public void setUserAddress(String addr) { 16 | userAddress = addr; 17 | } 18 | 19 | public String getUserAddress() { 20 | return userAddress; 21 | } 22 | 23 | // Implement remaining Order methods with actual fields 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/models/PickupOrder.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | public class PickupOrder extends Order { 4 | private String restaurantAddress; 5 | 6 | public PickupOrder() { 7 | restaurantAddress = ""; 8 | } 9 | 10 | @Override 11 | public String getType() { 12 | return "Pickup"; 13 | } 14 | 15 | public void setRestaurantAddress(String addr) { 16 | restaurantAddress = addr; 17 | } 18 | 19 | public String getRestaurantAddress() { 20 | return restaurantAddress; 21 | } 22 | 23 | // Implement remaining Order methods with actual fields 24 | } 25 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/models/Song.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Song { 8 | private: 9 | string title; 10 | string artist; 11 | string filePath; 12 | public: 13 | Song(string t, string a, string f) { 14 | title = t; 15 | artist = a; 16 | filePath = f; 17 | } 18 | string getTitle() { 19 | return title; 20 | } 21 | string getArtist() { 22 | return artist; 23 | } 24 | string getFilePath() { 25 | return filePath; 26 | } 27 | }; -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/strategies/UpiPaymentStrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef UPI_PAYMENT_STRATEGY_H 2 | #define UPI_PAYMENT_STRATEGY_H 3 | 4 | #include "PaymentStrategy.h" 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class UpiPaymentStrategy : public PaymentStrategy { 11 | private: 12 | string mobile; 13 | public: 14 | UpiPaymentStrategy(const string& mob) { 15 | mobile = mob; 16 | } 17 | 18 | void pay(double amount) override { 19 | cout << "Paid ₹" << amount << " using UPI (" << mobile << ")" << endl; 20 | } 21 | }; 22 | 23 | #endif // UPI_PAYMENT_STRATEGY_H 24 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/device/WiredSpeakerAdapter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../models/Song.hpp" 3 | #include "IAudioOutputDevice.hpp" 4 | #include "../external/WiredSpeakerAPI.hpp" 5 | 6 | using namespace std; 7 | 8 | class WiredSpeakerAdapter : public IAudioOutputDevice { 9 | private: 10 | WiredSpeakerAPI* wiredApi; 11 | public: 12 | WiredSpeakerAdapter(WiredSpeakerAPI* api) { 13 | wiredApi = api; 14 | } 15 | 16 | void playAudio(Song* song) override { 17 | string payload = song->getTitle() + " by " + song->getArtist(); 18 | wiredApi->playSoundViaCable(payload); 19 | } 20 | }; -------------------------------------------------------------------------------- /Lecture 10/C++ Code/ThreadSafeEagerSingleton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Singleton { 7 | private: 8 | static Singleton* instance; 9 | 10 | Singleton() { 11 | cout << "Singleton Constructor Called!" << endl; 12 | } 13 | 14 | public: 15 | static Singleton* getInstance() { 16 | return instance; 17 | } 18 | }; 19 | 20 | // Initialize static members 21 | Singleton* Singleton::instance = new Singleton(); 22 | 23 | int main() { 24 | Singleton* s1 = Singleton::getInstance(); 25 | Singleton* s2 = Singleton::getInstance(); 26 | 27 | cout << (s1 == s2) << endl; 28 | } -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/device/HeadphonesAdapter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../models/Song.hpp" 3 | #include "IAudioOutputDevice.hpp" 4 | #include "../external/HeadphonesAPI.hpp" 5 | 6 | using namespace std; 7 | 8 | class HeadphonesAdapter : public IAudioOutputDevice { 9 | private: 10 | HeadphonesAPI* headphonesApi; 11 | public: 12 | HeadphonesAdapter(HeadphonesAPI* api) { 13 | headphonesApi = api; 14 | } 15 | 16 | void playAudio(Song* song) override { 17 | string payload = song->getTitle() + " by " + song->getArtist(); 18 | headphonesApi->playSoundViaJack(payload); 19 | } 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/device/HeadphonesAdapter.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.device; 2 | 3 | import MusicPlayerApplication.models.Song; 4 | import MusicPlayerApplication.external.HeadphonesAPI; 5 | 6 | public class HeadphonesAdapter implements IAudioOutputDevice { 7 | private HeadphonesAPI headphonesApi; 8 | 9 | public HeadphonesAdapter(HeadphonesAPI api) { 10 | this.headphonesApi = api; 11 | } 12 | 13 | @Override 14 | public void playAudio(Song song) { 15 | String payload = song.getTitle() + " by " + song.getArtist(); 16 | headphonesApi.playSoundViaJack(payload); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/device/WiredSpeakerAdapter.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.device; 2 | 3 | import MusicPlayerApplication.models.Song; 4 | import MusicPlayerApplication.external.WiredSpeakerAPI; 5 | 6 | public class WiredSpeakerAdapter implements IAudioOutputDevice { 7 | private WiredSpeakerAPI wiredApi; 8 | 9 | public WiredSpeakerAdapter(WiredSpeakerAPI api) { 10 | this.wiredApi = api; 11 | } 12 | 13 | @Override 14 | public void playAudio(Song song) { 15 | String payload = song.getTitle() + " by " + song.getArtist(); 16 | wiredApi.playSoundViaCable(payload); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/models/Song.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.models; 2 | 3 | public class Song { 4 | private String title; 5 | private String artist; 6 | private String filePath; 7 | 8 | public Song(String title, String artist, String filePath) { 9 | this.title = title; 10 | this.artist = artist; 11 | this.filePath = filePath; 12 | } 13 | 14 | public String getTitle() { 15 | return title; 16 | } 17 | 18 | public String getArtist() { 19 | return artist; 20 | } 21 | 22 | public String getFilePath() { 23 | return filePath; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/factories/OrderFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef ORDER_FACTORY_H 2 | #define ORDER_FACTORY_H 3 | 4 | #include "../models/Order.h" 5 | #include "../models/Cart.h" 6 | #include "../models/Restaurant.h" 7 | #include "../strategies/PaymentStrategy.h" 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | class OrderFactory { 13 | public: 14 | virtual Order* createOrder(User* user, Cart* cart, Restaurant* restaurant, const vector& menuItems, 15 | PaymentStrategy* paymentStrategy, double totalCost, const string& orderType) = 0; 16 | virtual ~OrderFactory() {} 17 | }; 18 | 19 | #endif // ORDER_FACTORY_H 20 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/models/DeliveryOrder.h: -------------------------------------------------------------------------------- 1 | #ifndef DELIVERY_ORDER_H 2 | #define DELIVERY_ORDER_H 3 | 4 | #include "Order.h" 5 | using namespace std; 6 | 7 | class DeliveryOrder : public Order { 8 | private: 9 | string userAddress; 10 | 11 | public: 12 | DeliveryOrder() { 13 | userAddress = ""; 14 | } 15 | 16 | string getType() const override { 17 | return "Delivery"; 18 | } 19 | 20 | //Getter and Setters 21 | void setUserAddress(const string& addr) { 22 | userAddress = addr; 23 | } 24 | 25 | string getUserAddress() const { 26 | return userAddress; 27 | } 28 | }; 29 | 30 | #endif // DELIVERY_ORDER_H 31 | -------------------------------------------------------------------------------- /Lecture 10/Java Code/SimpleSingleton.java: -------------------------------------------------------------------------------- 1 | public class SimpleSingleton { 2 | private static SimpleSingleton instance = null; 3 | 4 | private SimpleSingleton() { 5 | System.out.println("Singleton Constructor called"); 6 | } 7 | 8 | public static SimpleSingleton getInstance() { 9 | if (instance == null) { 10 | instance = new SimpleSingleton(); 11 | } 12 | return instance; 13 | } 14 | 15 | public static void main(String[] args) { 16 | SimpleSingleton s1 = SimpleSingleton.getInstance(); 17 | SimpleSingleton s2 = SimpleSingleton.getInstance(); 18 | 19 | System.out.println(s1 == s2); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Lecture 10/Java Code/ThreadSafeEagerSingleton.java: -------------------------------------------------------------------------------- 1 | public class ThreadSafeEagerSingleton { 2 | private static ThreadSafeEagerSingleton instance = new ThreadSafeEagerSingleton(); 3 | 4 | private ThreadSafeEagerSingleton() { 5 | System.out.println("Singleton Constructor Called!"); 6 | } 7 | 8 | public static ThreadSafeEagerSingleton getInstance() { 9 | return instance; 10 | } 11 | 12 | public static void main(String[] args) { 13 | ThreadSafeEagerSingleton s1 = ThreadSafeEagerSingleton.getInstance(); 14 | ThreadSafeEagerSingleton s2 = ThreadSafeEagerSingleton.getInstance(); 15 | 16 | System.out.println(s1 == s2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/models/PickupOrder.h: -------------------------------------------------------------------------------- 1 | #ifndef PICKUP_ORDER_H 2 | #define PICKUP_ORDER_H 3 | 4 | #include "Order.h" 5 | using namespace std; 6 | 7 | class PickupOrder : public Order { 8 | private: 9 | string restaurantAddress; 10 | 11 | public: 12 | PickupOrder() { 13 | restaurantAddress = ""; 14 | } 15 | 16 | string getType() const override { 17 | return "Pickup"; 18 | } 19 | 20 | //Getter and Setters 21 | void setRestaurantAddress(const string& addr) { 22 | restaurantAddress = addr; 23 | } 24 | 25 | string getRestaurantAddress() const { 26 | return restaurantAddress; 27 | } 28 | }; 29 | 30 | #endif // PICKUP_ORDER_H 31 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/device/BluetoothSpeakerAdapter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../models/Song.hpp" 3 | #include "IAudioOutputDevice.hpp" 4 | #include "../external/BluetoothSpeakerAPI.hpp" 5 | 6 | using namespace std; 7 | 8 | class BluetoothSpeakerAdapter : public IAudioOutputDevice { 9 | private: 10 | BluetoothSpeakerAPI* bluetoothApi; 11 | public: 12 | BluetoothSpeakerAdapter(BluetoothSpeakerAPI* api) { 13 | bluetoothApi = api; 14 | } 15 | 16 | void playAudio(Song* song) override { 17 | string payload = song->getTitle() + " by " + song->getArtist(); 18 | bluetoothApi->playSoundViaBluetooth(payload); 19 | } 20 | }; -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/strategies/CreditCartPaymentStrategy.h: -------------------------------------------------------------------------------- 1 | #ifndef CREDIT_CARD_PAYMENT_STRATEGY_H 2 | #define CREDIT_CARD_PAYMENT_STRATEGY_H 3 | 4 | #include "PaymentStrategy.h" 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class CreditCardPaymentStrategy : public PaymentStrategy { 11 | private: 12 | string cardNumber; 13 | public: 14 | CreditCardPaymentStrategy(const string& card) { 15 | cardNumber = card; 16 | } 17 | 18 | void pay(double amount) override { 19 | cout << "Paid ₹" << amount << " using Credit Card (" << cardNumber << ")" << endl; 20 | } 21 | }; 22 | 23 | #endif // CREDIT_CARD_PAYMENT_STRATEGY_H 24 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/device/BluetoothSpeakerAdapter.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.device; 2 | 3 | import MusicPlayerApplication.models.Song; 4 | import MusicPlayerApplication.external.BluetoothSpeakerAPI; 5 | 6 | public class BluetoothSpeakerAdapter implements IAudioOutputDevice { 7 | private BluetoothSpeakerAPI bluetoothApi; 8 | 9 | public BluetoothSpeakerAdapter(BluetoothSpeakerAPI api) { 10 | this.bluetoothApi = api; 11 | } 12 | 13 | @Override 14 | public void playAudio(Song song) { 15 | String payload = song.getTitle() + " by " + song.getArtist(); 16 | bluetoothApi.playSoundViaBluetooth(payload); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Lecture 10/C++ Code/SimpleSingleton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Singleton { 6 | private: 7 | static Singleton* instance; 8 | 9 | Singleton() { 10 | cout << "Singleton Constructor called" << endl; 11 | } 12 | 13 | public: 14 | static Singleton* getInstance() { 15 | if(instance == nullptr) { 16 | instance = new Singleton(); 17 | } 18 | return instance; 19 | } 20 | }; 21 | 22 | // Initialize static member 23 | Singleton* Singleton::instance = nullptr; 24 | 25 | int main() { 26 | Singleton* s1 = Singleton::getInstance(); 27 | Singleton* s2 = Singleton::getInstance(); 28 | 29 | cout << (s1 == s2) << endl; 30 | } -------------------------------------------------------------------------------- /Lecture 28/Java Code/simpleBuilder/Main.java: -------------------------------------------------------------------------------- 1 | package simpleBuilder; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | // Using Builder Pattern (nested class) 6 | HttpRequest request = new HttpRequest.HttpRequestBuilder() 7 | .withUrl("https://api.example2.com") 8 | .withMethod("POST") 9 | .withHeader("Content-Type", "application/json") 10 | .withHeader("Accept", "application/json") 11 | .withQueryParams("key", "12345") 12 | .withBody("{\"name\": \"Aditya\"}") 13 | .withTimeout(60) 14 | .build(); 15 | 16 | request.execute(); // Guaranteed to be in a consistent state 17 | } 18 | } -------------------------------------------------------------------------------- /Lecture 28/Java Code/builderWithDirector/HttpRequestDirector.java: -------------------------------------------------------------------------------- 1 | package builderWithDirector; 2 | 3 | public class HttpRequestDirector { 4 | public static HttpRequest createGetRequest(String url) { 5 | return new HttpRequest.HttpRequestBuilder() 6 | .withUrl(url) 7 | .withMethod("GET") 8 | .build(); 9 | } 10 | 11 | // Creates a JSON POST request 12 | public static HttpRequest createJsonPostRequest(String url, String jsonBody) { 13 | return new HttpRequest.HttpRequestBuilder() 14 | .withUrl(url) 15 | .withMethod("POST") 16 | .withHeader("Content-Type", "application/json") 17 | .withHeader("Accept", "application/json") 18 | .withBody(jsonBody) 19 | .build(); 20 | } 21 | } -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/models/User.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | public class User { 4 | private int userId; 5 | private String name; 6 | private String address; 7 | private Cart cart; 8 | 9 | public User(int userId, String name, String address) { 10 | this.userId = userId; 11 | this.name = name; 12 | this.address = address; 13 | this.cart = new Cart(); 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void setName(String n) { 21 | name = n; 22 | } 23 | 24 | public String getAddress() { 25 | return address; 26 | } 27 | 28 | public void setAddress(String a) { 29 | address = a; 30 | } 31 | 32 | public Cart getCart() { 33 | return cart; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/models/MenuItem.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | public class MenuItem { 4 | private String code; 5 | private String name; 6 | private int price; 7 | 8 | public MenuItem(String code, String name, int price) { 9 | this.code = code; 10 | this.name = name; 11 | this.price = price; 12 | } 13 | 14 | public String getCode() { 15 | return code; 16 | } 17 | 18 | public void setCode(String c) { 19 | code = c; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String n) { 27 | name = n; 28 | } 29 | 30 | public int getPrice() { 31 | return price; 32 | } 33 | 34 | public void setPrice(int p) { 35 | price = p; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/models/Playlist.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "Song.hpp" 6 | 7 | using namespace std; 8 | 9 | class Playlist { 10 | private: 11 | string playlistName; 12 | vector songList; 13 | public: 14 | Playlist(string name) { 15 | playlistName = name; 16 | } 17 | string getPlaylistName() { 18 | return playlistName; 19 | } 20 | const vector getSongs() { 21 | return songList; 22 | } 23 | int getSize() { 24 | return (int)songList.size(); 25 | } 26 | void addSongToPlaylist(Song* song) { 27 | if (song == nullptr) { 28 | throw runtime_error("Cannot add null song to playlist."); 29 | } 30 | songList.push_back(song); 31 | } 32 | }; -------------------------------------------------------------------------------- /Lecture 10/C++ Code/ThreadSafeLockingSingleton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Singleton { 7 | private: 8 | static Singleton* instance; 9 | static mutex mtx; 10 | 11 | Singleton() { 12 | cout << "Singleton Constructor Called!" << endl; 13 | } 14 | 15 | public: 16 | static Singleton* getInstance() { 17 | lock_guard lock(mtx); // Lock for thread safety 18 | if (instance == nullptr) { 19 | instance = new Singleton(); 20 | } 21 | return instance; 22 | } 23 | }; 24 | 25 | // Initialize static members 26 | Singleton* Singleton::instance = nullptr; 27 | mutex Singleton::mtx; 28 | 29 | int main() { 30 | Singleton* s1 = Singleton::getInstance(); 31 | Singleton* s2 = Singleton::getInstance(); 32 | 33 | cout << (s1 == s2) << endl; 34 | } -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/factories/DeviceFactory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../device/IAudioOutputDevice.hpp" 4 | #include "../device/BluetoothSpeakerAdapter.hpp" 5 | #include "../device/WiredSpeakerAdapter.hpp" 6 | #include "../device/HeadphonesAdapter.hpp" 7 | #include "../enums/DeviceType.hpp" 8 | 9 | using namespace std; 10 | 11 | class DeviceFactory { 12 | public: 13 | static IAudioOutputDevice* createDevice(DeviceType deviceType) { 14 | if (deviceType == DeviceType::BLUETOOTH) { 15 | return new BluetoothSpeakerAdapter(new BluetoothSpeakerAPI()); 16 | } else if (deviceType == DeviceType::WIRED) { 17 | return new WiredSpeakerAdapter(new WiredSpeakerAPI()); 18 | } else { // HEADPHONES 19 | return new HeadphonesAdapter(new HeadphonesAPI()); 20 | } 21 | } 22 | }; -------------------------------------------------------------------------------- /Lecture 10/Java Code/ThreadSafeLockingSingleton.java: -------------------------------------------------------------------------------- 1 | public class ThreadSafeLockingSingleton { 2 | private static ThreadSafeLockingSingleton instance = null; 3 | 4 | private ThreadSafeLockingSingleton() { 5 | System.out.println("Singleton Constructor Called!"); 6 | } 7 | 8 | public static ThreadSafeLockingSingleton getInstance() { 9 | synchronized (ThreadSafeLockingSingleton.class) { // Lock for thread safety 10 | if (instance == null) { 11 | instance = new ThreadSafeLockingSingleton(); 12 | } 13 | return instance; 14 | } 15 | } 16 | 17 | public static void main(String[] args) { 18 | ThreadSafeLockingSingleton s1 = ThreadSafeLockingSingleton.getInstance(); 19 | ThreadSafeLockingSingleton s2 = ThreadSafeLockingSingleton.getInstance(); 20 | 21 | System.out.println(s1 == s2); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/folderStructure.txt: -------------------------------------------------------------------------------- 1 | OnlineFoodOrderingSystem/ 2 | │ 3 | ├── main.cpp # Composition root and entry point 4 | ├── TomatoApp.h # Facade class (main orchestrator) 5 | │ 6 | ├── models/ 7 | │ ├── MenuItem.h 8 | │ ├── Restaurant.h 9 | │ ├── User.h 10 | │ ├── Cart.h 11 | │ ├── Order.h # Abstract Order 12 | │ ├── DeliveryOrder.h 13 | │ ├── PickupOrder.h 14 | │ 15 | ├── managers/ 16 | │ ├── RestaurantManager.h 17 | │ ├── OrderManager.h 18 | │ 19 | ├── strategies/ 20 | │ ├── PaymentStrategy.h # Base class 21 | │ ├── CreditCardPaymentStrategy.h 22 | │ ├── UpiPaymentStrategy.h 23 | │ 24 | ├── factories/ 25 | │ ├── OrderFactory.h # Abstract factory 26 | │ ├── NowOrderFactory.h 27 | │ ├── ScheduledOrderFactory.h 28 | │ 29 | ├── services/ 30 | │ └── NotificationService.h 31 | │ 32 | ├── utils/ 33 | │ └── TimeUtils.h 34 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/models/Playlist.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.models; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Playlist { 7 | private String playlistName; 8 | private List songList; 9 | 10 | public Playlist(String name) { 11 | this.playlistName = name; 12 | this.songList = new ArrayList<>(); 13 | } 14 | 15 | public String getPlaylistName() { 16 | return playlistName; 17 | } 18 | 19 | public List getSongs() { 20 | return songList; 21 | } 22 | 23 | public int getSize() { 24 | return songList.size(); 25 | } 26 | 27 | public void addSongToPlaylist(Song song) { 28 | if (song == null) { 29 | throw new RuntimeException("Cannot add null song to playlist."); 30 | } 31 | songList.add(song); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/models/MenuItem.h: -------------------------------------------------------------------------------- 1 | #ifndef MENUITEM_H 2 | #define MENUITEM_H 3 | 4 | #include 5 | using namespace std; 6 | 7 | class MenuItem { 8 | private: 9 | string code; 10 | string name; 11 | int price; 12 | 13 | public: 14 | MenuItem(const string& code, const string& name, int price) { 15 | this->code = code; 16 | this->name = name; 17 | this->price = price; 18 | } 19 | 20 | //Getters and setters 21 | string getCode() const { 22 | return code; 23 | } 24 | 25 | void setCode(const string &c) { 26 | code = c; 27 | } 28 | 29 | string getName() const { 30 | return name; 31 | } 32 | 33 | void setName(const string &n) { 34 | name = n; 35 | } 36 | 37 | int getPrice() const { 38 | return price; 39 | } 40 | 41 | void setPrice(int p) { 42 | price = p; 43 | } 44 | }; 45 | 46 | #endif // MENUITEM_H 47 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/folderStructure.txt: -------------------------------------------------------------------------------- 1 | OnlineFoodOrderingSystem/ 2 | │ 3 | ├── Main.java # Composition root and entry point 4 | ├── TomatoApp.java # Facade class (main orcjavaestrator) 5 | │ 6 | ├── models/ 7 | │ ├── MenuItem.java 8 | │ ├── Restaurant.java 9 | │ ├── User.java 10 | │ ├── Cart.java 11 | │ ├── Order.java # Abstract Order 12 | │ ├── DeliveryOrder.java 13 | │ ├── PickupOrder.java 14 | │ 15 | ├── managers/ 16 | │ ├── RestaurantManager.java 17 | │ ├── OrderManager.java 18 | │ 19 | ├── strategies/ 20 | │ ├── PaymentStrategy.java # Base class 21 | │ ├── CreditCardPaymentStrategy.java 22 | │ ├── UpiPaymentStrategy.java 23 | │ 24 | ├── factories/ 25 | │ ├── OrderFactory.java # Abstract factory 26 | │ ├── NowOrderFactory.java 27 | │ ├── ScheduledOrderFactory.java 28 | │ 29 | ├── services/ 30 | │ └── NotificationService.java 31 | │ 32 | ├── utils/ 33 | │ └── TimeUtils.java 34 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/models/User.h: -------------------------------------------------------------------------------- 1 | #ifndef USER_H 2 | #define USER_H 3 | 4 | #include 5 | #include "Cart.h" 6 | using namespace std; 7 | 8 | class User { 9 | private: 10 | int userId; 11 | string name; 12 | string address; 13 | Cart* cart; 14 | 15 | public: 16 | User(int userId, const string& name, const string& address) { 17 | this->userId = userId; 18 | this->name = name; 19 | this->address = address; 20 | cart = new Cart(); 21 | } 22 | 23 | ~User() { 24 | delete cart; 25 | } 26 | 27 | // Getters and Setters 28 | string getName() const { 29 | return name; 30 | } 31 | 32 | void setName(const string &n) { 33 | name = n; 34 | } 35 | 36 | string getAddress() const { 37 | return address; 38 | } 39 | 40 | void setAddress(const string &a) { 41 | address = a; 42 | } 43 | 44 | Cart* getCart() const { 45 | return cart; 46 | } 47 | }; 48 | 49 | #endif // USER_H 50 | -------------------------------------------------------------------------------- /Lecture 10/C++ Code/ThreadSafeDoubleLockingSingleton.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Singleton { 7 | private: 8 | static Singleton* instance; 9 | static mutex mtx; 10 | 11 | Singleton() { 12 | cout << "Singleton Constructor Called!" << endl; 13 | } 14 | 15 | public: 16 | // Double check locking.. 17 | static Singleton* getInstance() { 18 | if (instance == nullptr) { // First check (no locking) 19 | lock_guard lock(mtx); // Lock only if needed 20 | if (instance == nullptr) { // Second check (after acquiring lock) 21 | instance = new Singleton(); 22 | } 23 | } 24 | return instance; 25 | } 26 | }; 27 | 28 | // Initialize static members 29 | Singleton* Singleton::instance = nullptr; 30 | mutex Singleton::mtx; 31 | 32 | int main() { 33 | Singleton* s1 = Singleton::getInstance(); 34 | Singleton* s2 = Singleton::getInstance(); 35 | 36 | cout << (s1 == s2) << endl; 37 | } -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/managers/OrderManager.java: -------------------------------------------------------------------------------- 1 | package managers; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import models.*; 6 | 7 | public class OrderManager { 8 | private List orders = new ArrayList<>(); 9 | private static OrderManager instance = null; 10 | 11 | private OrderManager() { 12 | // Private Constructor 13 | } 14 | 15 | public static OrderManager getInstance() { 16 | if (instance == null) { 17 | instance = new OrderManager(); 18 | } 19 | return instance; 20 | } 21 | 22 | public void addOrder(Order order) { 23 | orders.add(order); 24 | } 25 | 26 | public void listOrders() { 27 | System.out.println("\n--- All Orders ---"); 28 | for (Order order : orders) { 29 | System.out.println(order.getType() + " order for " + order.getUser().getName() 30 | + " | Total: ₹" + order.getTotal() 31 | + " | At: " + order.getScheduled()); 32 | } 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/models/Restaurant.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Restaurant { 7 | private static int nextRestaurantId = 0; 8 | private int restaurantId; 9 | private String name; 10 | private String location; 11 | private List menu = new ArrayList<>(); 12 | 13 | public Restaurant(String name, String location) { 14 | this.name = name; 15 | this.location = location; 16 | this.restaurantId = ++nextRestaurantId; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String n) { 24 | name = n; 25 | } 26 | 27 | public String getLocation() { 28 | return location; 29 | } 30 | 31 | public void setLocation(String loc) { 32 | location = loc; 33 | } 34 | 35 | public void addMenuItem(MenuItem item) { 36 | menu.add(item); 37 | } 38 | 39 | public List getMenu() { 40 | return menu; 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Lecture 21/Java Code/VirtualProxy.java: -------------------------------------------------------------------------------- 1 | interface IImage { 2 | void display(); 3 | } 4 | 5 | class RealImage implements IImage { 6 | private String filename; 7 | 8 | public RealImage(String file) { 9 | this.filename = file; 10 | System.out.println("[RealImage] Loading image from disk: " + filename); 11 | } 12 | 13 | @Override 14 | public void display() { 15 | System.out.println("[RealImage] Displaying " + filename); 16 | } 17 | } 18 | 19 | class ImageProxy implements IImage { 20 | private RealImage realImage; 21 | private String filename; 22 | 23 | public ImageProxy(String file) { 24 | this.filename = file; 25 | this.realImage = null; 26 | } 27 | 28 | @Override 29 | public void display() { 30 | if (realImage == null) { 31 | realImage = new RealImage(filename); 32 | } 33 | realImage.display(); 34 | } 35 | } 36 | 37 | public class VirtualProxy { 38 | public static void main(String[] args) { 39 | IImage image1 = new ImageProxy("sample.jpg"); 40 | image1.display(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/LSP-Rules/SingatureRules/MethodArgumentRule.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // Method Argument Rule : 6 | // Subtype method arguments can be identical or wider than the supertype 7 | // C++ imposes this by keeping singature identical 8 | 9 | class Parent { 10 | public: 11 | virtual void print(string msg) { 12 | cout << "Parent: " << msg << endl; 13 | } 14 | }; 15 | 16 | class Child : public Parent { 17 | public: 18 | void print(string msg) override { 19 | cout << "Child: " << msg << endl; 20 | } 21 | }; 22 | 23 | //Client that pass string as msg as client expects. 24 | class Client { 25 | private: 26 | Parent* p; 27 | 28 | public: 29 | Client(Parent* p) { 30 | this->p = p; 31 | } 32 | void printMsg() { 33 | p->print("Hello"); 34 | } 35 | }; 36 | 37 | int main() { 38 | 39 | Parent* parent = new Parent(); 40 | Parent* child = new Child(); 41 | 42 | //Client* client = new Client(parent); 43 | Client* client = new Client(child); 44 | 45 | client->printMsg(); 46 | 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Lecture 10/Java Code/ThreadSafeDoubleLockingSingleton.java: -------------------------------------------------------------------------------- 1 | public class ThreadSafeDoubleLockingSingleton { 2 | private static ThreadSafeDoubleLockingSingleton instance = null; 3 | 4 | private ThreadSafeDoubleLockingSingleton() { 5 | System.out.println("Singleton Constructor Called!"); 6 | } 7 | 8 | // Double check locking.. 9 | public static ThreadSafeDoubleLockingSingleton getInstance() { 10 | if (instance == null) { // First check (no locking) 11 | synchronized (ThreadSafeDoubleLockingSingleton.class) { // Lock only if needed 12 | if (instance == null) { // Second check (after acquiring lock) 13 | instance = new ThreadSafeDoubleLockingSingleton(); 14 | } 15 | } 16 | } 17 | return instance; 18 | } 19 | 20 | public static void main(String[] args) { 21 | ThreadSafeDoubleLockingSingleton s1 = ThreadSafeDoubleLockingSingleton.getInstance(); 22 | ThreadSafeDoubleLockingSingleton s2 = ThreadSafeDoubleLockingSingleton.getInstance(); 23 | 24 | System.out.println(s1 == s2); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Lecture 21/Java Code/RemoteProxy.java: -------------------------------------------------------------------------------- 1 | interface IDataService { 2 | String fetchData(); 3 | } 4 | 5 | class RealDataService implements IDataService { 6 | public RealDataService() { 7 | // Imagine this connects to a remote server or loads heavy resources. 8 | System.out.println("[RealDataService] Initialized (simulating remote setup)"); 9 | } 10 | 11 | @Override 12 | public String fetchData() { 13 | return "[RealDataService] Data from server"; 14 | } 15 | } 16 | 17 | // Remote proxy 18 | class DataServiceProxy implements IDataService { 19 | private RealDataService realService; 20 | 21 | public DataServiceProxy() { 22 | realService = new RealDataService(); 23 | } 24 | 25 | @Override 26 | public String fetchData() { 27 | System.out.println("[DataServiceProxy] Connecting to remote service..."); 28 | return realService.fetchData(); 29 | } 30 | } 31 | 32 | public class RemoteProxy { 33 | public static void main(String[] args) { 34 | IDataService dataService = new DataServiceProxy(); 35 | dataService.fetchData(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/factories/DeviceFactory.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.factories; 2 | 3 | import MusicPlayerApplication.device.IAudioOutputDevice; 4 | import MusicPlayerApplication.device.BluetoothSpeakerAdapter; 5 | import MusicPlayerApplication.device.HeadphonesAdapter; 6 | import MusicPlayerApplication.device.WiredSpeakerAdapter; 7 | import MusicPlayerApplication.external.BluetoothSpeakerAPI; 8 | import MusicPlayerApplication.external.HeadphonesAPI; 9 | import MusicPlayerApplication.external.WiredSpeakerAPI; 10 | import MusicPlayerApplication.enums.DeviceType; 11 | 12 | 13 | public class DeviceFactory { 14 | public static IAudioOutputDevice createDevice(DeviceType deviceType) { 15 | switch (deviceType) { 16 | case BLUETOOTH: 17 | return new BluetoothSpeakerAdapter(new BluetoothSpeakerAPI()); 18 | case WIRED: 19 | return new WiredSpeakerAdapter(new WiredSpeakerAPI()); 20 | case HEADPHONES: 21 | default: 22 | return new HeadphonesAdapter(new HeadphonesAPI()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/LSP-Rules/SingatureRules/MethodArgumentRule.java: -------------------------------------------------------------------------------- 1 | // Method Argument Rule : 2 | // Subtype method arguments can be identical or wider than the supertype 3 | // Java enforces this by requiring the same method signature for overrides 4 | 5 | class Parent { 6 | public void print(String msg) { 7 | System.out.println("Parent: " + msg); 8 | } 9 | } 10 | 11 | class Child extends Parent { 12 | @Override 13 | public void print(String msg) { 14 | System.out.println("Child: " + msg); 15 | } 16 | } 17 | 18 | // Client that passes a String msg as the client expects. 19 | class Client { 20 | private Parent p; 21 | 22 | public Client(Parent p) { 23 | this.p = p; 24 | } 25 | 26 | public void printMsg() { 27 | p.print("Hello"); 28 | } 29 | } 30 | 31 | public class MethodArgumentRule { 32 | public static void main(String[] args) { 33 | Parent parent = new Parent(); 34 | Parent child = new Child(); 35 | 36 | Client client = new Client(parent); 37 | //Client client = new Client(child); 38 | 39 | client.printMsg(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/managers/RestaurantManager.java: -------------------------------------------------------------------------------- 1 | package managers; 2 | 3 | import models.*; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | // Singleton 8 | public class RestaurantManager { 9 | private List restaurants = new ArrayList<>(); 10 | private static RestaurantManager instance = null; 11 | 12 | private RestaurantManager() { 13 | // private constructor 14 | } 15 | 16 | public static RestaurantManager getInstance() { 17 | if (instance == null) { 18 | instance = new RestaurantManager(); 19 | } 20 | return instance; 21 | } 22 | 23 | public void addRestaurant(Restaurant r) { 24 | restaurants.add(r); 25 | } 26 | 27 | public List searchByLocation(String loc) { 28 | List result = new ArrayList<>(); 29 | loc = loc.toLowerCase(); 30 | for (Restaurant r : restaurants) { 31 | String rl = r.getLocation().toLowerCase(); 32 | if (rl.equals(loc)) { 33 | result.add(r); 34 | } 35 | } 36 | return result; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/managers/OrderManager.h: -------------------------------------------------------------------------------- 1 | #ifndef ORDER_MANAGER_H 2 | #define ORDER_MANAGER_H 3 | 4 | #include 5 | #include 6 | #include "../models/Order.h" 7 | using namespace std; 8 | 9 | class OrderManager { 10 | private: 11 | vector orders; 12 | static OrderManager* instance; 13 | 14 | OrderManager() { 15 | // Private Constructor 16 | } 17 | 18 | public: 19 | static OrderManager* getInstance() { 20 | if (!instance) { 21 | instance = new OrderManager(); 22 | } 23 | return instance; 24 | } 25 | 26 | void addOrder(Order* order) { 27 | orders.push_back(order); 28 | } 29 | 30 | void listOrders() { 31 | cout << "\n--- All Orders ---" << endl; 32 | for (auto order : orders) { 33 | cout << order->getType() << " order for " << order->getUser()->getName() 34 | << " | Total: ₹" << order->getTotal() 35 | << " | At: " << order->getScheduled() << endl; 36 | } 37 | } 38 | }; 39 | 40 | OrderManager* OrderManager::instance = nullptr; 41 | 42 | #endif // ORDER_MANAGER_H 43 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/DIP/DIP_violated.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class MySQLDatabase { // Low-level module 5 | public: 6 | void saveToSQL(string data) { 7 | cout << "Executing SQL Query: INSERT INTO users VALUES('" << data << "');" << endl; 8 | } 9 | }; 10 | 11 | class MongoDBDatabase { // Low-level module 12 | public: 13 | void saveToMongo(string data) { 14 | cout << "Executing MongoDB Function: db.users.insert({name: '" << data << "'})" << endl; 15 | } 16 | }; 17 | 18 | class UserService { // High-level module (Tightly coupled) 19 | private: 20 | MySQLDatabase sqlDb; // Direct dependency on MySQL 21 | MongoDBDatabase mongoDb; // Direct dependency on MongoDB 22 | 23 | public: 24 | void storeUserToSQL(string user) { 25 | // MySQL-specific code 26 | sqlDb.saveToSQL(user); 27 | } 28 | 29 | void storeUserToMongo(string user) { 30 | // MongoDB-specific code 31 | mongoDb.saveToMongo(user); 32 | } 33 | }; 34 | 35 | int main() { 36 | UserService service; 37 | service.storeUserToSQL("Aditya"); 38 | service.storeUserToMongo("Rohit"); 39 | } 40 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/services/NotificationService.java: -------------------------------------------------------------------------------- 1 | package services; 2 | 3 | import java.util.List; 4 | import models.*; 5 | 6 | public class NotificationService { 7 | public static void notify(Order order) { 8 | System.out.println("\nNotification: New " + order.getType() + " order placed!"); 9 | System.out.println("---------------------------------------------"); 10 | System.out.println("Order ID: " + order.getOrderId()); 11 | System.out.println("Customer: " + order.getUser().getName()); 12 | System.out.println("Restaurant: " + order.getRestaurant().getName()); 13 | System.out.println("Items Ordered:"); 14 | 15 | List items = order.getItems(); 16 | for (MenuItem item : items) { 17 | System.out.println(" - " + item.getName() + " (₹" + item.getPrice() + ")"); 18 | } 19 | 20 | System.out.println("Total: ₹" + order.getTotal()); 21 | System.out.println("Scheduled For: " + order.getScheduled()); 22 | System.out.println("Payment: Done"); 23 | System.out.println("---------------------------------------------"); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Lecture 21/C++ Code/RemoteProxy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class IDataService { 7 | public: 8 | virtual string fetchData() = 0; 9 | virtual ~IDataService() = default; 10 | }; 11 | 12 | class RealDataService : public IDataService { 13 | public: 14 | RealDataService() { 15 | // Imagine this connects to a remote server or loads heavy resources. 16 | cout << "[RealDataService] Initialized (simulating remote setup)\n"; 17 | } 18 | string fetchData() override { 19 | return "[RealDataService] Data from server"; 20 | } 21 | }; 22 | 23 | // Remote proxy 24 | class DataServiceProxy : public IDataService { 25 | private: 26 | RealDataService* realService = nullptr; 27 | 28 | public: 29 | DataServiceProxy() { 30 | realService = new RealDataService(); 31 | } 32 | 33 | string fetchData() override { 34 | cout << "[DataServiceProxy] Connecting to remote service...\n"; 35 | return realService->fetchData(); 36 | } 37 | }; 38 | 39 | int main() { 40 | IDataService* dataService = new DataServiceProxy(); 41 | dataService->fetchData(); 42 | } 43 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/LSP-Rules/MethodRules/PreConditions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // A Precondition must be statisfied before a method can be executed. 6 | // Sub classes can weaken the precondition but cannot strengthen it. 7 | 8 | class User { 9 | public: 10 | // Precondition: Password must be at least 8 characters long 11 | virtual void setPassword(string password) { 12 | if (password.length() < 8) { 13 | throw invalid_argument("Password must be at least 8 characters long!"); 14 | } 15 | cout << "Password set successfully" << endl; 16 | } 17 | }; 18 | 19 | class AdminUser : public User { 20 | public: 21 | // Precondition: Password must be at least 6 characters 22 | void setPassword(string password) override { 23 | if (password.length() < 6) { 24 | throw invalid_argument("Password must be at least 6 characters long!"); 25 | } 26 | cout << "Password set successfully" << endl; 27 | } 28 | }; 29 | 30 | int main() { 31 | User* user = new AdminUser(); 32 | user->setPassword("Admin1"); // Works fine: AdminUser allows shorter passwords 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/LSP-Rules/MethodRules/PreConditions.java: -------------------------------------------------------------------------------- 1 | 2 | // A Precondition must be statisfied before a method can be executed. 3 | // Sub classes can weaken the precondition but cannot strengthen it. 4 | 5 | class User { 6 | // Precondition: Password must be at least 8 characters long 7 | public void setPassword(String password) { 8 | if (password.length() < 8) { 9 | throw new IllegalArgumentException("Password must be at least 8 characters long!"); 10 | } 11 | System.out.println("Password set successfully"); 12 | } 13 | } 14 | 15 | class AdminUser extends User { 16 | // Precondition: Password must be at least 6 characters 17 | @Override 18 | public void setPassword(String password) { 19 | if (password.length() < 6) { 20 | throw new IllegalArgumentException("Password must be at least 6 characters long!"); 21 | } 22 | System.out.println("Password set successfully"); 23 | } 24 | } 25 | 26 | public class PreConditions { 27 | public static void main(String[] args) { 28 | User user = new AdminUser(); 29 | user.setPassword("Admin1"); // Works fine: AdminUser allows shorter passwords 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Lecture 21/C++ Code/VirtualProxy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class IImage { 7 | public: 8 | virtual void display() = 0; 9 | virtual ~IImage() = default; 10 | }; 11 | 12 | class RealImage : public IImage { 13 | string filename; 14 | public: 15 | RealImage(string file) { 16 | this->filename = file; 17 | // Heavy Operation 18 | cout << "[RealImage] Loading image from disk: " << filename << "\n"; 19 | } 20 | 21 | void display() override { 22 | cout << "[RealImage] Displaying " << filename << "\n"; 23 | } 24 | }; 25 | 26 | class ImageProxy : public IImage { 27 | RealImage* realImage; 28 | string filename; 29 | public: 30 | ImageProxy(string file) { 31 | this->filename = file; 32 | realImage = nullptr; 33 | } 34 | 35 | void display() override { 36 | // Lazy initialization of RealImage 37 | if (!realImage) { 38 | realImage = new RealImage(filename); 39 | } 40 | realImage->display(); 41 | } 42 | }; 43 | 44 | int main() { 45 | 46 | IImage* image1 = new ImageProxy("sample.jpg"); 47 | image1->display(); 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/factories/NowOrderFactory.java: -------------------------------------------------------------------------------- 1 | package factories; 2 | 3 | import java.util.List; 4 | import models.*; 5 | import strategies.*; 6 | import utils.*; 7 | 8 | public class NowOrderFactory implements OrderFactory { 9 | @Override 10 | public Order createOrder(User user, Cart cart, Restaurant restaurant, List menuItems, 11 | PaymentStrategy paymentStrategy, double totalCost, String orderType) { 12 | Order order = null; 13 | 14 | if (orderType.equals("Delivery")) { 15 | DeliveryOrder deliveryOrder = new DeliveryOrder(); 16 | deliveryOrder.setUserAddress(user.getAddress()); 17 | order = deliveryOrder; 18 | } else { 19 | PickupOrder pickupOrder = new PickupOrder(); 20 | pickupOrder.setRestaurantAddress(restaurant.getLocation()); 21 | order = pickupOrder; 22 | } 23 | 24 | order.setUser(user); 25 | order.setRestaurant(restaurant); 26 | order.setItems(menuItems); 27 | order.setPaymentStrategy(paymentStrategy); 28 | order.setScheduled(TimeUtils.getCurrentTime()); 29 | order.setTotal(totalCost); 30 | return order; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/services/NotificationService.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTIFICATION_SERVICE_H 2 | #define NOTIFICATION_SERVICE_H 3 | 4 | #include 5 | #include "../models/Order.h" 6 | using namespace std; 7 | 8 | class NotificationService { 9 | public: 10 | static void notify(Order* order) { 11 | cout << "\nNotification: New " << order->getType() << " order placed!" << endl; 12 | cout << "---------------------------------------------" << endl; 13 | cout << "Order ID: " << order->getOrderId() << endl; 14 | cout << "Customer: " << order->getUser()->getName() << endl; 15 | cout << "Restaurant: " << order->getRestaurant()->getName() << endl; 16 | cout << "Items Ordered:\n"; 17 | 18 | const vector& items = order->getItems(); 19 | for (const auto& item : items) { 20 | cout << " - " << item.getName() << " (₹" << item.getPrice() << ")\n"; 21 | } 22 | 23 | cout << "Total: ₹" << order->getTotal() << endl; 24 | cout << "Scheduled For: " << order->getScheduled() << endl; 25 | cout << "Payment: Done" << endl; 26 | cout << "---------------------------------------------" << endl; 27 | } 28 | }; 29 | 30 | #endif // NOTIFICATION_SERVICE_H 31 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/models/Cart.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Cart { 7 | private Restaurant restaurant; 8 | private List items = new ArrayList<>(); 9 | 10 | public Cart() { 11 | restaurant = null; 12 | } 13 | 14 | public void addItem(MenuItem item) { 15 | if (restaurant == null) { 16 | System.err.println("Cart: Set a restaurant before adding items."); 17 | return; 18 | } 19 | items.add(item); 20 | } 21 | 22 | public double getTotalCost() { 23 | double sum = 0; 24 | for (MenuItem it : items) { 25 | sum += it.getPrice(); 26 | } 27 | return sum; 28 | } 29 | 30 | public boolean isEmpty() { 31 | return restaurant == null || items.isEmpty(); 32 | } 33 | 34 | public void clear() { 35 | items.clear(); 36 | restaurant = null; 37 | } 38 | 39 | public void setRestaurant(Restaurant r) { 40 | restaurant = r; 41 | } 42 | 43 | public Restaurant getRestaurant() { 44 | return restaurant; 45 | } 46 | 47 | public List getItems() { 48 | return items; 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Lecture 28/Java Code/builderWithDirector/Main.java: -------------------------------------------------------------------------------- 1 | package builderWithDirector; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | // Normal Request from Builder Directly 6 | HttpRequest normalRequest = new HttpRequest.HttpRequestBuilder() 7 | .withUrl("https://api.example.com") 8 | .withMethod("POST") 9 | .withHeader("Content-Type", "application/json") 10 | .withHeader("Accept", "application/json") 11 | .withQueryParams("key", "12345") 12 | .withBody("{\"name\": \"Aditya\"}") 13 | .withTimeout(60) 14 | .build(); 15 | 16 | normalRequest.execute(); // Guaranteed to be in a consistent state 17 | 18 | System.out.println("\n----------------------------\n"); 19 | 20 | HttpRequest getRequest = HttpRequestDirector.createGetRequest("https://api.example.com/users"); 21 | getRequest.execute(); 22 | 23 | System.out.println("\n----------------------------\n"); 24 | 25 | HttpRequest postRequest = HttpRequestDirector.createJsonPostRequest( 26 | "https://api.example.com/users", 27 | "{\"name\": \"Aditya\", \"email\": \"aditya@example.com\"}"); 28 | postRequest.execute(); 29 | } 30 | } -------------------------------------------------------------------------------- /Lecture 06/Java Code/DIP/DIPViolated.java: -------------------------------------------------------------------------------- 1 | class MySQLDatabase { // Low-level module 2 | public void saveToSQL(String data) { 3 | System.out.println( 4 | "Executing SQL Query: INSERT INTO users VALUES('" 5 | + data + "');" 6 | ); 7 | } 8 | } 9 | 10 | class MongoDBDatabase { // Low-level module 11 | public void saveToMongo(String data) { 12 | System.out.println( 13 | "Executing MongoDB Function: db.users.insert({name: '" 14 | + data + "'})" 15 | ); 16 | } 17 | } 18 | 19 | class UserService { // High-level module (Tightly coupled) 20 | private final MySQLDatabase sqlDb = new MySQLDatabase(); 21 | private final MongoDBDatabase mongoDb = new MongoDBDatabase(); 22 | 23 | public void storeUserToSQL(String user) { 24 | // MySQL-specific code 25 | sqlDb.saveToSQL(user); 26 | } 27 | 28 | public void storeUserToMongo(String user) { 29 | // MongoDB-specific code 30 | mongoDb.saveToMongo(user); 31 | } 32 | } 33 | 34 | public class DIPViolated { 35 | public static void main(String[] args) { 36 | UserService service = new UserService(); 37 | service.storeUserToSQL("Aditya"); 38 | service.storeUserToMongo("Rohit"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Lecture 36/Java Code/WithoutPrototype.java: -------------------------------------------------------------------------------- 1 | // Simple NPC class — no Prototype 2 | class NPC { 3 | public String name; 4 | public int health; 5 | public int attack; 6 | public int defense; 7 | 8 | // "Heavy" constructor: every field must be provided 9 | public NPC(String name, int health, int attack, int defense) { 10 | // call database 11 | // complex calc 12 | this.name = name; 13 | this.health = health; 14 | this.attack = attack; 15 | this.defense = defense; 16 | System.out.println("Creating NPC '" + name + "' [HP:" + health + ", ATK:" 17 | + attack + ", DEF:" + defense + "]"); 18 | } 19 | 20 | public void describe() { 21 | System.out.println(" NPC: " + name + " | HP=" + health + " ATK=" + attack 22 | + " DEF=" + defense); 23 | } 24 | } 25 | 26 | public class WithoutPrototype { 27 | public static void main(String[] args) { 28 | // Base Alien 29 | NPC alien = new NPC("Alien", 30, 5, 2); 30 | alien.describe(); 31 | 32 | // Powerful Alien — must re-pass all stats, easy to make mistakes 33 | NPC alien2 = new NPC("Powerful Alien", 30, 5, 5); 34 | alien2.describe(); 35 | 36 | // If you want 100 aliens, you'd repeat this 100 times… 37 | } 38 | } -------------------------------------------------------------------------------- /Lecture 06/C++ Code/LSP-Rules/PropertiesRules/ClassInvariants.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // Class Invariant of a parent class Object should not be broken by child class Object. 6 | // Hence child class can either maintain or strengthen the invariant but never narrows it down. 7 | 8 | //Invariant : Balance cannot be negative 9 | class BankAccount { 10 | protected: 11 | double balance; 12 | public: 13 | BankAccount(double b) { 14 | if (b < 0) throw invalid_argument("Balance can't be negative"); 15 | balance = b; 16 | } 17 | virtual void withdraw(double amount) { 18 | if (balance - amount < 0) throw runtime_error("Insufficient funds"); 19 | balance -= amount; 20 | cout<< "Amount withdrawn. Remaining balance is " << balance << endl; 21 | } 22 | }; 23 | 24 | //Brakes invariant : Should not be allowed. 25 | class CheatAccount : public BankAccount { 26 | public: 27 | CheatAccount(double b) : BankAccount(b) {} 28 | 29 | void withdraw(double amount) override { 30 | balance -= amount; // LSP break! Negative balance allowed 31 | cout<< "Amount withdrawn. Remaining balance is " << balance << endl; 32 | } 33 | }; 34 | 35 | int main() { 36 | BankAccount* bankAccount = new BankAccount(100); 37 | bankAccount->withdraw(100); 38 | } 39 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/DIP/DIP_followed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Abstraction (Interface) 5 | class Database { 6 | public: 7 | virtual void save(string data) = 0; // Pure virtual function 8 | }; 9 | 10 | // MySQL implementation (Low-level module) 11 | class MySQLDatabase : public Database { 12 | public: 13 | void save(string data) override { 14 | cout << "Executing SQL Query: INSERT INTO users VALUES('" << data << "');" << endl; 15 | } 16 | }; 17 | 18 | // MongoDB implementation (Low-level module) 19 | class MongoDBDatabase : public Database { 20 | public: 21 | void save(string data) override { 22 | cout << "Executing MongoDB Function: db.users.insert({name: '" << data << "'})" << endl; 23 | } 24 | }; 25 | 26 | // High-level module (Now loosely coupled) 27 | class UserService { 28 | private: 29 | Database* db; // Dependency Injection 30 | 31 | public: 32 | UserService(Database* database) { 33 | db = database; 34 | } 35 | 36 | void storeUser(string user) { 37 | db->save(user); 38 | } 39 | }; 40 | 41 | int main() { 42 | MySQLDatabase mysql; 43 | MongoDBDatabase mongodb; 44 | 45 | UserService service1(&mysql); 46 | service1.storeUser("Aditya"); 47 | 48 | UserService service2(&mongodb); 49 | service2.storeUser("Rohit"); 50 | } 51 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/LSP-Rules/PropertiesRules/HistoryConstraint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // Sub class methods should not be allowed state changes What 6 | // Base class never allowed. 7 | 8 | class BankAccount { 9 | protected: 10 | double balance; 11 | 12 | public: 13 | BankAccount(double b) { 14 | if (b < 0) throw invalid_argument("Balance can't be negative"); 15 | balance = b; 16 | } 17 | 18 | // History Constraint : Withdraw should be allowed 19 | virtual void withdraw(double amount) { 20 | if (balance - amount < 0) throw runtime_error("Insufficient funds"); 21 | balance -= amount; 22 | cout<< "Amount withdrawn. Remaining balance is " << balance << endl; 23 | } 24 | }; 25 | 26 | 27 | class FixedDepositAccount : public BankAccount { 28 | public: 29 | FixedDepositAccount(double b) : BankAccount(b) {} 30 | 31 | // LSP break! History constraint broke! 32 | // Parent class behaviour change : Now withdraw is not allowed. 33 | //This class will brake client code that relies on withdraw. 34 | void withdraw(double amount) override { 35 | throw runtime_error("Withdraw not allowed in Fixed Deposit"); 36 | } 37 | }; 38 | 39 | int main() { 40 | BankAccount* bankAccount = new BankAccount(100); 41 | bankAccount->withdraw(100); 42 | } -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/managers/RestaurantManager.h: -------------------------------------------------------------------------------- 1 | #ifndef RESTAURANT_MANAGER_H 2 | #define RESTAURANT_MANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../models/Restaurant.h" 8 | using namespace std; 9 | 10 | class RestaurantManager { 11 | private: 12 | vector restaurants; 13 | static RestaurantManager* instance; 14 | 15 | RestaurantManager() { 16 | // private constructor 17 | } 18 | 19 | public: 20 | static RestaurantManager* getInstance() { 21 | if (!instance) { 22 | instance = new RestaurantManager(); 23 | } 24 | return instance; 25 | } 26 | 27 | void addRestaurant(Restaurant* r) { 28 | restaurants.push_back(r); 29 | } 30 | 31 | vector searchByLocation(string loc) { 32 | vector result; 33 | transform(loc.begin(), loc.end(), loc.begin(), ::tolower); 34 | for (auto r : restaurants) { 35 | string rl = r->getLocation(); 36 | transform(rl.begin(), rl.end(), rl.begin(), ::tolower); 37 | if (rl == loc) { 38 | result.push_back(r); 39 | } 40 | } 41 | return result; 42 | } 43 | }; 44 | 45 | RestaurantManager* RestaurantManager::instance = nullptr; 46 | 47 | #endif // RESTAURANT_MANAGER_H 48 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/factories/ScheduledOrderFactory.java: -------------------------------------------------------------------------------- 1 | package factories; 2 | 3 | import java.util.List; 4 | import models.*; 5 | import strategies.*; 6 | 7 | public class ScheduledOrderFactory implements OrderFactory { 8 | private String scheduleTime; 9 | 10 | public ScheduledOrderFactory(String scheduleTime) { 11 | this.scheduleTime = scheduleTime; 12 | } 13 | 14 | @Override 15 | public Order createOrder(User user, Cart cart, Restaurant restaurant, List menuItems, 16 | PaymentStrategy paymentStrategy, double totalCost, String orderType) { 17 | Order order = null; 18 | 19 | if (orderType.equals("Delivery")) { 20 | DeliveryOrder deliveryOrder = new DeliveryOrder(); 21 | deliveryOrder.setUserAddress(user.getAddress()); 22 | order = deliveryOrder; 23 | } else { 24 | PickupOrder pickupOrder = new PickupOrder(); 25 | pickupOrder.setRestaurantAddress(restaurant.getLocation()); 26 | order = pickupOrder; 27 | } 28 | 29 | order.setUser(user); 30 | order.setRestaurant(restaurant); 31 | order.setItems(menuItems); 32 | order.setPaymentStrategy(paymentStrategy); 33 | order.setScheduled(scheduleTime); 34 | order.setTotal(totalCost); 35 | return order; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/LSP-Rules/SingatureRules/ReturnTypeRule.java: -------------------------------------------------------------------------------- 1 | // Return Type Rule : 2 | // Subtype overridden method return type should be either identical 3 | // or narrower than the parent method's return type. 4 | // This is also called return type covariance. 5 | // Java supports this out of the box. 6 | 7 | class Animal { 8 | // some common Animal methods 9 | } 10 | 11 | class Dog extends Animal { 12 | // Additional Dog methods specific to Dogs. 13 | } 14 | 15 | class Parent { 16 | public Animal getAnimal() { 17 | System.out.println("Parent : Returning Animal instance"); 18 | return new Animal(); 19 | } 20 | } 21 | 22 | class Child extends Parent { 23 | @Override 24 | public Animal getAnimal() { 25 | System.out.println("Child : Returning Dog instance"); 26 | return new Dog(); 27 | } 28 | } 29 | 30 | class Client { 31 | private Parent p; 32 | 33 | public Client(Parent p) { 34 | this.p = p; 35 | } 36 | 37 | public void takeAnimal() { 38 | p.getAnimal(); 39 | } 40 | } 41 | 42 | public class ReturnTypeRule { 43 | public static void main(String[] args) { 44 | Parent parent = new Parent(); 45 | Child child = new Child(); 46 | 47 | Client client = new Client(child); 48 | //Client client = new Client(parent); 49 | client.takeAnimal(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/factories/NowOrderFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef NOW_ORDER_FACTORY_H 2 | #define NOW_ORDER_FACTORY_H 3 | 4 | #include "OrderFactory.h" 5 | #include "../models/DeliveryOrder.h" 6 | #include "../models/PickupOrder.h" 7 | #include "../utils/TimeUtils.h" 8 | using namespace std; 9 | 10 | class NowOrderFactory : public OrderFactory { 11 | public: 12 | Order* createOrder(User* user, Cart* cart, Restaurant* restaurant, const vector& menuItems, 13 | PaymentStrategy* paymentStrategy, double totalCost, const string& orderType) override { 14 | Order* order = nullptr; 15 | if (orderType == "Delivery") { 16 | auto deliveryOrder = new DeliveryOrder(); 17 | deliveryOrder->setUserAddress(user->getAddress()); 18 | order = deliveryOrder; 19 | } 20 | else { 21 | auto pickupOrder = new PickupOrder(); 22 | pickupOrder->setRestaurantAddress(restaurant->getLocation()); 23 | order = pickupOrder; 24 | } 25 | order->setUser(user); 26 | order->setRestaurant(restaurant); 27 | order->setItems(menuItems); 28 | order->setPaymentStrategy(paymentStrategy); 29 | order->setScheduled(TimeUtils::getCurrentTime()); 30 | order->setTotal(totalCost); 31 | return order; 32 | } 33 | }; 34 | 35 | #endif // NOW_ORDER_FACTORY_H 36 | -------------------------------------------------------------------------------- /Lecture 36/C++ Code/WithoutPrototype.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // Simple NPC class — no Prototype 7 | class NPC { 8 | public: 9 | string name; 10 | int health; 11 | int attack; 12 | int defense; 13 | 14 | // “Heavy” constructor: every field must be provided 15 | NPC(const string& name, int health, int attack, int defense) { 16 | 17 | // call database 18 | // complex calc 19 | this->name = name; 20 | this->health = health; 21 | this->attack = attack; 22 | this->defense = defense; 23 | 24 | cout << "Creating NPC '" << name << "' [HP:" << health << ", ATK:" 25 | << attack << ", DEF:" << defense << "]\n"; 26 | } 27 | 28 | void describe() { 29 | cout << " NPC: " << name << " | HP=" << health << " ATK=" << attack 30 | << " DEF=" << defense << "\n"; 31 | } 32 | }; 33 | 34 | int main() { 35 | // Base Alien 36 | NPC* alien = new NPC("Alien", 30, 5, 2); 37 | alien->describe(); 38 | 39 | // Powerful Alien — must re-pass all stats, easy to make mistakes 40 | NPC* alien2 = new NPC("Powerful Alien", 30, 5, 5); 41 | alien2->describe(); 42 | 43 | // If you want 100 aliens, you'd repeat this 100 times… 44 | 45 | // cleanup 46 | delete alien; 47 | delete alien2; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/models/Cart.h: -------------------------------------------------------------------------------- 1 | #ifndef CART_H 2 | #define CART_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../models/MenuItem.h" 8 | #include "../models/Restaurant.h" 9 | 10 | using namespace std; 11 | 12 | class Cart { 13 | private: 14 | Restaurant* restaurant; 15 | vector items; 16 | 17 | public: 18 | Cart() { 19 | restaurant = nullptr; 20 | } 21 | 22 | void addItem(const MenuItem& item) { 23 | if (!restaurant) { 24 | cerr << "Cart: Set a restaurant before adding items." << endl; 25 | return; 26 | } 27 | items.push_back(item); 28 | } 29 | 30 | double getTotalCost() const { 31 | double sum = 0; 32 | for (const auto& it : items) { 33 | sum += it.getPrice(); 34 | } 35 | return sum; 36 | } 37 | 38 | bool isEmpty() { 39 | return (!restaurant || items.empty()); 40 | } 41 | 42 | void clear() { 43 | items.clear(); 44 | restaurant = nullptr; 45 | } 46 | 47 | // Getters and Setters 48 | void setRestaurant(Restaurant* r) { 49 | restaurant = r; 50 | } 51 | 52 | Restaurant* getRestaurant() const { 53 | return restaurant; 54 | } 55 | 56 | const vector& getItems() const { 57 | return items; 58 | } 59 | }; 60 | 61 | #endif // CART_H 62 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/managers/StrategyManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../strategies/SequentialPlayStrategy.hpp" 4 | #include "../strategies/CustomQueueStrategy.hpp" 5 | #include "../strategies/RandomPlayStrategy.hpp" 6 | #include "../enums/PlayStrategyType.hpp" 7 | 8 | using namespace std; 9 | 10 | class StrategyManager { 11 | private: 12 | static StrategyManager* instance; 13 | SequentialPlayStrategy* sequentialStrategy; 14 | RandomPlayStrategy* randomStrategy; 15 | CustomQueueStrategy* customQueueStrategy; 16 | 17 | StrategyManager() { 18 | sequentialStrategy = new SequentialPlayStrategy(); 19 | randomStrategy = new RandomPlayStrategy(); 20 | customQueueStrategy = new CustomQueueStrategy(); 21 | } 22 | public: 23 | static StrategyManager* getInstance() { 24 | if (!instance) { 25 | instance = new StrategyManager(); 26 | } 27 | return instance; 28 | } 29 | PlayStrategy* getStrategy(PlayStrategyType type) { 30 | if (type == PlayStrategyType::SEQUENTIAL) { 31 | return sequentialStrategy; 32 | } else if (type == PlayStrategyType::RANDOM) { 33 | return randomStrategy; 34 | } else { 35 | return customQueueStrategy; 36 | } 37 | } 38 | }; 39 | 40 | StrategyManager* StrategyManager::instance = nullptr; -------------------------------------------------------------------------------- /Lecture 06/Java Code/LSP-Rules/PropertiesRules/ClassInvariants.java: -------------------------------------------------------------------------------- 1 | // Class Invariant of a parent class Object should not be broken by child class Object. 2 | // Hence child class can either maintain or strengthen the invariant but never narrows it down. 3 | 4 | // Invariant: Balance cannot be negative 5 | class BankAccount { 6 | protected double balance; 7 | 8 | public BankAccount(double b) { 9 | if (b < 0) throw new IllegalArgumentException("Balance can't be negative"); 10 | balance = b; 11 | } 12 | 13 | public void withdraw(double amount) { 14 | if (balance - amount < 0) throw new RuntimeException("Insufficient funds"); 15 | balance -= amount; 16 | System.out.println("Amount withdrawn. Remaining balance is " + balance); 17 | } 18 | } 19 | 20 | // Breaks invariant: Should not be allowed. 21 | class CheatAccount extends BankAccount { 22 | public CheatAccount(double b) { 23 | super(b); 24 | } 25 | 26 | @Override 27 | public void withdraw(double amount) { 28 | balance -= amount; // LSP break! Negative balance allowed 29 | System.out.println("Amount withdrawn. Remaining balance is " + balance); 30 | } 31 | } 32 | 33 | public class ClassInvariants { 34 | public static void main(String[] args) { 35 | BankAccount bankAccount = new BankAccount(100); 36 | bankAccount.withdraw(100); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/LSP-Rules/PropertiesRules/HistoryConstraint.java: -------------------------------------------------------------------------------- 1 | // Subclass methods should not be allowed state changes that 2 | // the base class never allowed. 3 | 4 | class BankAccount { 5 | protected double balance; 6 | 7 | public BankAccount(double b) { 8 | if (b < 0) throw new IllegalArgumentException("Balance can't be negative"); 9 | this.balance = b; 10 | } 11 | 12 | // History Constraint: withdraw should be allowed 13 | public void withdraw(double amount) { 14 | if (balance - amount < 0) throw new RuntimeException("Insufficient funds"); 15 | balance -= amount; 16 | System.out.println("Amount withdrawn. Remaining balance is " + balance); 17 | } 18 | } 19 | 20 | class FixedDepositAccount extends BankAccount { 21 | public FixedDepositAccount(double b) { 22 | super(b); 23 | } 24 | 25 | // LSP break! History constraint broken! 26 | // Parent class behavior changed: Now withdraw is not allowed. 27 | // This class will break client code that relies on withdraw. 28 | @Override 29 | public void withdraw(double amount) { 30 | throw new RuntimeException("Withdraw not allowed in Fixed Deposit"); 31 | } 32 | } 33 | 34 | public class HistoryConstraint { 35 | public static void main(String[] args) { 36 | BankAccount bankAccount = new BankAccount(100); 37 | bankAccount.withdraw(100); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/managers/PlaylistManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../models/Playlist.hpp" 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class PlaylistManager { 10 | private: 11 | static PlaylistManager* instance; 12 | map playlists; 13 | PlaylistManager() {} 14 | public: 15 | static PlaylistManager* getInstance() { 16 | if (!instance) { 17 | instance = new PlaylistManager(); 18 | } 19 | return instance; 20 | } 21 | 22 | void createPlaylist(const string& name) { 23 | if (playlists.count(name)) { 24 | throw runtime_error("Playlist \"" + name + "\" already exists."); 25 | } 26 | playlists[name] = new Playlist(name); 27 | } 28 | 29 | void addSongToPlaylist(const string& playlistName, Song* song) { 30 | if (!playlists.count(playlistName)) { 31 | throw runtime_error("Playlist \"" + playlistName + "\" not found."); 32 | } 33 | playlists[playlistName]->addSongToPlaylist(song); 34 | } 35 | 36 | Playlist* getPlaylist(const string& name) { 37 | if (!playlists.count(name)) { 38 | throw runtime_error("Playlist \"" + name + "\" not found."); 39 | } 40 | return playlists[name]; 41 | } 42 | }; 43 | PlaylistManager* PlaylistManager::instance = nullptr; -------------------------------------------------------------------------------- /Lecture 06/C++ Code/LSP-Rules/MethodRules/PostConditions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // A Postcondition must be statisfied after a method is executed. 6 | // Sub classes can strengthen the Postcondition but cannot weaken it. 7 | 8 | class Car { 9 | protected: 10 | int speed; 11 | 12 | public: 13 | Car() { 14 | speed = 0; 15 | } 16 | 17 | void accelerate() { 18 | cout << "Accelerating" << endl; 19 | speed += 20; 20 | } 21 | 22 | //PostCondition : Speed must reduce after brake 23 | virtual void brake() { 24 | cout << "Applying brakes" << endl; 25 | speed -= 20; 26 | } 27 | }; 28 | 29 | // Subclass can strengthen postcondition - Does not violate LSP 30 | class HybridCar : public Car { 31 | private: 32 | int charge; 33 | 34 | public: 35 | 36 | HybridCar() : Car() { 37 | charge = 0; 38 | } 39 | 40 | // PostCondition : Speed must reduce after brake 41 | // PostCondition : Charge must increase. 42 | void brake() { 43 | cout << "Applying brakes" << endl; 44 | speed -= 20; 45 | charge += 10; 46 | } 47 | }; 48 | 49 | 50 | int main() { 51 | Car* hybridCar = new HybridCar(); 52 | hybridCar->brake(); // Works fine: HybridCar reduces speed and also increases charge. 53 | 54 | //Client feels no difference in substituting Hybrid car in place of Car. 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/LSP-Rules/SingatureRules/ReturnTypeRule.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // Return Type Rule : 6 | // Subtype overriden method return type should be either identical 7 | // or narrower then the parent method's return type. 8 | // This is also called as return type covariance. 9 | // C++ enforces this by covariance. 10 | 11 | class Animal { 12 | //some common Animal methods 13 | }; 14 | 15 | class Dog : public Animal { 16 | //Additional Dog methods specific to Dogs. 17 | }; 18 | 19 | 20 | class Parent { 21 | public: 22 | virtual Animal* getAnimal() { 23 | cout << "Parent : Returning Animal instance" << endl; 24 | return new Animal(); 25 | } 26 | }; 27 | 28 | class Child : public Parent { 29 | public: 30 | // Can also have return type as Dog 31 | Animal* getAnimal() override { 32 | cout << "Child : Returning Dog instance" << std::endl; 33 | return new Dog(); 34 | } 35 | }; 36 | 37 | class Client { 38 | private: 39 | Parent* p; 40 | 41 | public: 42 | Client(Parent* p) { 43 | this->p = p; 44 | } 45 | void takeAnimal() { 46 | p->getAnimal(); 47 | } 48 | }; 49 | 50 | int main() { 51 | Parent* parent = new Parent(); 52 | Child* child = new Child(); 53 | 54 | Client* client = new Client(child); 55 | //Client * client = new Client(parent); 56 | client->takeAnimal(); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/models/Restaurant.h: -------------------------------------------------------------------------------- 1 | #ifndef RESTAURANT_H 2 | #define RESTAURANT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "MenuItem.h" 8 | using namespace std; 9 | 10 | class Restaurant { 11 | private: 12 | static int nextRestaurantId; 13 | int restaurantId; 14 | string name; 15 | string location; 16 | vector menu; 17 | 18 | public: 19 | Restaurant(const string& name, const string& location) { 20 | this->name = name; 21 | this->location = location; 22 | this->restaurantId = ++nextRestaurantId; 23 | } 24 | 25 | ~Restaurant() { 26 | // Optional: just for clarity or debug 27 | cout << "Destroying Restaurant: " << name << ", and clearing its menu." << endl; 28 | menu.clear(); 29 | } 30 | 31 | //Getters and setters 32 | string getName() const { 33 | return name; 34 | } 35 | 36 | void setName(const string &n) { 37 | name = n; 38 | } 39 | 40 | string getLocation() const { 41 | return location; 42 | } 43 | 44 | void setLocation(const string &loc) { 45 | location = loc; 46 | } 47 | 48 | void addMenuItem(const MenuItem &item) { 49 | menu.push_back(item); 50 | } 51 | 52 | const vector& getMenu() const { 53 | return menu; 54 | } 55 | }; 56 | 57 | int Restaurant::nextRestaurantId = 0; 58 | 59 | #endif // RESTAURANT_H 60 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/LSP-Rules/MethodRules/PostConditions.java: -------------------------------------------------------------------------------- 1 | 2 | // A Postcondition must be satisfied after a method is executed. 3 | // Subclasses can strengthen the Postcondition but cannot weaken it. 4 | 5 | class Car { 6 | protected int speed; 7 | 8 | public Car() { 9 | speed = 0; 10 | } 11 | 12 | public void accelerate() { 13 | System.out.println("Accelerating"); 14 | speed += 20; 15 | } 16 | 17 | // PostCondition: Speed must reduce after brake 18 | public void brake() { 19 | System.out.println("Applying brakes"); 20 | speed -= 20; 21 | } 22 | } 23 | 24 | // Subclass can strengthen postcondition - Does not violate LSP 25 | class HybridCar extends Car { 26 | private int charge; 27 | 28 | public HybridCar() { 29 | super(); 30 | charge = 0; 31 | } 32 | 33 | // PostCondition: Speed must reduce after brake 34 | // PostCondition: Charge must increase. 35 | @Override 36 | public void brake() { 37 | System.out.println("Applying brakes"); 38 | speed -= 20; 39 | charge += 10; 40 | } 41 | } 42 | 43 | public class PostConditions { 44 | public static void main(String[] args) { 45 | Car hybridCar = new HybridCar(); 46 | hybridCar.brake(); // Works fine: HybridCar reduces speed and also increases charge. 47 | 48 | //Client feels no difference in substituting Hybrid car in place of Car. 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/managers/StrategyManager.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.managers; 2 | 3 | import MusicPlayerApplication.strategies.SequentialPlayStrategy; 4 | import MusicPlayerApplication.strategies.RandomPlayStrategy; 5 | import MusicPlayerApplication.strategies.CustomQueueStrategy; 6 | import MusicPlayerApplication.strategies.PlayStrategy; 7 | import MusicPlayerApplication.enums.PlayStrategyType; 8 | 9 | public class StrategyManager { 10 | private static StrategyManager instance = null; 11 | private SequentialPlayStrategy sequentialStrategy; 12 | private RandomPlayStrategy randomStrategy; 13 | private CustomQueueStrategy customQueueStrategy; 14 | 15 | private StrategyManager() { 16 | sequentialStrategy = new SequentialPlayStrategy(); 17 | randomStrategy = new RandomPlayStrategy(); 18 | customQueueStrategy = new CustomQueueStrategy(); 19 | } 20 | 21 | public static synchronized StrategyManager getInstance() { 22 | if (instance == null) { 23 | instance = new StrategyManager(); 24 | } 25 | return instance; 26 | } 27 | 28 | public PlayStrategy getStrategy(PlayStrategyType type) { 29 | if (type == PlayStrategyType.SEQUENTIAL) { 30 | return sequentialStrategy; 31 | } else if (type == PlayStrategyType.RANDOM) { 32 | return randomStrategy; 33 | } else { 34 | return customQueueStrategy; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/folderStructure.txt: -------------------------------------------------------------------------------- 1 | MusicPlayerApplication/ 2 | │ Main.java # Composition root and entry point 3 | │ MusicPlayerApplication.java # High-level application/demo runner 4 | │ MusicPlayerFacade.java # Facade class (orchestrator) 5 | │ 6 | ├── core/ 7 | │ └── AudioEngine.java #Playback engine 8 | │ 9 | ├── strategies/ 10 | │ ├── PlayStrategy.java 11 | │ ├── SequentialPlayStrategy.java 12 | │ ├── RandomPlayStrategy.java 13 | │ └── CustomQueueStrategy.java 14 | │ 15 | ├── enums/ # All shared enum types 16 | │ ├── DeviceType.java # enum class DeviceType { BLUETOOTH, WIRED, HEADPHONES } 17 | │ └── PlayStrategyType.java # enum class PlayStrategyType { SEQUENTIAL, RANDOM, CUSTOM_QUEUE } 18 | │ 19 | ├── models/ 20 | │ ├── Song.java 21 | │ └── Playlist.java 22 | │ 23 | ├── device/ # Audio device interfaces & adapters 24 | │ ├── IAudioOutputDevice.java 25 | │ ├── WiredSpeakerAdapter.java 26 | │ ├── HeadphonesAdapter.java 27 | │ └── BluetoothSpeakerAdapter.java 28 | │ 29 | ├── external/ # External devices 30 | │ ├── WiredSpeakerAPI.java 31 | │ ├── HeadphonesAPI.java 32 | │ └── BluetoothSpeakerAPI.java 33 | │ 34 | ├── factories/ 35 | │ └── DeviceFactory.java # Creates IAudioOutputDevice instances 36 | │ 37 | └── managers/ 38 | ├── PlaylistManager.java 39 | ├── StrategyManager.java 40 | └── DeviceManager.java 41 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/DIP/DIPFollowed.java: -------------------------------------------------------------------------------- 1 | // Abstraction (Interface) 2 | interface Database { 3 | void save(String data); 4 | } 5 | 6 | // MySQL implementation (Low-level module) 7 | class MySQLDatabase implements Database { 8 | @Override 9 | public void save(String data) { 10 | System.out.println( 11 | "Executing SQL Query: INSERT INTO users VALUES('" 12 | + data + "');" 13 | ); 14 | } 15 | } 16 | 17 | // MongoDB implementation (Low-level module) 18 | class MongoDBDatabase implements Database { 19 | @Override 20 | public void save(String data) { 21 | System.out.println( 22 | "Executing MongoDB Function: db.users.insert({name: '" 23 | + data + "'})" 24 | ); 25 | } 26 | } 27 | 28 | // High-level module (Now loosely coupled via Dependency Injection) 29 | class UserService { 30 | private final Database db; 31 | 32 | public UserService(Database database) { 33 | this.db = database; 34 | } 35 | 36 | public void storeUser(String user) { 37 | db.save(user); 38 | } 39 | } 40 | 41 | public class DIPFollowed { 42 | public static void main(String[] args) { 43 | MySQLDatabase mysql = new MySQLDatabase(); 44 | MongoDBDatabase mongodb = new MongoDBDatabase(); 45 | 46 | UserService service1 = new UserService(mysql); 47 | service1.storeUser("Aditya"); 48 | 49 | UserService service2 = new UserService(mongodb); 50 | service2.storeUser("Rohit"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/factories/ScheduledOrderFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEDULED_ORDER_FACTORY_H 2 | #define SCHEDULED_ORDER_FACTORY_H 3 | 4 | #include "OrderFactory.h" 5 | #include "../models/DeliveryOrder.h" 6 | #include "../models/PickupOrder.h" 7 | #include "../utils/TimeUtils.h" 8 | using namespace std; 9 | 10 | class ScheduledOrderFactory : public OrderFactory { 11 | private: 12 | string scheduleTime; 13 | public: 14 | ScheduledOrderFactory(string scheduleTime) { 15 | this->scheduleTime = scheduleTime; 16 | } 17 | 18 | Order* createOrder(User* user, Cart* cart, Restaurant* restaurant, const vector& menuItems, 19 | PaymentStrategy* paymentStrategy, double totalCost, const string& orderType) override { 20 | Order* order = nullptr; 21 | 22 | if(orderType == "Delivery") { 23 | auto deliveryOrder = new DeliveryOrder(); 24 | deliveryOrder->setUserAddress(user->getAddress()); 25 | order = deliveryOrder; 26 | } 27 | else { 28 | auto pickupOrder = new PickupOrder(); 29 | pickupOrder->setRestaurantAddress(restaurant->getLocation()); 30 | } 31 | order->setUser(user); 32 | order->setRestaurant(restaurant); 33 | order->setItems(menuItems); 34 | order->setPaymentStrategy(paymentStrategy); 35 | order->setScheduled(scheduleTime); 36 | order->setTotal(totalCost); 37 | return order; 38 | } 39 | }; 40 | 41 | #endif // SCHEDULED_ORDER_FACTORY_H 42 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "TomatoApp.h" 3 | using namespace std; 4 | 5 | int main() { 6 | // Create TomatoApp Object 7 | TomatoApp* tomato = new TomatoApp(); 8 | 9 | // Simulate a user coming in (Happy Flow) 10 | User* user = new User(101, "Aditya", "Delhi"); 11 | cout << "User: " << user->getName() << " is active." << endl; 12 | 13 | // User searches for restaurants by location 14 | vector restaurantList = tomato->searchRestaurants("Delhi"); 15 | 16 | if (restaurantList.empty()) { 17 | cout << "No restaurants found!" << endl; 18 | return 0; 19 | } 20 | cout << "Found Restaurants:" << endl; 21 | for (auto restaurant : restaurantList) { 22 | cout << " - " << restaurant->getName() << endl; 23 | } 24 | 25 | // User selects a restaurant 26 | tomato->selectRestaurant(user, restaurantList[0]); 27 | 28 | cout << "Selected restaurant: " << restaurantList[0]->getName() << endl; 29 | 30 | // User adds items to the cart 31 | tomato->addToCart(user, "P1"); 32 | tomato->addToCart(user, "P2"); 33 | 34 | tomato->printUserCart(user); 35 | 36 | // User checkout the cart 37 | Order* order = tomato->checkoutNow(user, "Delivery", new UpiPaymentStrategy("1234567890")); 38 | 39 | // User pay for the cart. If payment is success, notification is sent. 40 | tomato->payForOrder(user, order); 41 | 42 | // Cleanup Code. 43 | delete tomato; 44 | delete user; 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/strategies/SequentialPlayStrategy.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../models/Playlist.hpp" 4 | #include "PlayStrategy.hpp" 5 | 6 | using namespace std; 7 | 8 | class SequentialPlayStrategy : public PlayStrategy { 9 | private: 10 | Playlist* currentPlaylist; 11 | int currentIndex; 12 | public: 13 | SequentialPlayStrategy() { 14 | currentPlaylist = nullptr; 15 | currentIndex = -1; 16 | } 17 | 18 | void setPlaylist(Playlist* playlist) override { 19 | currentPlaylist = playlist; 20 | currentIndex = -1; 21 | } 22 | 23 | bool hasNext() override { 24 | return ((currentIndex + 1) < currentPlaylist->getSize()); 25 | } 26 | 27 | // Next in Loop 28 | Song* next() override { 29 | if (!currentPlaylist || currentPlaylist->getSize() == 0) { 30 | throw runtime_error("No playlist loaded or playlist is empty."); 31 | } 32 | currentIndex = currentIndex + 1; 33 | return currentPlaylist->getSongs()[currentIndex]; 34 | } 35 | 36 | bool hasPrevious() override { 37 | return (currentIndex - 1 > 0); 38 | } 39 | 40 | // previous in Loop 41 | Song* previous() override { 42 | if (!currentPlaylist || currentPlaylist->getSize() == 0) { 43 | throw runtime_error("No playlist loaded or playlist is empty."); 44 | } 45 | currentIndex = currentIndex - 1; 46 | return currentPlaylist->getSongs()[currentIndex]; 47 | } 48 | }; -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/managers/PlaylistManager.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.managers; 2 | 3 | import MusicPlayerApplication.models.Playlist; 4 | import MusicPlayerApplication.models.Song; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class PlaylistManager { 10 | private static PlaylistManager instance = null; 11 | private Map playlists; 12 | 13 | private PlaylistManager() { 14 | playlists = new HashMap<>(); 15 | } 16 | 17 | public static synchronized PlaylistManager getInstance() { 18 | if (instance == null) { 19 | instance = new PlaylistManager(); 20 | } 21 | return instance; 22 | } 23 | 24 | public void createPlaylist(String name) { 25 | if (playlists.containsKey(name)) { 26 | throw new RuntimeException("Playlist \"" + name + "\" already exists."); 27 | } 28 | playlists.put(name, new Playlist(name)); 29 | } 30 | 31 | public void addSongToPlaylist(String playlistName, Song song) { 32 | if (!playlists.containsKey(playlistName)) { 33 | throw new RuntimeException("Playlist \"" + playlistName + "\" not found."); 34 | } 35 | playlists.get(playlistName).addSongToPlaylist(song); 36 | } 37 | 38 | public Playlist getPlaylist(String name) { 39 | if (!playlists.containsKey(name)) { 40 | throw new RuntimeException("Playlist \"" + name + "\" not found."); 41 | } 42 | return playlists.get(name); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/folderstructure.txt: -------------------------------------------------------------------------------- 1 | MusicPlayerApp/ 2 | │ 3 | ├── main.cpp # Composition root and entry point 4 | ├── MusicPlayerFacade.hpp # Facade class (orchestrator) 5 | ├── MusicPlayerApplication.hpp # High-level application/demo runner 6 | │ 7 | ├── core/ 8 | │ └── AudioEngine.hpp # Playback engine 9 | │ 10 | ├── enums/ # All shared enum types 11 | │ ├── DeviceType.hpp # enum class DeviceType { BLUETOOTH, WIRED, HEADPHONES } 12 | │ └── PlayStrategyType.hpp # enum class PlayStrategyType { SEQUENTIAL, RANDOM, CUSTOM_QUEUE } 13 | │ 14 | ├── models/ 15 | │ ├── Song.hpp 16 | │ └── Playlist.hpp 17 | │ 18 | ├── managers/ 19 | │ ├── PlaylistManager.hpp 20 | │ ├── DeviceManager.hpp 21 | | └── StrategyManager.hpp 22 | │ 23 | ├── strategies/ 24 | │ ├── PlayStrategy.hpp 25 | │ ├── SequentialPlayStrategy.hpp 26 | │ ├── RandomPlayStrategy.hpp 27 | │ └── CustomQueueStrategy.hpp 28 | │ 29 | ├── device/ # Audio device interfaces & adapters 30 | │ ├── IAudioOutputDevice.hpp 31 | │ ├── BluetoothSpeakerAdapter.hpp 32 | │ ├── WiredSpeakerAdapter.hpp 33 | │ └── HeadphonesAdapter.hpp 34 | | 35 | ├── external/ # External devices 36 | │ ├── BluetoothSpeakerAPI.hpp 37 | │ ├── HeadphonesAPI.hpp 38 | │ └── WiredSpeakerAPI.hpp 39 | │ 40 | └── factories/ 41 | └── DeviceFactory.hpp # Creates IAudioOutputDevice instances 42 | -------------------------------------------------------------------------------- /Lecture 09/C++ Code/SimpleFactory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Burger { 6 | public: 7 | virtual void prepare() = 0; // Pure virtual function 8 | virtual ~Burger() {} // Virtual destructor 9 | }; 10 | 11 | class BasicBurger : public Burger { 12 | public: 13 | void prepare() override { 14 | cout << "Preparing Basic Burger with bun, patty, and ketchup!" << endl; 15 | } 16 | }; 17 | 18 | class StandardBurger : public Burger { 19 | public: 20 | void prepare() override { 21 | cout << "Preparing Standard Burger with bun, patty, cheese, and lettuce!" << endl; 22 | } 23 | }; 24 | 25 | class PremiumBurger : public Burger { 26 | public: 27 | void prepare() override { 28 | cout << "Preparing Premium Burger with gourmet bun, premium patty, cheese, lettuce, and secret sauce!" << endl; 29 | } 30 | }; 31 | 32 | class BurgerFactory { 33 | public: 34 | Burger* createBurger(string& type) { 35 | if (type == "basic") { 36 | return new BasicBurger(); 37 | } else if (type == "standard") { 38 | return new StandardBurger(); 39 | } else if (type == "premium") { 40 | return new PremiumBurger(); 41 | } else { 42 | cout << "Invalid burger type! " << endl; 43 | return nullptr; 44 | } 45 | } 46 | }; 47 | 48 | int main() { 49 | string type = "standard"; 50 | 51 | BurgerFactory* myBurgerFactory = new BurgerFactory(); 52 | 53 | Burger* burger = myBurgerFactory->createBurger(type); 54 | 55 | burger->prepare(); 56 | 57 | return 0; 58 | } 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/Main.java: -------------------------------------------------------------------------------- 1 | import models.*; 2 | import strategies.*; 3 | 4 | public class Main { 5 | public static void main(String[] args) { 6 | // Simulating a happy flow 7 | // Create TomatoApp Object 8 | TomatoApp tomato = new TomatoApp(); 9 | 10 | // Simulate a user coming in (Happy Flow) 11 | User user = new User(101, "Aditya", "Delhi"); 12 | System.out.println("User: " + user.getName() + " is active."); 13 | 14 | // User searches for restaurants by location 15 | java.util.List restaurantList = tomato.searchRestaurants("Delhi"); 16 | 17 | if (restaurantList.isEmpty()) { 18 | System.out.println("No restaurants found!"); 19 | return; 20 | } 21 | 22 | System.out.println("Found Restaurants:"); 23 | for (Restaurant restaurant : restaurantList) { 24 | System.out.println(" - " + restaurant.getName()); 25 | } 26 | 27 | // User selects a restaurant 28 | tomato.selectRestaurant(user, restaurantList.get(0)); 29 | System.out.println("Selected restaurant: " + restaurantList.get(0).getName()); 30 | 31 | // User adds items to the cart 32 | tomato.addToCart(user, "P1"); 33 | tomato.addToCart(user, "P2"); 34 | 35 | tomato.printUserCart(user); 36 | 37 | // User checkout the cart 38 | Order order = tomato.checkoutNow(user, "Delivery", new UpiPaymentStrategy("1234567890")); 39 | 40 | // User pays for the cart. If payment is successful, notification is sent. 41 | tomato.payForOrder(user, order); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/strategies/SequentialPlayStrategy.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.strategies; 2 | 3 | import MusicPlayerApplication.models.Playlist; 4 | import MusicPlayerApplication.models.Song; 5 | 6 | public class SequentialPlayStrategy implements PlayStrategy { 7 | private Playlist currentPlaylist; 8 | private int currentIndex; 9 | 10 | public SequentialPlayStrategy() { 11 | currentPlaylist = null; 12 | currentIndex = -1; 13 | } 14 | 15 | @Override 16 | public void setPlaylist(Playlist playlist) { 17 | currentPlaylist = playlist; 18 | currentIndex = -1; 19 | } 20 | 21 | @Override 22 | public boolean hasNext() { 23 | return ((currentIndex + 1) < currentPlaylist.getSize()); 24 | } 25 | 26 | // Next in Loop 27 | @Override 28 | public Song next() { 29 | if (currentPlaylist == null || currentPlaylist.getSize() == 0) { 30 | throw new RuntimeException("No playlist loaded or playlist is empty."); 31 | } 32 | currentIndex = currentIndex + 1; 33 | return currentPlaylist.getSongs().get(currentIndex); 34 | } 35 | 36 | @Override 37 | public boolean hasPrevious() { 38 | return (currentIndex - 1 > 0); 39 | } 40 | 41 | // previous in Loop 42 | @Override 43 | public Song previous() { 44 | if (currentPlaylist == null || currentPlaylist.getSize() == 0) { 45 | throw new RuntimeException("No playlist loaded or playlist is empty."); 46 | } 47 | currentIndex = currentIndex - 1; 48 | return currentPlaylist.getSongs().get(currentIndex); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/managers/DeviceManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../device/IAudioOutputDevice.hpp" 4 | #include "../enums/DeviceType.hpp" 5 | #include "../factories/DeviceFactory.hpp" 6 | 7 | using namespace std; 8 | 9 | class DeviceManager { 10 | private: 11 | static DeviceManager* instance; 12 | IAudioOutputDevice* currentOutputDevice; 13 | DeviceManager() { 14 | currentOutputDevice = nullptr; 15 | } 16 | public: 17 | static DeviceManager* getInstance() { 18 | if (instance == nullptr) { 19 | instance = new DeviceManager(); 20 | } 21 | return instance; 22 | } 23 | void connect(DeviceType deviceType) { 24 | if (currentOutputDevice) { 25 | delete currentOutputDevice; 26 | } 27 | 28 | currentOutputDevice = DeviceFactory::createDevice(deviceType); 29 | 30 | switch(deviceType) { 31 | case DeviceType::BLUETOOTH: 32 | cout<< "Bluetooth device connected \n"; 33 | break; 34 | case DeviceType::WIRED: 35 | cout<< "Wired device connected \n"; 36 | break; 37 | case DeviceType::HEADPHONES: 38 | cout<< "Headphones connected \n"; 39 | } 40 | } 41 | 42 | IAudioOutputDevice* getOutputDevice() { 43 | if (!currentOutputDevice) { 44 | throw runtime_error("No output device is connected."); 45 | } 46 | return currentOutputDevice; 47 | } 48 | 49 | bool hasOutputDevice() { 50 | return currentOutputDevice != nullptr; 51 | } 52 | }; 53 | 54 | DeviceManager* DeviceManager::instance = nullptr; -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/core/AudioEngine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../models/Song.hpp" 3 | #include "../device/IAudioOutputDevice.hpp" 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class AudioEngine { 10 | private: 11 | Song* currentSong; 12 | bool songIsPaused; 13 | public: 14 | AudioEngine() { 15 | currentSong = nullptr; 16 | songIsPaused = false; 17 | } 18 | string getCurrentSongTitle() const { 19 | if (currentSong) { 20 | return currentSong->getTitle(); 21 | } 22 | return ""; 23 | } 24 | bool isPaused() const { 25 | return songIsPaused; 26 | } 27 | void play(IAudioOutputDevice* aod, Song* song) { 28 | if (song == nullptr) { 29 | throw runtime_error("Cannot play a null song."); 30 | } 31 | // Resume if same song was paused 32 | if (songIsPaused && song == currentSong) { 33 | songIsPaused = false; 34 | cout << "Resuming song: " << song->getTitle() << "\n"; 35 | aod->playAudio(song); 36 | return; 37 | } 38 | 39 | currentSong = song; 40 | songIsPaused = false; 41 | cout << "Playing song: " << song->getTitle() << "\n"; 42 | aod->playAudio(song); 43 | } 44 | 45 | void pause() { 46 | if (currentSong == nullptr) { 47 | throw runtime_error("No song is currently playing to pause."); 48 | } 49 | if (songIsPaused) { 50 | throw runtime_error("Song is already paused."); 51 | } 52 | songIsPaused = true; 53 | cout << "Pausing song: " << currentSong->getTitle() << "\n"; 54 | } 55 | }; -------------------------------------------------------------------------------- /Lecture 09/Java Code/SimpleFactory.java: -------------------------------------------------------------------------------- 1 | // --- Burger Interface --- 2 | interface Burger { 3 | void prepare(); 4 | } 5 | 6 | // --- Concrete Burger Implementations --- 7 | class BasicBurger implements Burger { 8 | @Override 9 | public void prepare() { 10 | System.out.println("Preparing Basic Burger with bun, patty, and ketchup!"); 11 | } 12 | } 13 | 14 | class StandardBurger implements Burger { 15 | @Override 16 | public void prepare() { 17 | System.out.println("Preparing Standard Burger with bun, patty, cheese, and lettuce!"); 18 | } 19 | } 20 | 21 | class PremiumBurger implements Burger { 22 | @Override 23 | public void prepare() { 24 | System.out.println("Preparing Premium Burger with gourmet bun, premium patty, cheese, lettuce, and secret sauce!"); 25 | } 26 | } 27 | 28 | // --- Burger Factory --- 29 | class BurgerFactory { 30 | public Burger createBurger(String type) { 31 | if (type.equalsIgnoreCase("basic")) { 32 | return new BasicBurger(); 33 | } else if (type.equalsIgnoreCase("standard")) { 34 | return new StandardBurger(); 35 | } else if (type.equalsIgnoreCase("premium")) { 36 | return new PremiumBurger(); 37 | } else { 38 | System.out.println("Invalid burger type!"); 39 | return null; 40 | } 41 | } 42 | } 43 | 44 | // --- Main Class --- 45 | public class SimpleFactory { 46 | public static void main(String[] args) { 47 | String type = "standard"; 48 | 49 | BurgerFactory myBurgerFactory = new BurgerFactory(); 50 | 51 | Burger burger = myBurgerFactory.createBurger(type); 52 | 53 | if (burger != null) { 54 | burger.prepare(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/core/AudioEngine.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.core; 2 | 3 | import MusicPlayerApplication.models.Song; 4 | import MusicPlayerApplication.device.IAudioOutputDevice; 5 | 6 | public class AudioEngine { 7 | private Song currentSong; 8 | private boolean songIsPaused; 9 | 10 | public AudioEngine() { 11 | currentSong = null; 12 | songIsPaused = false; 13 | } 14 | 15 | public String getCurrentSongTitle() { 16 | if (currentSong != null) { 17 | return currentSong.getTitle(); 18 | } 19 | return ""; 20 | } 21 | 22 | public boolean isPaused() { 23 | return songIsPaused; 24 | } 25 | 26 | public void play(IAudioOutputDevice aod, Song song) { 27 | if (song == null) { 28 | throw new RuntimeException("Cannot play a null song."); 29 | } 30 | // Resume if same song was paused 31 | if (songIsPaused && song == currentSong) { 32 | songIsPaused = false; 33 | System.out.println("Resuming song: " + song.getTitle()); 34 | aod.playAudio(song); 35 | return; 36 | } 37 | 38 | currentSong = song; 39 | songIsPaused = false; 40 | System.out.println("Playing song: " + song.getTitle()); 41 | aod.playAudio(song); 42 | } 43 | 44 | public void pause() { 45 | if (currentSong == null) { 46 | throw new RuntimeException("No song is currently playing to pause."); 47 | } 48 | if (songIsPaused) { 49 | throw new RuntimeException("Song is already paused."); 50 | } 51 | songIsPaused = true; 52 | System.out.println("Pausing song: " + currentSong.getTitle()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Lecture 05/C++ Code/SRP/SRP_violated.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Product class representing any item of any ECommerce. 7 | class Product { 8 | public: 9 | string name; 10 | double price; 11 | 12 | Product(string name, double price) { 13 | this->name = name; 14 | this->price = price; 15 | } 16 | }; 17 | 18 | // Violating SRP: ShoppingCart is handling multiple responsibilities 19 | class ShoppingCart { 20 | private: 21 | vector products; 22 | 23 | public: 24 | void addProduct(Product* p) { 25 | products.push_back(p); 26 | } 27 | 28 | const vector& getProducts() { 29 | return products; 30 | } 31 | 32 | // 1. Calculates total price in cart. 33 | double calculateTotal() { 34 | double total = 0; 35 | for (auto p : products) { 36 | total += p->price; 37 | } 38 | return total; 39 | } 40 | 41 | // 2. Violating SRP - Prints invoice (Should be in a separate class) 42 | void printInvoice() { 43 | cout << "Shopping Cart Invoice:\n"; 44 | for (auto p : products) { 45 | cout << p->name << " - Rs " << p->price << endl; 46 | } 47 | cout << "Total: Rs " << calculateTotal() << endl; 48 | } 49 | 50 | // 3. Violating SRP - Saves to DB (Should be in a separate class) 51 | void saveToDatabase() { 52 | cout << "Saving shopping cart to database..." << endl; 53 | } 54 | }; 55 | 56 | int main() { 57 | ShoppingCart* cart = new ShoppingCart(); 58 | 59 | cart->addProduct(new Product("Laptop", 50000)); 60 | cart->addProduct(new Product("Mouse", 2000)); 61 | 62 | cart->printInvoice(); 63 | cart->saveToDatabase(); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/ISP/ISP_followed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // Separate interface for 2D shapes 6 | class TwoDimensionalShape { 7 | public: 8 | virtual double area() = 0; 9 | }; 10 | 11 | // Separate interface for 3D shapes 12 | class ThreeDimensionalShape { 13 | public: 14 | virtual double area() = 0; 15 | virtual double volume() = 0; 16 | }; 17 | 18 | // Square implements only the 2D interface 19 | class Square : public TwoDimensionalShape { 20 | private: 21 | double side; 22 | 23 | public: 24 | Square(double s) : side(s) {} 25 | 26 | double area() override { 27 | return side * side; 28 | } 29 | }; 30 | 31 | // Rectangle implements only the 2D interface 32 | class Rectangle : public TwoDimensionalShape { 33 | private: 34 | double length, width; 35 | 36 | public: 37 | Rectangle(double l, double w) : length(l), width(w) {} 38 | 39 | double area() override { 40 | return length * width; 41 | } 42 | }; 43 | 44 | // Cube implements the 3D interface 45 | class Cube : public ThreeDimensionalShape { 46 | private: 47 | double side; 48 | 49 | public: 50 | Cube(double s) : side(s) {} 51 | 52 | double area() override { 53 | return 6 * side * side; 54 | } 55 | 56 | double volume() override { 57 | return side * side * side; 58 | } 59 | }; 60 | 61 | int main() { 62 | TwoDimensionalShape* square = new Square(5); 63 | TwoDimensionalShape* rectangle = new Rectangle(4, 6); 64 | ThreeDimensionalShape* cube = new Cube(3); 65 | 66 | cout << "Square Area: " << square->area() << endl; 67 | cout << "Rectangle Area: " << rectangle->area() << endl; 68 | cout << "Cube Area: " << cube->area() << endl; 69 | cout << "Cube Volume: " << cube->volume() << endl; 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/managers/DeviceManager.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.managers; 2 | 3 | import MusicPlayerApplication.device.IAudioOutputDevice; 4 | import MusicPlayerApplication.enums.DeviceType; 5 | import MusicPlayerApplication.factories.DeviceFactory; 6 | 7 | public class DeviceManager { 8 | private static DeviceManager instance = null; 9 | private IAudioOutputDevice currentOutputDevice; 10 | 11 | private DeviceManager() { 12 | currentOutputDevice = null; 13 | } 14 | 15 | public static synchronized DeviceManager getInstance() { 16 | if (instance == null) { 17 | instance = new DeviceManager(); 18 | } 19 | return instance; 20 | } 21 | 22 | public void connect(DeviceType deviceType) { 23 | if (currentOutputDevice != null) { 24 | // In C++: delete currentOutputDevice; 25 | // In Java, garbage collector handles it, so no explicit delete. 26 | } 27 | 28 | currentOutputDevice = DeviceFactory.createDevice(deviceType); 29 | 30 | switch (deviceType) { 31 | case BLUETOOTH: 32 | System.out.println("Bluetooth device connected "); 33 | break; 34 | case WIRED: 35 | System.out.println("Wired device connected "); 36 | break; 37 | case HEADPHONES: 38 | System.out.println("Headphones connected "); 39 | break; 40 | } 41 | } 42 | 43 | public IAudioOutputDevice getOutputDevice() { 44 | if (currentOutputDevice == null) { 45 | throw new RuntimeException("No output device is connected."); 46 | } 47 | return currentOutputDevice; 48 | } 49 | 50 | public boolean hasOutputDevice() { 51 | return currentOutputDevice != null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Lecture 05/Java Code/SRP/SRPViolated.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | // Product class representing any item of any ECommerce. 5 | class Product { 6 | public String name; 7 | public double price; 8 | 9 | public Product(String name, double price) { 10 | this.name = name; 11 | this.price = price; 12 | } 13 | } 14 | 15 | // Violating SRP: ShoppingCart is handling multiple responsibilities 16 | class ShoppingCart { 17 | private List products = new ArrayList<>(); 18 | 19 | public void addProduct(Product p) { 20 | products.add(p); 21 | } 22 | 23 | public List getProducts() { 24 | return products; 25 | } 26 | 27 | // 1. Calculates total price in cart. 28 | public double calculateTotal() { 29 | double total = 0; 30 | for (Product p : products) { 31 | total += p.price; 32 | } 33 | return total; 34 | } 35 | 36 | // 2. Violating SRP - Prints invoice (Should be in a separate class) 37 | public void printInvoice() { 38 | System.out.println("Shopping Cart Invoice:"); 39 | for (Product p : products) { 40 | System.out.println(p.name + " - Rs " + p.price); 41 | } 42 | System.out.println("Total: Rs " + calculateTotal()); 43 | } 44 | 45 | // 3. Violating SRP - Saves to DB (Should be in a separate class) 46 | public void saveToDatabase() { 47 | System.out.println("Saving shopping cart to database..."); 48 | } 49 | } 50 | 51 | public class SRPViolated { 52 | public static void main(String[] args) { 53 | ShoppingCart cart = new ShoppingCart(); 54 | 55 | cart.addProduct(new Product("Laptop", 50000)); 56 | cart.addProduct(new Product("Mouse", 2000)); 57 | 58 | cart.printInvoice(); 59 | cart.saveToDatabase(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/ISP/ISPFollowed.java: -------------------------------------------------------------------------------- 1 | 2 | // Separate interface for 2D shapes 3 | interface TwoDimensionalShape { 4 | double area(); 5 | } 6 | 7 | // Separate interface for 3D shapes 8 | interface ThreeDimensionalShape { 9 | double area(); 10 | double volume(); 11 | } 12 | 13 | // Square implements only the 2D interface 14 | class Square implements TwoDimensionalShape { 15 | private double side; 16 | 17 | public Square(double s) { 18 | this.side = s; 19 | } 20 | 21 | @Override 22 | public double area() { 23 | return side * side; 24 | } 25 | } 26 | 27 | // Rectangle implements only the 2D interface 28 | class Rectangle implements TwoDimensionalShape { 29 | private double length, width; 30 | 31 | public Rectangle(double l, double w) { 32 | this.length = l; 33 | this.width = w; 34 | } 35 | 36 | @Override 37 | public double area() { 38 | return length * width; 39 | } 40 | } 41 | 42 | // Cube implements the 3D interface 43 | class Cube implements ThreeDimensionalShape { 44 | private double side; 45 | 46 | public Cube(double s) { 47 | this.side = s; 48 | } 49 | 50 | @Override 51 | public double area() { 52 | return 6 * side * side; 53 | } 54 | 55 | @Override 56 | public double volume() { 57 | return side * side * side; 58 | } 59 | } 60 | 61 | public class ISPFollowed { 62 | public static void main(String[] args) { 63 | TwoDimensionalShape square = new Square(5); 64 | TwoDimensionalShape rectangle = new Rectangle(4, 6); 65 | ThreeDimensionalShape cube = new Cube(3); 66 | 67 | System.out.println("Square Area: " + square.area()); 68 | System.out.println("Rectangle Area: " + rectangle.area()); 69 | System.out.println("Cube Area: " + cube.area()); 70 | System.out.println("Cube Volume: " + cube.volume()); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Lecture 17/C++ Code/FacadePattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Subsystems 5 | class PowerSupply { 6 | public: 7 | void providePower() { 8 | cout << "Power Supply: Providing power..." << endl; 9 | } 10 | }; 11 | 12 | class CoolingSystem { 13 | public: 14 | void startFans() { 15 | cout << "Cooling System: Fans started..." << endl; 16 | } 17 | }; 18 | 19 | class CPU { 20 | public: 21 | void initialize() { 22 | cout << "CPU: Initialization started..." << endl; 23 | } 24 | }; 25 | 26 | class Memory { 27 | public: 28 | void selfTest() { 29 | cout << "Memory: Self-test passed..." << endl; 30 | } 31 | }; 32 | 33 | class HardDrive { 34 | public: 35 | void spinUp() { 36 | cout << "Hard Drive: Spinning up..." << endl; 37 | } 38 | }; 39 | 40 | class BIOS { 41 | public: 42 | void boot(CPU& cpu, Memory& memory) { 43 | cout << "BIOS: Booting CPU and Memory checks..." << endl; 44 | cpu.initialize(); 45 | memory.selfTest(); 46 | } 47 | }; 48 | 49 | class OperatingSystem { 50 | public: 51 | void load() { 52 | cout << "Operating System: Loading into memory..." << endl; 53 | } 54 | }; 55 | 56 | // Facade 57 | class ComputerFacade { 58 | private: 59 | PowerSupply powerSupply; 60 | CoolingSystem coolingSystem; 61 | CPU cpu; 62 | Memory memory; 63 | HardDrive hardDrive; 64 | BIOS bios; 65 | OperatingSystem os; 66 | 67 | public: 68 | void startComputer() { 69 | cout << "----- Starting Computer -----" << endl; 70 | powerSupply.providePower(); 71 | coolingSystem.startFans(); 72 | bios.boot(cpu, memory); 73 | hardDrive.spinUp(); 74 | os.load(); 75 | cout << "Computer Booted Successfully!" << endl; 76 | } 77 | }; 78 | 79 | // Client 80 | int main() { 81 | ComputerFacade computer; 82 | computer.startComputer(); 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /Lecture 07/C++ Code/BadDesign/DocumentEditor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class DocumentEditor { 9 | private: 10 | vector documentElements; 11 | string renderedDocument; 12 | 13 | public: 14 | // Adds text as a plain string 15 | void addText(string text) { 16 | documentElements.push_back(text); 17 | } 18 | 19 | // Adds an image represented by its file path 20 | void addImage(string imagePath) { 21 | documentElements.push_back(imagePath); 22 | } 23 | 24 | // Renders the document by checking the type of each element at runtime 25 | string renderDocument() { 26 | if(renderedDocument.empty()) { 27 | string result; 28 | for (auto element : documentElements) { 29 | if (element.size() > 4 && (element.substr(element.size() - 4) == ".jpg" || 30 | element.substr(element.size() - 4) == ".png")) { 31 | result += "[Image: " + element + "]" + "\n"; 32 | } else { 33 | result += element + "\n"; 34 | } 35 | } 36 | renderedDocument = result; 37 | } 38 | return renderedDocument; 39 | } 40 | 41 | void saveToFile() { 42 | ofstream file("document.txt"); 43 | if (file.is_open()) { 44 | file << renderDocument(); 45 | file.close(); 46 | cout << "Document saved to document.txt" << endl; 47 | } else { 48 | cout << "Error: Unable to open file for writing." << endl; 49 | } 50 | } 51 | }; 52 | 53 | int main() { 54 | DocumentEditor editor; 55 | editor.addText("Hello, world!"); 56 | editor.addImage("picture.jpg"); 57 | editor.addText("This is a document editor."); 58 | 59 | cout << editor.renderDocument() << endl; 60 | 61 | editor.saveToFile(); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/LSP-Rules/SingatureRules/ExceptionRule.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // Exception Rule: 6 | // A subclass should throw fewer or narrower exceptions 7 | // (but not additional or broader exceptions) than the parent. 8 | // C++ does not enforces this. Hence no compilation error. 9 | 10 | /* 11 | ├── std::logic_error <-- For logical errors detected before runtime 12 | │ ├── std::invalid_argument <-- Invalid function argument 13 | │ ├── std::domain_error <-- Function argument domain error 14 | │ ├── std::length_error <-- Exceeding valid length limits 15 | │ ├── std::out_of_range <-- Array or container index out of bounds 16 | │ 17 | ├── std::runtime_error <-- For errors that occur at runtime 18 | │ ├── std::range_error <-- Numeric result out of range 19 | │ ├── std::overflow_error <-- Arithmetic overflow 20 | │ ├── std::underflow_error 21 | */ 22 | 23 | class Parent { 24 | public: 25 | virtual void getValue() noexcept(false) { // Parent throws logic_error exception 26 | throw logic_error("Parent error"); 27 | } 28 | }; 29 | 30 | class Child : public Parent { 31 | public: 32 | void getValue() noexcept(false) override { // Child throws out_of_range exception 33 | throw out_of_range("Child error"); 34 | // throw runtime_error("Child Error"); // This is Wrong 35 | } 36 | }; 37 | 38 | class Client { 39 | private: 40 | Parent* p; 41 | 42 | public: 43 | Client(Parent* p) { 44 | this->p = p; 45 | } 46 | void takeValue() { 47 | try { 48 | p->getValue(); 49 | } 50 | catch(const logic_error& e) { 51 | cout << "Logic error exception occured : " << e.what() << endl; 52 | } 53 | } 54 | }; 55 | 56 | int main() { 57 | Parent* parent = new Parent(); 58 | Child* child = new Child(); 59 | 60 | Client* client = new Client(parent); 61 | //Client* client = new Client(child); 62 | 63 | client->takeValue(); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/strategies/RandomPlayStrategy.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "../models/Playlist.hpp" 4 | #include "PlayStrategy.hpp" 5 | 6 | using namespace std; 7 | 8 | class RandomPlayStrategy : public PlayStrategy { 9 | private: 10 | Playlist* currentPlaylist; 11 | vector remainingSongs; 12 | stack history; 13 | 14 | public: 15 | RandomPlayStrategy() { 16 | currentPlaylist = nullptr; 17 | srand((unsigned)time(nullptr)); 18 | } 19 | 20 | void setPlaylist(Playlist* playlist) override { 21 | currentPlaylist = playlist; 22 | if (!currentPlaylist || currentPlaylist->getSize() == 0) return; 23 | 24 | remainingSongs = currentPlaylist->getSongs(); 25 | history = stack(); 26 | } 27 | 28 | bool hasNext() override { 29 | return currentPlaylist && !remainingSongs.empty(); 30 | } 31 | 32 | // Next in Loop 33 | Song* next() override { 34 | if (!currentPlaylist || currentPlaylist->getSize() == 0) { 35 | throw runtime_error("No playlist loaded or playlist is empty."); 36 | } 37 | if (remainingSongs.empty()) { 38 | throw runtime_error("No songs left to play"); 39 | } 40 | 41 | int idx = rand() % remainingSongs.size(); 42 | Song* selectedSong = remainingSongs[idx]; 43 | 44 | // Remove the selectedSong from the list. (Swap and pop to remove in O(1)) 45 | swap(remainingSongs[idx], remainingSongs.back()); 46 | remainingSongs.pop_back(); 47 | 48 | history.push(selectedSong); 49 | return selectedSong; 50 | } 51 | 52 | bool hasPrevious() override { 53 | return history.size() > 0; 54 | } 55 | 56 | Song* previous() override { 57 | if (history.empty()) { 58 | throw std::runtime_error("No previous song available."); 59 | } 60 | 61 | Song* song = history.top(); 62 | history.pop(); 63 | return song; 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /Lecture 21/Java Code/ProtectionProxy.java: -------------------------------------------------------------------------------- 1 | interface IDocumentReader { 2 | void unlockPDF(String filePath, String password); 3 | } 4 | 5 | class RealDocumentReader implements IDocumentReader { 6 | @Override 7 | public void unlockPDF(String filePath, String password) { 8 | System.out.println("[RealDocumentReader] Unlocking PDF at: " + filePath); 9 | System.out.println("[RealDocumentReader] PDF unlocked successfully with password: " + password); 10 | System.out.println("[RealDocumentReader] Displaying PDF content..."); 11 | } 12 | } 13 | 14 | class User { 15 | public String name; 16 | public boolean premiumMembership; 17 | 18 | public User(String name, boolean isPremium) { 19 | this.name = name; 20 | this.premiumMembership = isPremium; 21 | } 22 | } 23 | 24 | class DocumentProxy implements IDocumentReader { 25 | private RealDocumentReader realReader; 26 | private User user; 27 | 28 | public DocumentProxy(User user) { 29 | this.realReader = new RealDocumentReader(); 30 | this.user = user; 31 | } 32 | 33 | @Override 34 | public void unlockPDF(String filePath, String password) { 35 | if (!user.premiumMembership) { 36 | System.out.println("[DocumentProxy] Access denied. Only premium members can unlock PDFs."); 37 | return; 38 | } 39 | realReader.unlockPDF(filePath, password); 40 | } 41 | } 42 | 43 | public class ProtectionProxy { 44 | public static void main(String[] args) { 45 | User user1 = new User("Rohan", false); 46 | User user2 = new User("Rashmi", true); 47 | 48 | System.out.println("== Rohan (Non-Premium) tries to unlock PDF =="); 49 | IDocumentReader docReader = new DocumentProxy(user1); 50 | docReader.unlockPDF("protected_document.pdf", "secret123"); 51 | 52 | System.out.println("\n== Rashmi (Premium) unlocks PDF =="); 53 | docReader = new DocumentProxy(user2); 54 | docReader.unlockPDF("protected_document.pdf", "secret123"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Lecture 17/Java Code/FacadePattern.java: -------------------------------------------------------------------------------- 1 | 2 | // Subsystems 3 | class PowerSupply { 4 | public void providePower() { 5 | System.out.println("Power Supply: Providing power..."); 6 | } 7 | } 8 | 9 | class CoolingSystem { 10 | public void startFans() { 11 | System.out.println("Cooling System: Fans started..."); 12 | } 13 | } 14 | 15 | class CPU { 16 | public void initialize() { 17 | System.out.println("CPU: Initialization started..."); 18 | } 19 | } 20 | 21 | class Memory { 22 | public void selfTest() { 23 | System.out.println("Memory: Self-test passed..."); 24 | } 25 | } 26 | 27 | class HardDrive { 28 | public void spinUp() { 29 | System.out.println("Hard Drive: Spinning up..."); 30 | } 31 | } 32 | 33 | class BIOS { 34 | public void boot(CPU cpu, Memory memory) { 35 | System.out.println("BIOS: Booting CPU and Memory checks..."); 36 | cpu.initialize(); 37 | memory.selfTest(); 38 | } 39 | } 40 | 41 | class OperatingSystem { 42 | public void load() { 43 | System.out.println("Operating System: Loading into memory..."); 44 | } 45 | } 46 | 47 | // Facade 48 | class ComputerFacade { 49 | private PowerSupply powerSupply = new PowerSupply(); 50 | private CoolingSystem coolingSystem = new CoolingSystem(); 51 | private CPU cpu = new CPU(); 52 | private Memory memory = new Memory(); 53 | private HardDrive hardDrive = new HardDrive(); 54 | private BIOS bios = new BIOS(); 55 | private OperatingSystem os = new OperatingSystem(); 56 | 57 | public void startComputer() { 58 | System.out.println("----- Starting Computer -----"); 59 | powerSupply.providePower(); 60 | coolingSystem.startFans(); 61 | bios.boot(cpu, memory); 62 | hardDrive.spinUp(); 63 | os.load(); 64 | System.out.println("Computer Booted Successfully!"); 65 | } 66 | } 67 | 68 | // Client 69 | public class FacadePattern { 70 | public static void main(String[] args) { 71 | ComputerFacade computer = new ComputerFacade(); 72 | computer.startComputer(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Lecture 06/C++ Code/ISP/ISP_violated.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Single interface for all shapes (Violates ISP) 7 | class Shape { 8 | public: 9 | virtual double area() = 0; 10 | virtual double volume() = 0; // 2D shapes don't have volume! 11 | }; 12 | 13 | // Square is a 2D shape but is forced to implement volume() 14 | class Square : public Shape { 15 | private: 16 | double side; 17 | 18 | public: 19 | Square(double s) : side(s) {} 20 | 21 | double area() override { 22 | return side * side; 23 | } 24 | 25 | double volume() override { 26 | throw logic_error("Volume not applicable for Square"); // Unnecessary method 27 | } 28 | }; 29 | 30 | // Rectangle is also a 2D shape but is forced to implement volume() 31 | class Rectangle : public Shape { 32 | private: 33 | double length, width; 34 | 35 | public: 36 | Rectangle(double l, double w) : length(l), width(w) {} 37 | 38 | double area() override { 39 | return length * width; 40 | } 41 | 42 | double volume() override { 43 | throw logic_error("Volume not applicable for Rectangle"); // Unnecessary method 44 | } 45 | }; 46 | 47 | // Cube is a 3D shape, so it actually has a volume 48 | class Cube : public Shape { 49 | private: 50 | double side; 51 | 52 | public: 53 | Cube(double s) : side(s) {} 54 | 55 | double area() override { 56 | return 6 * side * side; 57 | } 58 | 59 | double volume() override { 60 | return side * side * side; 61 | } 62 | }; 63 | 64 | int main() { 65 | Shape* square = new Square(5); 66 | Shape* rectangle = new Rectangle(4, 6); 67 | Shape* cube = new Cube(3); 68 | 69 | cout << "Square Area: " << square->area() << endl; 70 | cout << "Rectangle Area: " << rectangle->area() << endl; 71 | cout << "Cube Area: " << cube->area() << endl; 72 | cout << "Cube Volume: " << cube->volume() << endl; 73 | 74 | try { 75 | cout << "Square Volume: " << square->volume() << endl; // Will throw an exception 76 | } catch (logic_error& e) { 77 | cout << "Exception: " << e.what() << endl; 78 | } 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /Lecture 36/Java Code/PrototypePattern.java: -------------------------------------------------------------------------------- 1 | // Cloneable (aka Prototype) interface 2 | interface Cloneable { 3 | Cloneable clone(); 4 | } 5 | 6 | class NPC implements Cloneable { 7 | public String name; 8 | public int health; 9 | public int attack; 10 | public int defense; 11 | 12 | public NPC(String name, int health, int attack, int defense) { 13 | // call database 14 | // complex calc 15 | this.name = name; 16 | this.health = health; 17 | this.attack = attack; 18 | this.defense = defense; 19 | System.out.println("Setting up template NPC '" + name + "'"); 20 | } 21 | 22 | // copy‐ctor used by clone() 23 | public NPC(NPC other) { 24 | name = other.name; 25 | health = other.health; 26 | attack = other.attack; 27 | defense = other.defense; 28 | System.out.println("Cloning NPC '" + name + "'"); 29 | } 30 | 31 | // the clone method required by Prototype 32 | public Cloneable clone() { 33 | return new NPC(this); 34 | } 35 | 36 | public void describe() { 37 | System.out.println("NPC " + name + " [HP=" + health + " ATK=" + attack 38 | + " DEF=" + defense + "]"); 39 | } 40 | 41 | // setters to tweak the clone… 42 | public void setName(String n) { 43 | name = n; 44 | } 45 | public void setHealth(int h) { 46 | health = h; 47 | } 48 | public void setAttack(int a) { 49 | attack = a; 50 | } 51 | public void setDefense(int d){ 52 | defense = d; 53 | } 54 | } 55 | 56 | public class PrototypePattern { 57 | public static void main(String[] args) { 58 | // 1) build one "heavy" template 59 | NPC alien = new NPC("Alien", 30, 5, 2); 60 | 61 | // 2) quickly clone + tweak as many variants as you like: 62 | NPC alienCopied1 = (NPC)alien.clone(); 63 | alienCopied1.describe(); 64 | 65 | NPC alienCopied2 = (NPC)alien.clone(); 66 | alienCopied2.setName("Powerful Alien"); 67 | alienCopied2.setHealth(50); 68 | alienCopied2.describe(); 69 | 70 | // cleanup 71 | alien = null; 72 | alienCopied1 = null; 73 | alienCopied2 = null; 74 | } 75 | } -------------------------------------------------------------------------------- /Lecture 11/Java Code/Tomato/models/Order.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | import java.util.List; 4 | import strategies.*; 5 | 6 | public abstract class Order { 7 | private static int nextOrderId = 0; 8 | 9 | protected int orderId; 10 | protected User user; 11 | protected Restaurant restaurant; 12 | protected List items; 13 | protected PaymentStrategy paymentStrategy; 14 | protected double total; 15 | protected String scheduled; 16 | 17 | public Order() { 18 | this.user = null; 19 | this.restaurant = null; 20 | this.paymentStrategy = null; 21 | this.total = 0.0; 22 | this.scheduled = ""; 23 | this.orderId = ++nextOrderId; 24 | } 25 | 26 | public boolean processPayment() { 27 | if (paymentStrategy != null) { 28 | paymentStrategy.pay(total); 29 | return true; 30 | } else { 31 | System.out.println("Please choose a payment mode first"); 32 | return false; 33 | } 34 | } 35 | 36 | public abstract String getType(); 37 | 38 | // Getters and Setters 39 | public int getOrderId() { 40 | return orderId; 41 | } 42 | 43 | public void setUser(User u) { 44 | user = u; 45 | } 46 | 47 | public User getUser() { 48 | return user; 49 | } 50 | 51 | public void setRestaurant(Restaurant r) { 52 | restaurant = r; 53 | } 54 | 55 | public Restaurant getRestaurant() { 56 | return restaurant; 57 | } 58 | 59 | public void setItems(List its) { 60 | items = its; 61 | total = 0; 62 | for (MenuItem i : items) { 63 | total += i.getPrice(); 64 | } 65 | } 66 | 67 | public List getItems() { 68 | return items; 69 | } 70 | 71 | public void setPaymentStrategy(PaymentStrategy p) { 72 | paymentStrategy = p; 73 | } 74 | 75 | public void setScheduled(String s) { 76 | scheduled = s; 77 | } 78 | 79 | public String getScheduled() { 80 | return scheduled; 81 | } 82 | 83 | public double getTotal() { 84 | return total; 85 | } 86 | 87 | public void setTotal(double total) { 88 | this.total = total; 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /Lecture 36/C++ Code/PrototypePattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // Cloneable (aka Prototype) interface 7 | class Cloneable { 8 | public: 9 | virtual Cloneable* clone() const = 0; 10 | virtual ~Cloneable() {} 11 | }; 12 | 13 | class NPC : public Cloneable { 14 | public: 15 | string name; 16 | int health; 17 | int attack; 18 | int defense; 19 | 20 | NPC(const string& name, int health, int attack, int defense) { 21 | // call database 22 | // complex calc 23 | this->name = name; 24 | this->health = health; 25 | this->attack = attack; 26 | this->defense = defense; 27 | cout << "Setting up template NPC '" << name << "'\n"; 28 | } 29 | 30 | // copy‐ctor used by clone() 31 | NPC(const NPC& other) { 32 | name = other.name; 33 | health = other.health; 34 | attack = other.attack; 35 | defense = other.defense; 36 | cout << "Cloning NPC '" << name << "'\n"; 37 | } 38 | 39 | // the clone method required by Prototype 40 | Cloneable* clone() const override { 41 | return new NPC(*this); 42 | } 43 | 44 | void describe() { 45 | cout << "NPC " << name << " [HP=" << health << " ATK=" << attack 46 | << " DEF=" << defense << "]\n"; 47 | } 48 | 49 | // setters to tweak the clone… 50 | void setName(const string& n) { 51 | name = n; 52 | } 53 | void setHealth(int h) { 54 | health = h; 55 | } 56 | void setAttack(int a) { 57 | attack = a; 58 | } 59 | void setDefense(int d){ 60 | defense = d; 61 | } 62 | }; 63 | 64 | int main() { 65 | // 1) build one “heavy” template 66 | NPC* alien = new NPC("Alien", 30, 5, 2); 67 | 68 | // 2) quickly clone + tweak as many variants as you like: 69 | NPC* alienCopied1 = dynamic_cast(alien->clone()); 70 | alienCopied1->describe(); 71 | 72 | NPC* alienCopied2 = dynamic_cast(alien->clone()); 73 | alienCopied2->setName("Powerful Alien"); 74 | alienCopied2->setHealth(50); 75 | alienCopied2->describe(); 76 | 77 | // cleanup 78 | delete alien; 79 | delete alienCopied1; 80 | delete alienCopied2; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Lecture 07/Java Code/Bad Design/DocumentEditorClient.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | import java.io.FileWriter; 4 | import java.io.IOException; 5 | 6 | class DocumentEditor { 7 | private List documentElements; 8 | private String renderedDocument; 9 | 10 | public DocumentEditor() { 11 | documentElements = new ArrayList<>(); 12 | renderedDocument = ""; 13 | } 14 | 15 | // Adds text as a plain string 16 | public void addText(String text) { 17 | documentElements.add(text); 18 | } 19 | 20 | // Adds an image represented by its file path 21 | public void addImage(String imagePath) { 22 | documentElements.add(imagePath); 23 | } 24 | 25 | // Renders the document by checking the type of each element at runtime 26 | public String renderDocument() { 27 | if (renderedDocument.isEmpty()) { 28 | StringBuilder result = new StringBuilder(); 29 | for (String element : documentElements) { 30 | if (element.length() > 4 && 31 | (element.endsWith(".jpg") || element.endsWith(".png"))) { 32 | result.append("[Image: ").append(element).append("]\n"); 33 | } else { 34 | result.append(element).append("\n"); 35 | } 36 | } 37 | renderedDocument = result.toString(); 38 | } 39 | return renderedDocument; 40 | } 41 | 42 | public void saveToFile() { 43 | try { 44 | FileWriter writer = new FileWriter("document.txt"); 45 | writer.write(renderDocument()); 46 | writer.close(); 47 | System.out.println("Document saved to document.txt"); 48 | } catch (IOException e) { 49 | System.out.println("Error: Unable to open file for writing."); 50 | } 51 | } 52 | } 53 | 54 | public class DocumentEditorClient { 55 | public static void main(String[] args) { 56 | DocumentEditor editor = new DocumentEditor(); 57 | editor.addText("Hello, world!"); 58 | editor.addImage("picture.jpg"); 59 | editor.addText("This is a document editor."); 60 | 61 | System.out.println(editor.renderDocument()); 62 | 63 | editor.saveToFile(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Lecture 25/Java Code/BridgePattern.java: -------------------------------------------------------------------------------- 1 | 2 | // Implementation Hierarchy: Engine interface (LLL) 3 | interface Engine { 4 | void start(); 5 | } 6 | 7 | // Concrete Implementors (LLL) 8 | class PetrolEngine implements Engine { 9 | @Override 10 | public void start() { 11 | System.out.println("Petrol engine starting with ignition!"); 12 | } 13 | } 14 | 15 | class DieselEngine implements Engine { 16 | @Override 17 | public void start() { 18 | System.out.println("Diesel engine roaring to life!"); 19 | } 20 | } 21 | 22 | class ElectricEngine implements Engine { 23 | @Override 24 | public void start() { 25 | System.out.println("Electric engine powering up silently!"); 26 | } 27 | } 28 | 29 | // Abstraction Hierarchy: Car (HLL) 30 | abstract class Car { 31 | protected Engine engine; 32 | public Car(Engine e) { 33 | this.engine = e; 34 | } 35 | public abstract void drive(); 36 | } 37 | 38 | // Refined Abstraction: Sedan 39 | class Sedan extends Car { 40 | public Sedan(Engine e) { 41 | super(e); 42 | } 43 | 44 | @Override 45 | public void drive() { 46 | engine.start(); 47 | System.out.println("Driving a Sedan on the highway."); 48 | } 49 | } 50 | 51 | // Refined Abstraction: SUV 52 | class SUV extends Car { 53 | public SUV(Engine e) { 54 | super(e); 55 | } 56 | 57 | @Override 58 | public void drive() { 59 | engine.start(); 60 | System.out.println("Driving an SUV off-road."); 61 | } 62 | } 63 | 64 | public class BridgePattern { 65 | public static void main(String[] args) { 66 | // Create Engine implementations 67 | Engine petrolEng = new PetrolEngine(); 68 | Engine dieselEng = new DieselEngine(); 69 | Engine electricEng = new ElectricEngine(); 70 | 71 | // Create Car abstractions, injecting Engine implementations 72 | Car mySedan = new Sedan(petrolEng); 73 | Car mySUV = new SUV(electricEng); 74 | Car yourSUV = new SUV(dieselEng); 75 | 76 | // Use the cars 77 | mySedan.drive(); // Petrol engine + Sedan 78 | mySUV.drive(); // Electric engine + SUV 79 | yourSUV.drive(); // Diesel engine + SUV 80 | 81 | // No explicit cleanup needed in Java 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Lecture 25/C++ Code/BridgePattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Implementation Hierarchy: Engine interface (LLL) 7 | class Engine { 8 | public: 9 | virtual void start() = 0; 10 | virtual ~Engine() {} 11 | }; 12 | 13 | // Concrete Implementors (LLL) 14 | class PetrolEngine : public Engine { 15 | public: 16 | void start() override { 17 | cout << "Petrol engine starting with ignition!" << endl; 18 | } 19 | }; 20 | 21 | class DieselEngine : public Engine { 22 | public: 23 | void start() override { 24 | cout << "Diesel engine roaring to life!" << endl; 25 | } 26 | }; 27 | 28 | class ElectricEngine : public Engine { 29 | public: 30 | void start() override { 31 | cout << "Electric engine powering up silently!" << endl; 32 | } 33 | }; 34 | 35 | // Abstraction Hierarchy: Car (HLL) 36 | class Car { 37 | protected: 38 | Engine* engine; 39 | public: 40 | Car(Engine* e) { 41 | engine = e; 42 | } 43 | virtual void drive() = 0; 44 | }; 45 | 46 | // Refined Abstraction: Sedan 47 | class Sedan : public Car { 48 | public: 49 | Sedan(Engine* e) : Car(e) {} 50 | 51 | void drive() override { 52 | engine->start(); 53 | cout << "Driving a Sedan on the highway." << endl; 54 | } 55 | }; 56 | 57 | // Refined Abstraction: SUV 58 | class SUV : public Car { 59 | public: 60 | SUV(Engine* e) : Car(e) {} 61 | 62 | void drive() override { 63 | engine->start(); 64 | cout << "Driving an SUV off-road." << endl; 65 | } 66 | }; 67 | 68 | int main() { 69 | // Create Engine implementations on the heap 70 | Engine* petrolEng = new PetrolEngine(); 71 | Engine* dieselEng = new DieselEngine(); 72 | Engine* electricEng = new ElectricEngine(); 73 | 74 | // Create Car abstractions, injecting Engine implementations 75 | Car* mySedan = new Sedan(petrolEng); 76 | Car* mySUV = new SUV(electricEng); 77 | Car* yourSUV = new SUV(dieselEng); // electric 78 | 79 | // Use the cars 80 | mySedan->drive(); // Petrol engine + Sedan 81 | mySUV->drive(); // Electric engine + SUV 82 | yourSUV->drive(); // Diesel engine + SUV 83 | 84 | // Clean up 85 | // delete mySedan; 86 | // delete mySUV; 87 | // delete yourSUV; 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /Lecture 05/C++ Code/SRP/SRP_followed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Product class representing any item in eCommerce. 7 | class Product { 8 | public: 9 | string name; 10 | double price; 11 | 12 | Product(string name, double price) { 13 | this->name = name; 14 | this->price = price; 15 | } 16 | }; 17 | 18 | //1. ShoppingCart: Only responsible for Cart related business logic. 19 | class ShoppingCart { 20 | private: 21 | vector products; // Store heap-allocated products 22 | 23 | public: 24 | void addProduct(Product* p) { 25 | products.push_back(p); 26 | } 27 | 28 | const vector& getProducts() { 29 | return products; 30 | } 31 | 32 | //Calculates total price in cart. 33 | double calculateTotal() { 34 | double total = 0; 35 | for (auto p : products) { 36 | total += p->price; 37 | } 38 | return total; 39 | } 40 | }; 41 | 42 | // 2. ShoppingCartPrinter: Only responsible for printing invoices 43 | class ShoppingCartPrinter { 44 | private: 45 | ShoppingCart* cart; 46 | 47 | public: 48 | ShoppingCartPrinter(ShoppingCart* cart) { 49 | this->cart = cart; 50 | } 51 | 52 | void printInvoice() { 53 | cout << "Shopping Cart Invoice:\n"; 54 | for (auto p : cart->getProducts()) { 55 | cout << p->name << " - Rs " << p->price << endl; 56 | } 57 | cout << "Total: Rs " << cart->calculateTotal() << endl; 58 | } 59 | }; 60 | 61 | // 3. ShoppingCartStorage: Only responsible for saving cart to DB 62 | class ShoppingCartStorage { 63 | private: 64 | ShoppingCart* cart; 65 | 66 | public: 67 | ShoppingCartStorage(ShoppingCart* cart) { 68 | this->cart = cart; 69 | } 70 | 71 | void saveToDatabase() { 72 | cout << "Saving shopping cart to database..." << endl; 73 | } 74 | }; 75 | 76 | int main() { 77 | ShoppingCart* cart = new ShoppingCart(); 78 | 79 | cart->addProduct(new Product("Laptop", 50000)); 80 | cart->addProduct(new Product("Mouse", 2000)); 81 | 82 | ShoppingCartPrinter* printer = new ShoppingCartPrinter(cart); 83 | printer->printInvoice(); 84 | 85 | ShoppingCartStorage* db = new ShoppingCartStorage(cart); 86 | db->saveToDatabase(); 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /Lecture 05/Java Code/SRP/SRPFollowed.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | // Product class representing any item in eCommerce. 5 | class Product { 6 | public String name; 7 | public double price; 8 | 9 | public Product(String name, double price) { 10 | this.name = name; 11 | this.price = price; 12 | } 13 | } 14 | 15 | // 1. ShoppingCart: Only responsible for Cart related business logic. 16 | class ShoppingCart { 17 | private List products = new ArrayList<>(); 18 | 19 | public void addProduct(Product p) { 20 | products.add(p); 21 | } 22 | 23 | public List getProducts() { 24 | return products; 25 | } 26 | 27 | // Calculates total price in cart. 28 | public double calculateTotal() { 29 | double total = 0; 30 | for (Product p : products) { 31 | total += p.price; 32 | } 33 | return total; 34 | } 35 | } 36 | 37 | // 2. ShoppingCartPrinter: Only responsible for printing invoices 38 | class ShoppingCartPrinter { 39 | private ShoppingCart cart; 40 | 41 | public ShoppingCartPrinter(ShoppingCart cart) { 42 | this.cart = cart; 43 | } 44 | 45 | public void printInvoice() { 46 | System.out.println("Shopping Cart Invoice:"); 47 | for (Product p : cart.getProducts()) { 48 | System.out.println(p.name + " - Rs " + p.price); 49 | } 50 | System.out.println("Total: Rs " + cart.calculateTotal()); 51 | } 52 | } 53 | 54 | // 3. ShoppingCartStorage: Only responsible for saving cart to DB 55 | class ShoppingCartStorage { 56 | private ShoppingCart cart; 57 | 58 | public ShoppingCartStorage(ShoppingCart cart) { 59 | this.cart = cart; 60 | } 61 | 62 | public void saveToDatabase() { 63 | System.out.println("Saving shopping cart to database..."); 64 | } 65 | } 66 | 67 | public class SRPFollowed { 68 | public static void main(String[] args) { 69 | ShoppingCart cart = new ShoppingCart(); 70 | 71 | cart.addProduct(new Product("Laptop", 50000)); 72 | cart.addProduct(new Product("Mouse", 2000)); 73 | 74 | ShoppingCartPrinter printer = new ShoppingCartPrinter(cart); 75 | printer.printInvoice(); 76 | 77 | ShoppingCartStorage db = new ShoppingCartStorage(cart); 78 | db.saveToDatabase(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Lecture 18/Java Code/MusicPlayerSystem/MusicPlayerApplication/strategies/RandomPlayStrategy.java: -------------------------------------------------------------------------------- 1 | package MusicPlayerApplication.strategies; 2 | 3 | import MusicPlayerApplication.models.Playlist; 4 | import MusicPlayerApplication.models.Song; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Random; 9 | import java.util.Stack; 10 | 11 | public class RandomPlayStrategy implements PlayStrategy { 12 | private Playlist currentPlaylist; 13 | private List remainingSongs; 14 | private Stack history; 15 | private Random random; 16 | 17 | public RandomPlayStrategy() { 18 | currentPlaylist = null; 19 | random = new Random(); 20 | } 21 | 22 | @Override 23 | public void setPlaylist(Playlist playlist) { 24 | currentPlaylist = playlist; 25 | if (currentPlaylist == null || currentPlaylist.getSize() == 0) return; 26 | 27 | remainingSongs = new ArrayList<>(currentPlaylist.getSongs()); 28 | history = new Stack<>(); 29 | } 30 | 31 | @Override 32 | public boolean hasNext() { 33 | return currentPlaylist != null && !remainingSongs.isEmpty(); 34 | } 35 | 36 | // Next in Loop 37 | @Override 38 | public Song next() { 39 | if (currentPlaylist == null || currentPlaylist.getSize() == 0) { 40 | throw new RuntimeException("No playlist loaded or playlist is empty."); 41 | } 42 | if (remainingSongs.isEmpty()) { 43 | throw new RuntimeException("No songs left to play"); 44 | } 45 | 46 | int idx = random.nextInt(remainingSongs.size()); 47 | Song selectedSong = remainingSongs.get(idx); 48 | 49 | // Remove the selectedSong from the list. (Swap and pop to remove in O(1)) 50 | int lastIndex = remainingSongs.size() - 1; 51 | remainingSongs.set(idx, remainingSongs.get(lastIndex)); 52 | remainingSongs.remove(lastIndex); 53 | 54 | history.push(selectedSong); 55 | return selectedSong; 56 | } 57 | 58 | @Override 59 | public boolean hasPrevious() { 60 | return history.size() > 0; 61 | } 62 | 63 | @Override 64 | public Song previous() { 65 | if (history.isEmpty()) { 66 | throw new RuntimeException("No previous song available."); 67 | } 68 | 69 | Song song = history.pop(); 70 | return song; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Lecture 06/Java Code/ISP/ISPViolated.java: -------------------------------------------------------------------------------- 1 | 2 | // Single interface for all shapes (Violates ISP) 3 | interface Shape { 4 | double area(); 5 | double volume(); // 2D shapes don't have volume! 6 | } 7 | 8 | // Square is a 2D shape but is forced to implement volume() 9 | class Square implements Shape { 10 | private double side; 11 | 12 | public Square(double s) { 13 | this.side = s; 14 | } 15 | 16 | @Override 17 | public double area() { 18 | return side * side; 19 | } 20 | 21 | @Override 22 | public double volume() { 23 | throw new UnsupportedOperationException("Volume not applicable for Square"); // Unnecessary method 24 | } 25 | } 26 | 27 | // Rectangle is also a 2D shape but is forced to implement volume() 28 | class Rectangle implements Shape { 29 | private double length, width; 30 | 31 | public Rectangle(double l, double w) { 32 | this.length = l; 33 | this.width = w; 34 | } 35 | 36 | @Override 37 | public double area() { 38 | return length * width; 39 | } 40 | 41 | @Override 42 | public double volume() { 43 | throw new UnsupportedOperationException("Volume not applicable for Rectangle"); // Unnecessary method 44 | } 45 | } 46 | 47 | // Cube is a 3D shape, so it actually has a volume 48 | class Cube implements Shape { 49 | private double side; 50 | 51 | public Cube(double s) { 52 | this.side = s; 53 | } 54 | 55 | @Override 56 | public double area() { 57 | return 6 * side * side; 58 | } 59 | 60 | @Override 61 | public double volume() { 62 | return side * side * side; 63 | } 64 | } 65 | 66 | public class ISPViolated { 67 | public static void main(String[] args) { 68 | Shape square = new Square(5); 69 | Shape rectangle = new Rectangle(4, 6); 70 | Shape cube = new Cube(3); 71 | 72 | System.out.println("Square Area: " + square.area()); 73 | System.out.println("Rectangle Area: " + rectangle.area()); 74 | System.out.println("Cube Area: " + cube.area()); 75 | System.out.println("Cube Volume: " + cube.volume()); 76 | 77 | try { 78 | System.out.println("Square Volume: " + square.volume()); // Will throw an exception 79 | } catch (UnsupportedOperationException e) { 80 | System.out.println("Exception: " + e.getMessage()); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Lecture 13/Java Code/DecoratorPattern.java: -------------------------------------------------------------------------------- 1 | // Component Interface: defines a common interface for Mario and all power-up decorators. 2 | interface Character { 3 | String getAbilities(); 4 | } 5 | 6 | // Concrete Component: Basic Mario character with no power-ups. 7 | class Mario implements Character { 8 | public String getAbilities() { 9 | return "Mario"; 10 | } 11 | } 12 | 13 | // Abstract Decorator: CharacterDecorator "is-a" Character and "has-a" Character. 14 | abstract class CharacterDecorator implements Character { 15 | protected Character character; // Wrapped component 16 | 17 | public CharacterDecorator(Character c) { 18 | this.character = c; 19 | } 20 | } 21 | 22 | // Concrete Decorator: Height-Increasing Power-Up. 23 | class HeightUp extends CharacterDecorator { 24 | public HeightUp(Character c) { 25 | super(c); 26 | } 27 | 28 | public String getAbilities() { 29 | return character.getAbilities() + " with HeightUp"; 30 | } 31 | } 32 | 33 | // Concrete Decorator: Gun Shooting Power-Up. 34 | class GunPowerUp extends CharacterDecorator { 35 | public GunPowerUp(Character c) { 36 | super(c); 37 | } 38 | 39 | public String getAbilities() { 40 | return character.getAbilities() + " with Gun"; 41 | } 42 | } 43 | 44 | // Concrete Decorator: Star Power-Up (temporary ability). 45 | class StarPowerUp extends CharacterDecorator { 46 | public StarPowerUp(Character c) { 47 | super(c); 48 | } 49 | 50 | public String getAbilities() { 51 | return character.getAbilities() + " with Star Power (Limited Time)"; 52 | } 53 | } 54 | 55 | public class DecoratorPattern { 56 | public static void main(String[] args) { 57 | // Create a basic Mario character. 58 | Character mario = new Mario(); 59 | System.out.println("Basic Character: " + mario.getAbilities()); 60 | 61 | // Decorate Mario with a HeightUp power-up. 62 | mario = new HeightUp(mario); 63 | System.out.println("After HeightUp: " + mario.getAbilities()); 64 | 65 | // Decorate Mario further with a GunPowerUp. 66 | mario = new GunPowerUp(mario); 67 | System.out.println("After GunPowerUp: " + mario.getAbilities()); 68 | 69 | // Finally, add a StarPowerUp decoration. 70 | mario = new StarPowerUp(mario); 71 | System.out.println("After StarPowerUp: " + mario.getAbilities()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Lecture 21/C++ Code/ProtectionProxy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Interface for Document Reader 7 | class IDocumentReader { 8 | public: 9 | virtual void unlockPDF(string filePath, string password) = 0; 10 | virtual ~IDocumentReader() = default; 11 | }; 12 | 13 | // Concrete Class: Reads the PDF (simulated) 14 | class RealDocumentReader : public IDocumentReader { 15 | public: 16 | void unlockPDF(string filePath, string password) override { 17 | cout << "[RealDocumentReader] Unlocking PDF at: " << filePath << "\n"; 18 | cout << "[RealDocumentReader] PDF unlocked successfully with password: " << password << "\n"; 19 | cout << "[RealDocumentReader] Displaying PDF content...\n"; 20 | } 21 | }; 22 | 23 | // User class with membership status 24 | class User { 25 | public: 26 | string name; 27 | bool premiumMembership; 28 | 29 | User(string name, bool isPremium) { 30 | this->name = name; 31 | this->premiumMembership = isPremium; 32 | } 33 | }; 34 | 35 | // Proxy Class: Controls access to RealDocumentReader 36 | class DocumentProxy : public IDocumentReader { 37 | RealDocumentReader* realReader; 38 | User* user; 39 | 40 | public: 41 | DocumentProxy(User* user) { 42 | realReader = new RealDocumentReader(); 43 | this->user = user; 44 | } 45 | 46 | void unlockPDF(string filePath, string password) override { 47 | if (!user->premiumMembership) { 48 | cout << "[DocumentProxy] Access denied. Only premium members can unlock PDFs.\n"; 49 | return; 50 | } 51 | 52 | // Forwarding the request to the real reader 53 | realReader->unlockPDF(filePath, password); 54 | } 55 | 56 | ~DocumentProxy() { 57 | delete realReader; 58 | } 59 | }; 60 | 61 | // Client code 62 | int main() { 63 | 64 | User* user1 = new User("Rohan", false); // Non Premium User 65 | User* user2 = new User("Rashmi", true); // premium user 66 | 67 | cout << "== Rohan (Non-Premium) tries to unlock PDF ==\n"; 68 | IDocumentReader* docReader = new DocumentProxy(user1); 69 | docReader->unlockPDF("protected_document.pdf", "secret123"); 70 | delete docReader; 71 | 72 | cout << "\n== Rashmi (Premium) unlocks PDF ==\n"; 73 | docReader = new DocumentProxy(user2); 74 | docReader->unlockPDF("protected_document.pdf", "secret123"); 75 | delete docReader; 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /Lecture 05/Java Code/OCP/OCPViolated.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | // Product class representing any item in eCommerce. 5 | class Product { 6 | String name; 7 | double price; 8 | 9 | Product(String name, double price) { 10 | this.name = name; 11 | this.price = price; 12 | } 13 | } 14 | 15 | // 1. ShoppingCart: Only responsible for Cart related business logic. 16 | class ShoppingCart { 17 | private List products = new ArrayList<>(); 18 | 19 | void addProduct(Product p) { 20 | products.add(p); 21 | } 22 | 23 | List getProducts() { 24 | return products; 25 | } 26 | 27 | double calculateTotal() { 28 | double total = 0; 29 | for (Product p : products) { 30 | total += p.price; 31 | } 32 | return total; 33 | } 34 | } 35 | 36 | // 2. ShoppingCartPrinter: Only responsible for printing invoices 37 | class ShoppingCartPrinter { 38 | private ShoppingCart cart; 39 | 40 | ShoppingCartPrinter(ShoppingCart cart) { 41 | this.cart = cart; 42 | } 43 | 44 | void printInvoice() { 45 | System.out.println("Shopping Cart Invoice:"); 46 | for (Product p : cart.getProducts()) { 47 | System.out.println(p.name + " - Rs " + p.price); 48 | } 49 | System.out.println("Total: Rs " + cart.calculateTotal()); 50 | } 51 | } 52 | 53 | // 3. ShoppingCartStorage: Only responsible for saving cart to DB 54 | class ShoppingCartStorage { 55 | private ShoppingCart cart; 56 | 57 | ShoppingCartStorage(ShoppingCart cart) { 58 | this.cart = cart; 59 | } 60 | 61 | void saveToSQLDatabase() { 62 | System.out.println("Saving shopping cart to SQL DB..."); 63 | } 64 | 65 | void saveToMongoDatabase() { 66 | System.out.println("Saving shopping cart to Mongo DB..."); 67 | } 68 | 69 | void saveToFile() { 70 | System.out.println("Saving shopping cart to File..."); 71 | } 72 | } 73 | 74 | public class OCPViolated { 75 | public static void main(String[] args) { 76 | ShoppingCart cart = new ShoppingCart(); 77 | 78 | cart.addProduct(new Product("Laptop", 50000)); 79 | cart.addProduct(new Product("Mouse", 2000)); 80 | 81 | ShoppingCartPrinter printer = new ShoppingCartPrinter(cart); 82 | printer.printInvoice(); 83 | 84 | ShoppingCartStorage db = new ShoppingCartStorage(cart); 85 | db.saveToSQLDatabase(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Lecture 05/C++ Code/OCP/OCP_violated.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Product class representing any item in eCommerce. 7 | class Product { 8 | public: 9 | string name; 10 | double price; 11 | 12 | Product(string name, double price) { 13 | this->name = name; 14 | this->price = price; 15 | } 16 | }; 17 | 18 | //1. ShoppingCart: Only responsible for Cart related business logic. 19 | class ShoppingCart { 20 | private: 21 | vector products; 22 | 23 | public: 24 | void addProduct(Product* p) { 25 | products.push_back(p); 26 | } 27 | 28 | const vector& getProducts() { 29 | return products; 30 | } 31 | 32 | //Calculates total price in cart. 33 | double calculateTotal() { 34 | double total = 0; 35 | for (auto p : products) { 36 | total += p->price; 37 | } 38 | return total; 39 | } 40 | }; 41 | 42 | // 2. ShoppingCartPrinter: Only responsible for printing invoices 43 | class ShoppingCartPrinter { 44 | private: 45 | ShoppingCart* cart; 46 | 47 | public: 48 | ShoppingCartPrinter(ShoppingCart* cart) { 49 | this->cart = cart; 50 | } 51 | 52 | void printInvoice() { 53 | cout << "Shopping Cart Invoice:\n"; 54 | for (auto p : cart->getProducts()) { 55 | cout << p->name << " - Rs " << p->price << endl; 56 | } 57 | cout << "Total: Rs " << cart->calculateTotal() << endl; 58 | } 59 | }; 60 | 61 | // 3. ShoppingCartStorage: Only responsible for saving cart to DB 62 | class ShoppingCartStorage { 63 | private: 64 | ShoppingCart* cart; 65 | 66 | public: 67 | ShoppingCartStorage(ShoppingCart* cart) { 68 | this->cart = cart; 69 | } 70 | 71 | void saveToSQLDatabase() { 72 | cout << "Saving shopping cart to SQL DB..." << endl; 73 | } 74 | 75 | void saveToMongoDatabase() { 76 | cout << "Saving shopping cart to Mongo DB..." << endl; 77 | } 78 | 79 | void saveToFile() { 80 | cout << "Saving shopping cart to File..." << endl; 81 | } 82 | }; 83 | 84 | int main() { 85 | ShoppingCart* cart = new ShoppingCart(); 86 | 87 | cart->addProduct(new Product("Laptop", 50000)); 88 | cart->addProduct(new Product("Mouse", 2000)); 89 | 90 | ShoppingCartPrinter* printer = new ShoppingCartPrinter(cart); 91 | printer->printInvoice(); 92 | 93 | ShoppingCartStorage* db = new ShoppingCartStorage(cart); 94 | db->saveToSQLDatabase(); 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /Lecture 16/Java Code/AdapterPattern.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 1. Target interface expected by the client 4 | interface IReports { 5 | // now takes the raw data string and returns JSON 6 | String getJsonData(String data); 7 | } 8 | 9 | // 2. Adaptee: provides XML data from a raw input 10 | class XmlDataProvider { 11 | // Expect data in "name:id" format (e.g. "Alice:42") 12 | String getXmlData(String data) { 13 | int sep = data.indexOf(':'); 14 | String name = data.substring(0, sep); 15 | String id = data.substring(sep + 1); 16 | // Build an XML representation 17 | return "" 18 | + "" + name + "" 19 | + "" + id + "" 20 | + ""; 21 | } 22 | } 23 | 24 | // 3. Adapter: implements IReports by converting XML → JSON 25 | class XmlDataProviderAdapter implements IReports { 26 | private XmlDataProvider xmlProvider; 27 | public XmlDataProviderAdapter(XmlDataProvider provider) { 28 | this.xmlProvider = provider; 29 | } 30 | 31 | public String getJsonData(String data) { 32 | // 1. Get XML from the adaptee 33 | String xml = xmlProvider.getXmlData(data); 34 | 35 | // 2. Naïvely parse out and values 36 | int startName = xml.indexOf("") + 6; 37 | int endName = xml.indexOf(""); 38 | String name = xml.substring(startName, endName); 39 | 40 | int startId = xml.indexOf("") + 4; 41 | int endId = xml.indexOf(""); 42 | String id = xml.substring(startId, endId); 43 | 44 | // 3. Build and return JSON 45 | return "{\"name\":\"" + name + "\", \"id\":" + id + "}"; 46 | } 47 | } 48 | 49 | // 4. Client code works only with IReports 50 | class Client { 51 | public void getReport(IReports report, String rawData) { 52 | System.out.println("Processed JSON: " 53 | + report.getJsonData(rawData)); 54 | } 55 | } 56 | 57 | public class AdapterPattern { 58 | public static void main(String[] args) { 59 | // 1. Create the adaptee 60 | XmlDataProvider xmlProv = new XmlDataProvider(); 61 | 62 | // 2. Make our adapter 63 | IReports adapter = new XmlDataProviderAdapter(xmlProv); 64 | 65 | // 3. Give it some raw data 66 | String rawData = "Alice:42"; 67 | 68 | // 4. Client prints the JSON 69 | Client client = new Client(); 70 | 71 | client.getReport(adapter, rawData); 72 | // → Processed JSON: {"name":"Alice", "id":42} 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Lecture 11/C++ Code/Tomato/models/Order.h: -------------------------------------------------------------------------------- 1 | #ifndef ORDER_H 2 | #define ORDER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "User.h" 8 | #include "Restaurant.h" 9 | #include "MenuItem.h" 10 | #include "../strategies/PaymentStrategy.h" 11 | #include "../utils/TimeUtils.h" 12 | using namespace std; 13 | 14 | class Order { 15 | protected: 16 | static int nextOrderId; 17 | int orderId; 18 | User* user; 19 | Restaurant* restaurant; 20 | vector items; 21 | PaymentStrategy* paymentStrategy; 22 | double total; 23 | string scheduled; 24 | 25 | public: 26 | Order() { 27 | user = nullptr; 28 | restaurant = nullptr; 29 | paymentStrategy = nullptr; 30 | total = 0.0; 31 | scheduled = ""; 32 | orderId = ++nextOrderId; 33 | } 34 | 35 | virtual ~Order() { 36 | delete paymentStrategy; 37 | } 38 | 39 | bool processPayment() { 40 | if (paymentStrategy) { 41 | paymentStrategy->pay(total); 42 | return true; 43 | } else { 44 | cout << "Please choose a payment mode first" << endl; 45 | return false; 46 | } 47 | } 48 | 49 | virtual string getType() const = 0; 50 | 51 | //Getter and Setters 52 | int getOrderId() const { 53 | return orderId; 54 | } 55 | 56 | void setUser(User* u) { 57 | user = u; 58 | } 59 | 60 | User* getUser() const { 61 | return user; 62 | } 63 | 64 | void setRestaurant(Restaurant* r) { 65 | restaurant = r; 66 | } 67 | 68 | Restaurant* getRestaurant() const { 69 | return restaurant; 70 | } 71 | 72 | void setItems(const vector& its) { 73 | items = its; 74 | total = 0; 75 | for (auto &i : items) { 76 | total += i.getPrice(); 77 | } 78 | } 79 | 80 | const vector& getItems() const { 81 | return items; 82 | } 83 | 84 | void setPaymentStrategy(PaymentStrategy* p) { 85 | paymentStrategy = p; 86 | } 87 | 88 | void setScheduled(const string& s) { 89 | scheduled = s; 90 | } 91 | 92 | string getScheduled() const { 93 | return scheduled; 94 | } 95 | 96 | double getTotal() const { 97 | return total; 98 | } 99 | 100 | void setTotal(int total) { 101 | this->total = total; 102 | } 103 | }; 104 | 105 | int Order::nextOrderId = 0; 106 | 107 | #endif // ORDER_H 108 | -------------------------------------------------------------------------------- /Lecture 13/C++ Code/DecoratorPattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Component Interface: defines a common interface for Mario and all power-up decorators. 7 | class Character { 8 | public: 9 | virtual string getAbilities() const = 0; 10 | virtual ~Character() {} // Virtual destructor 11 | }; 12 | 13 | // Concrete Component: Basic Mario character with no power-ups. 14 | class Mario : public Character { 15 | public: 16 | string getAbilities() const override { 17 | return "Mario"; 18 | } 19 | }; 20 | 21 | // Abstract Decorator: CharacterDecorator "is-a" Charatcer and "has-a" Character. 22 | class CharacterDecorator : public Character { 23 | protected: 24 | Character* character; // Wrapped component 25 | public: 26 | CharacterDecorator(Character* c){ 27 | this->character = c; 28 | } 29 | 30 | }; 31 | 32 | // Concrete Decorator: Height-Increasing Power-Up. 33 | class HeightUp : public CharacterDecorator { 34 | public: 35 | HeightUp(Character* c) : CharacterDecorator(c) { } 36 | 37 | string getAbilities() const override { 38 | return character->getAbilities() + " with HeightUp"; 39 | } 40 | 41 | }; 42 | 43 | // Concrete Decorator: Gun Shooting Power-Up. 44 | class GunPowerUp : public CharacterDecorator { 45 | public: 46 | GunPowerUp(Character* c) : CharacterDecorator(c) { } 47 | 48 | string getAbilities() const override { 49 | return character->getAbilities() + " with Gun"; 50 | } 51 | }; 52 | 53 | // Concrete Decorator: Star Power-Up (temporary ability). 54 | class StarPowerUp : public CharacterDecorator { 55 | public: 56 | StarPowerUp(Character* c) : CharacterDecorator(c) { } 57 | 58 | string getAbilities() const override { 59 | return character->getAbilities() + " with Star Power (Limited Time)"; 60 | } 61 | 62 | ~StarPowerUp() { 63 | cout << "Destroying StarPowerUp Decorator" << endl; 64 | } 65 | }; 66 | 67 | int main() { 68 | // Create a basic Mario character. 69 | Character* mario = new Mario(); 70 | cout << "Basic Character: " << mario->getAbilities() << endl; 71 | 72 | // Decorate Mario with a HeightUp power-up. 73 | mario = new HeightUp(mario); 74 | cout << "After HeightUp: " << mario->getAbilities() << endl; 75 | 76 | // Decorate Mario further with a GunPowerUp. 77 | mario = new GunPowerUp(mario); 78 | cout << "After GunPowerUp: " << mario->getAbilities() << endl; 79 | 80 | // Finally, add a StarPowerUp decoration. 81 | mario = new StarPowerUp(mario); 82 | cout << "After StarPowerUp: " << mario->getAbilities() << endl; 83 | 84 | delete mario; 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /Lecture 35/C++ Code/WithoutMediator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // Each User knows *all* the others directly. 7 | // If you have N users, you wind up wiring N*(N–1)/2 connections, 8 | // and every new feature (mute, private send, logging...) lives in User too. 9 | 10 | class User { 11 | private: 12 | string name; 13 | vector peers; 14 | vector mutedUsers; 15 | 16 | public: 17 | User(const string& n) { 18 | name = n; 19 | } 20 | 21 | // must manually connect every pair → N^2 wiring 22 | void addPeer(User* u) { 23 | peers.push_back(u); 24 | } 25 | 26 | // duplication: everyone has its own mute list 27 | void mute(const string& userToMute) { 28 | mutedUsers.push_back(userToMute); 29 | } 30 | 31 | // broadcast to all peers 32 | void send(const string& msg) { 33 | cout << "[" << name << " broadcasts]: " << msg << endl; 34 | for (User* peer : peers) { 35 | 36 | // if they have muted me dont send. 37 | if(!peer->isMuted(name)) { 38 | peer->receive(name, msg); 39 | } 40 | } 41 | } 42 | 43 | bool isMuted(string userName) { 44 | for(auto name : mutedUsers) { 45 | if(name == userName) { 46 | return true; 47 | } 48 | } 49 | return false; 50 | } 51 | 52 | // private send - duplicated in every class 53 | void sendTo(User* target, const string& msg) { 54 | cout << "[" << name << "→" << target->name << "]: " << msg << endl; 55 | if(!target->isMuted(name)) { 56 | target->receive(name, msg); 57 | } 58 | } 59 | 60 | void receive(const string& from, const string& msg) { 61 | cout << " " << name << " got from " << from << ": " << msg << endl; 62 | } 63 | }; 64 | 65 | int main() { 66 | // create users 67 | User* user1 = new User("Rohan"); 68 | User* user2 = new User("Neha"); 69 | User* user3 = new User("Mohan"); 70 | 71 | // wire up peers (each knows each other) → n*(n-1)/2 connections 72 | user1->addPeer(user2); 73 | user2->addPeer(user1); 74 | 75 | user1->addPeer(user3); 76 | user3->addPeer(user1); 77 | 78 | user2->addPeer(user3); 79 | user3->addPeer(user2); 80 | 81 | // mute example: Mohan mutes Rohan (Hence Rohan add Mohan to its muted list). 82 | user1->mute("Mohan"); 83 | 84 | // broadcast 85 | user1->send("Hello everyone!"); 86 | 87 | // private 88 | user3->sendTo(user2, "Hey Neha!"); 89 | 90 | // cleanup 91 | delete user1; 92 | delete user2; 93 | delete user3; 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /Lecture 16/C++ Code/AdpaterPattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // 1. Target interface expected by the client 7 | class IReports { 8 | public: 9 | // now takes the raw data string and returns JSON 10 | virtual string getJsonData(const string& data) = 0; 11 | virtual ~IReports() {} 12 | }; 13 | 14 | // 2. Adaptee: provides XML data from a raw input 15 | class XmlDataProvider { 16 | public: 17 | // Expect data in "name:id" format (e.g. "Alice:42") 18 | string getXmlData(const string& data) { 19 | size_t sep = data.find(':'); 20 | string name = data.substr(0, sep); 21 | string id = data.substr(sep + 1); 22 | // Build an XML representation 23 | return "" 24 | "" + name + "" 25 | "" + id + "" 26 | ""; 27 | } 28 | }; 29 | 30 | // 3. Adapter: implements IReports by converting XML → JSON 31 | class XmlDataProviderAdapter : public IReports { 32 | private: 33 | XmlDataProvider* xmlProvider; 34 | public: 35 | XmlDataProviderAdapter(XmlDataProvider* provider) { 36 | this->xmlProvider = provider; 37 | } 38 | 39 | string getJsonData(const string& data) override { 40 | // 1. Get XML from the adaptee 41 | string xml = xmlProvider->getXmlData(data); 42 | 43 | // 2. Naïvely parse out and values 44 | size_t startName = xml.find("") + 6; 45 | size_t endName = xml.find(""); 46 | string name = xml.substr(startName, endName - startName); 47 | 48 | size_t startId = xml.find("") + 4; 49 | size_t endId = xml.find(""); 50 | string id = xml.substr(startId, endId - startId); 51 | 52 | // 3. Build and return JSON 53 | return "{\"name\":\"" + name + "\", \"id\":" + id + "}"; 54 | } 55 | }; 56 | 57 | // 4. Client code works only with IReports 58 | class Client { 59 | public: 60 | void getReport(IReports* report, string rawData) { 61 | cout << "Processed JSON: " 62 | << report->getJsonData(rawData) 63 | << endl; 64 | } 65 | }; 66 | 67 | int main() { 68 | // 1. Create the adaptee 69 | XmlDataProvider* xmlProv = new XmlDataProvider(); 70 | 71 | // 2. Make our adapter 72 | IReports* adapter = new XmlDataProviderAdapter(xmlProv); 73 | 74 | // 3. Give it some raw data 75 | string rawData = "Alice:42"; 76 | 77 | // 4. Client prints the JSON 78 | Client* client = new Client(); 79 | client->getReport(adapter, rawData); 80 | // → Processed JSON: {"name":"Alice", "id":42} 81 | 82 | // 5. Cleanup 83 | delete adapter; 84 | delete xmlProv; 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /Lecture 03/C++ Code/StaticPolymorphism.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /* 7 | Static Polymorphism (Compile-time polymorphism) in real life says that 8 | the same action can behave differently depending on the input parameters. 9 | For example, a Manual car can accelerate by a fixed amount or by a 10 | specific amount you request. In programming, we achieve this via method 11 | overloading: multiple methods with the same name but different signatures. 12 | */ 13 | 14 | class ManualCar { 15 | 16 | private: 17 | string brand; 18 | string model; 19 | bool isEngineOn; 20 | int currentSpeed; 21 | int currentGear; 22 | 23 | public: 24 | ManualCar(string brand, string model) { 25 | this->brand = brand; 26 | this->model = model; 27 | this->isEngineOn = false; 28 | this->currentSpeed = 0; 29 | this->currentGear = 0; 30 | } 31 | 32 | void startEngine() { 33 | isEngineOn = true; 34 | cout << brand << " " << model << " : Engine started." << endl; 35 | } 36 | 37 | void stopEngine() { 38 | isEngineOn = false; 39 | currentSpeed = 0; 40 | cout << brand << " " << model << " : Engine turned off." << endl; 41 | } 42 | 43 | // Overloading accelerate - Static Polymorphism 44 | void accelerate() { 45 | if (!isEngineOn) { 46 | cout << brand << " " << model << " : Cannot accelerate! Engine is off." << endl; 47 | return; 48 | } 49 | currentSpeed += 20; 50 | cout << brand << " " << model << " : Accelerating to " << currentSpeed << " km/h" << endl; 51 | } 52 | 53 | void accelerate(int speed) { 54 | if (!isEngineOn) { 55 | cout << brand << " " << model << " : Cannot accelerate! Engine is off." << endl; 56 | return; 57 | } 58 | currentSpeed += speed; 59 | cout << brand << " " << model << " : Accelerating to " << currentSpeed << " km/h" << endl; 60 | } 61 | 62 | void brake() { 63 | currentSpeed -= 20; 64 | if (currentSpeed < 0) currentSpeed = 0; 65 | cout << brand << " " << model << " : Braking! Speed is now " << currentSpeed << " km/h" << endl; 66 | } 67 | 68 | void shiftGear(int gear) { 69 | currentGear = gear; 70 | cout << brand << " " << model << " : Shifted to gear " << currentGear << endl; 71 | } 72 | }; 73 | 74 | // Main function 75 | int main() { 76 | ManualCar* myManualCar = new ManualCar("Suzuki", "WagonR"); 77 | myManualCar->startEngine(); 78 | myManualCar->accelerate(); 79 | myManualCar->accelerate(40); 80 | myManualCar->brake(); 81 | myManualCar->stopEngine(); 82 | 83 | // Cleanup 84 | delete myManualCar; 85 | 86 | return 0; 87 | } -------------------------------------------------------------------------------- /Lecture 06/Java Code/LSP-Rules/SingatureRules/ExceptionRule.java: -------------------------------------------------------------------------------- 1 | 2 | // Exception Rule: 3 | // A subclass should throw fewer or narrower exceptions 4 | // (but not additional or broader exceptions) than the parent. 5 | // Java enforces this only for checked Exceptions. 6 | 7 | /* 8 | └── java.lang.Exception // Conditions your application might want to catch 9 | ├── java.io.IOException // Checked I/O failures 10 | │ ├── java.io.FileNotFoundException 11 | │ ├── java.io.EOFException 12 | │ └── java.net.MalformedURLException 13 | ├── java.lang.ClassNotFoundException // Checked reflect/… failures 14 | ├── java.lang.InterruptedException // Checked thread interruption 15 | ├── java.sql.SQLException // Checked SQL/database errors 16 | ├── java.text.ParseException // Checked parsing errors 17 | └── java.lang.RuntimeException // Unchecked; subclasses may be thrown anywhere 18 | ├── java.lang.ArithmeticException // e.g. divide by zero 19 | ├── java.lang.NullPointerException 20 | ├── java.lang.ArrayIndexOutOfBoundsException 21 | ├── java.lang.StringIndexOutOfBoundsException 22 | ├── java.lang.IllegalArgumentException 23 | │ └── java.lang.NumberFormatException 24 | ├── java.lang.IllegalStateException 25 | ├── java.lang.UnsupportedOperationException 26 | └── java.lang.IndexOutOfBoundsException // parent of the two “…OutOfBounds” above 27 | */ 28 | 29 | class Parent { 30 | public void getValue() throws RuntimeException { 31 | throw new RuntimeException("Parent error"); 32 | } 33 | } 34 | 35 | // Subclass overrides getValue and throws the narrower ChildException 36 | class Child extends Parent { 37 | @Override 38 | public void getValue() throws ArithmeticException { 39 | throw new ArithmeticException("Child error"); 40 | //throw new Exception("Child error"); // This is wrong & not allowed 41 | } 42 | } 43 | 44 | // Client that invokes getValue and catches the parent exception type 45 | class Client { 46 | private Parent p; 47 | 48 | public Client(Parent p) { 49 | this.p = p; 50 | } 51 | 52 | public void takeValue() { 53 | try { 54 | p.getValue(); 55 | } catch (RuntimeException e) { 56 | System.out.println("RuntimeException occurred: " + e.getMessage()); 57 | } 58 | } 59 | } 60 | 61 | public class ExceptionRule { 62 | public static void main(String[] args) { 63 | Parent parent = new Parent(); 64 | Child child = new Child(); 65 | 66 | Client client = new Client(parent); 67 | //Client client = new Client(child); 68 | 69 | client.takeValue(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Lecture 18/C++ Code/MusicPlayerSystem/MusicPlayerApplication/main.cpp: -------------------------------------------------------------------------------- 1 | #include "MusicPlayerApplication.hpp" 2 | 3 | using namespace std; 4 | 5 | int main() { 6 | try { 7 | auto application = MusicPlayerApplication::getInstance(); 8 | 9 | // Populate library 10 | application->createSongInLibrary("Kesariya", "Arijit Singh", "/music/kesariya.mp3"); 11 | application->createSongInLibrary("Chaiyya Chaiyya", "Sukhwinder Singh", "/music/chaiyya_chaiyya.mp3"); 12 | application->createSongInLibrary("Tum Hi Ho", "Arijit Singh", "/music/tum_hi_ho.mp3"); 13 | application->createSongInLibrary("Jai Ho", "A. R. Rahman", "/music/jai_ho.mp3"); 14 | application->createSongInLibrary("Zinda", "Siddharth Mahadevan", "/music/zinda.mp3"); 15 | 16 | // Create playlist and add songs 17 | application->createPlaylist("Bollywood Vibes"); 18 | application->addSongToPlaylist("Bollywood Vibes", "Kesariya"); 19 | application->addSongToPlaylist("Bollywood Vibes", "Chaiyya Chaiyya"); 20 | application->addSongToPlaylist("Bollywood Vibes", "Tum Hi Ho"); 21 | application->addSongToPlaylist("Bollywood Vibes", "Jai Ho"); 22 | 23 | // Connect device 24 | application->connectAudioDevice(DeviceType::BLUETOOTH); 25 | 26 | //Play/pause a single song 27 | application->playSingleSong("Zinda"); 28 | application->pauseCurrentSong("Zinda"); 29 | application->playSingleSong("Zinda"); // resume 30 | 31 | cout << "\n-- Sequential Playback --\n"; 32 | application->selectPlayStrategy(PlayStrategyType::SEQUENTIAL); 33 | application->loadPlaylist("Bollywood Vibes"); 34 | application->playAllTracksInPlaylist(); 35 | 36 | cout << "\n-- Random Playback --\n"; 37 | application->selectPlayStrategy(PlayStrategyType::RANDOM); 38 | application->loadPlaylist("Bollywood Vibes"); 39 | application->playAllTracksInPlaylist(); 40 | 41 | cout << "\n-- Custom Queue Playback --\n"; 42 | application->selectPlayStrategy(PlayStrategyType::CUSTOM_QUEUE); 43 | application->loadPlaylist("Bollywood Vibes"); 44 | application->queueSongNext("Kesariya"); 45 | application->queueSongNext("Tum Hi Ho"); 46 | application->playAllTracksInPlaylist(); 47 | 48 | cout << "\n-- Play Previous in Sequential --\n"; 49 | application->selectPlayStrategy(PlayStrategyType::SEQUENTIAL); 50 | application->loadPlaylist("Bollywood Vibes"); 51 | application->playAllTracksInPlaylist(); 52 | 53 | application->playPreviousTrackInPlaylist(); 54 | application->playPreviousTrackInPlaylist(); 55 | 56 | } catch (const exception& error) { 57 | cerr << "Error: " << error.what() << endl; 58 | } 59 | return 0; 60 | } -------------------------------------------------------------------------------- /Lecture 35/Java Code/WithoutMediator.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | // Each User knows *all* the others directly. 4 | // If you have N users, you wind up wiring N*(N–1)/2 connections, 5 | // and every new feature (mute, private send, logging...) lives in User too. 6 | class User { 7 | private String name; 8 | private List peers; 9 | private List mutedUsers; 10 | 11 | public User(String n) { 12 | name = n; 13 | peers = new ArrayList<>(); 14 | mutedUsers = new ArrayList<>(); 15 | } 16 | 17 | // must manually connect every pair → N^2 wiring 18 | public void addPeer(User u) { 19 | peers.add(u); 20 | } 21 | 22 | // duplication: everyone has its own mute list 23 | public void mute(String userToMute) { 24 | mutedUsers.add(userToMute); 25 | } 26 | 27 | // broadcast to all peers 28 | public void send(String msg) { 29 | System.out.println("[" + name + " broadcasts]: " + msg); 30 | for (User peer : peers) { 31 | 32 | // if they have muted me dont send. 33 | if(!peer.isMuted(name)) { 34 | peer.receive(name, msg); 35 | } 36 | } 37 | } 38 | 39 | public boolean isMuted(String userName) { 40 | for(String name : mutedUsers) { 41 | if(name.equals(userName)) { 42 | return true; 43 | } 44 | } 45 | return false; 46 | } 47 | 48 | // private send - duplicated in every class 49 | public void sendTo(User target, String msg) { 50 | System.out.println("[" + name + "→" + target.name + "]: " + msg); 51 | if(!target.isMuted(name)) { 52 | target.receive(name, msg); 53 | } 54 | } 55 | 56 | public void receive(String from, String msg) { 57 | System.out.println(" " + name + " got from " + from + ": " + msg); 58 | } 59 | } 60 | 61 | public class WithoutMediator { 62 | public static void main(String[] args) { 63 | // create users 64 | User user1 = new User("Rohan"); 65 | User user2 = new User("Neha"); 66 | User user3 = new User("Mohan"); 67 | 68 | // wire up peers (each knows each other) → n*(n-1)/2 connections 69 | user1.addPeer(user2); 70 | user2.addPeer(user1); 71 | 72 | user1.addPeer(user3); 73 | user3.addPeer(user1); 74 | 75 | user2.addPeer(user3); 76 | user3.addPeer(user2); 77 | 78 | // mute example: Mohan mutes Rohan (Hence Rohan add Mohan to its muted list). 79 | user1.mute("Mohan"); 80 | 81 | // broadcast 82 | user1.send("Hello everyone!"); 83 | 84 | // private 85 | user3.sendTo(user2, "Hey Neha!"); 86 | } 87 | } -------------------------------------------------------------------------------- /Lecture 03/Java Code/StaticPolymorphism.java: -------------------------------------------------------------------------------- 1 | /* 2 | Static Polymorphism (Compile-time polymorphism) in real life says that 3 | the same action can behave differently depending on the input parameters. 4 | For example, a Manual car can accelerate by a fixed amount or by a 5 | specific amount you request. In programming, we achieve this via method 6 | overloading: multiple methods with the same name but different signatures. 7 | */ 8 | 9 | class ManualCar { 10 | private String brand; 11 | private String model; 12 | private boolean isEngineOn; 13 | private int currentSpeed; 14 | private int currentGear; 15 | 16 | public ManualCar(String brand, String model) { 17 | this.brand = brand; 18 | this.model = model; 19 | this.isEngineOn = false; 20 | this.currentSpeed = 0; 21 | this.currentGear = 0; 22 | } 23 | 24 | public void startEngine() { 25 | isEngineOn = true; 26 | System.out.println(brand + " " + model + " : Engine started."); 27 | } 28 | 29 | public void stopEngine() { 30 | isEngineOn = false; 31 | currentSpeed = 0; 32 | System.out.println(brand + " " + model + " : Engine turned off."); 33 | } 34 | 35 | // Overloading accelerate - Static Polymorphism 36 | public void accelerate() { 37 | if (!isEngineOn) { 38 | System.out.println(brand + " " + model + " : Cannot accelerate! Engine is off."); 39 | return; 40 | } 41 | currentSpeed += 20; 42 | System.out.println(brand + " " + model + " : Accelerating to " + currentSpeed + " km/h"); 43 | } 44 | 45 | public void accelerate(int speed) { 46 | if (!isEngineOn) { 47 | System.out.println(brand + " " + model + " : Cannot accelerate! Engine is off."); 48 | return; 49 | } 50 | currentSpeed += speed; 51 | System.out.println(brand + " " + model + " : Accelerating to " + currentSpeed + " km/h"); 52 | } 53 | 54 | public void brake() { 55 | currentSpeed -= 20; 56 | if (currentSpeed < 0) { 57 | currentSpeed = 0; 58 | } 59 | System.out.println(brand + " " + model + " : Braking! Speed is now " 60 | + currentSpeed + " km/h"); 61 | } 62 | 63 | public void shiftGear(int gear) { 64 | currentGear = gear; 65 | System.out.println(brand + " " + model + " : Shifted to gear " + currentGear); 66 | } 67 | } 68 | 69 | public class StaticPolymorphism { 70 | public static void main(String[] args) { 71 | ManualCar myManualCar = new ManualCar("Suzuki", "WagonR"); 72 | myManualCar.startEngine(); 73 | myManualCar.accelerate(); 74 | myManualCar.accelerate(40); 75 | myManualCar.brake(); 76 | myManualCar.stopEngine(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Lecture 05/Java Code/OCP/OCPFollowed.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | // Product class representing any item in eCommerce. 5 | class Product { 6 | public String name; 7 | public double price; 8 | 9 | public Product(String name, double price) { 10 | this.name = name; 11 | this.price = price; 12 | } 13 | } 14 | 15 | // 1. ShoppingCart: Only responsible for Cart related business logic. 16 | class ShoppingCart { 17 | private List products = new ArrayList<>(); 18 | 19 | public void addProduct(Product p) { 20 | products.add(p); 21 | } 22 | 23 | public List getProducts() { 24 | return products; 25 | } 26 | 27 | // Calculates total price in cart. 28 | public double calculateTotal() { 29 | double total = 0; 30 | for (Product p : products) { 31 | total += p.price; 32 | } 33 | return total; 34 | } 35 | } 36 | 37 | // 2. ShoppingCartPrinter: Only responsible for printing invoices 38 | class ShoppingCartPrinter { 39 | private ShoppingCart cart; 40 | 41 | public ShoppingCartPrinter(ShoppingCart cart) { 42 | this.cart = cart; 43 | } 44 | 45 | public void printInvoice() { 46 | System.out.println("Shopping Cart Invoice:"); 47 | for (Product p : cart.getProducts()) { 48 | System.out.println(p.name + " - Rs " + p.price); 49 | } 50 | System.out.println("Total: Rs " + cart.calculateTotal()); 51 | } 52 | } 53 | 54 | interface Persistence { 55 | void save(ShoppingCart cart); 56 | } 57 | 58 | class SQLPersistence implements Persistence { 59 | @Override 60 | public void save(ShoppingCart cart) { 61 | System.out.println("Saving shopping cart to SQL DB..."); 62 | } 63 | } 64 | 65 | class MongoPersistence implements Persistence { 66 | @Override 67 | public void save(ShoppingCart cart) { 68 | System.out.println("Saving shopping cart to MongoDB..."); 69 | } 70 | } 71 | 72 | class FilePersistence implements Persistence { 73 | @Override 74 | public void save(ShoppingCart cart) { 75 | System.out.println("Saving shopping cart to a file..."); 76 | } 77 | } 78 | 79 | public class OCPFollowed { 80 | public static void main(String[] args) { 81 | ShoppingCart cart = new ShoppingCart(); 82 | cart.addProduct(new Product("Laptop", 50000)); 83 | cart.addProduct(new Product("Mouse", 2000)); 84 | 85 | ShoppingCartPrinter printer = new ShoppingCartPrinter(cart); 86 | printer.printInvoice(); 87 | 88 | Persistence db = new SQLPersistence(); 89 | Persistence mongo = new MongoPersistence(); 90 | Persistence file = new FilePersistence(); 91 | 92 | db.save(cart); // Save to SQL database 93 | mongo.save(cart); // Save to MongoDB 94 | file.save(cart); // Save to File 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Lecture 12/Java Code/ObserverDesignPattern.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | interface ISubscriber { 5 | void update(); 6 | } 7 | 8 | // Observable interface: a YouTube channel interface 9 | interface IChannel { 10 | void subscribe(ISubscriber subscriber); 11 | void unsubscribe(ISubscriber subscriber); 12 | void notifySubscribers(); 13 | } 14 | 15 | // Concrete Subject: a YouTube channel that observers can subscribe to 16 | class Channel implements IChannel { 17 | private List subscribers; 18 | private String name; 19 | private String latestVideo; 20 | 21 | public Channel(String name) { 22 | this.name = name; 23 | this.subscribers = new ArrayList<>(); 24 | } 25 | 26 | @Override 27 | public void subscribe(ISubscriber subscriber) { 28 | if (!subscribers.contains(subscriber)) { 29 | subscribers.add(subscriber); 30 | } 31 | } 32 | 33 | @Override 34 | public void unsubscribe(ISubscriber subscriber) { 35 | subscribers.remove(subscriber); 36 | } 37 | 38 | @Override 39 | public void notifySubscribers() { 40 | for (ISubscriber sub : subscribers) { 41 | sub.update(); 42 | } 43 | } 44 | 45 | public void uploadVideo(String title) { 46 | latestVideo = title; 47 | System.out.println("\n[" + name + " uploaded \"" + title + "\"]"); 48 | notifySubscribers(); 49 | } 50 | 51 | public String getVideoData() { 52 | return "\nCheckout our new Video : " + latestVideo + "\n"; 53 | } 54 | } 55 | 56 | // Concrete Observer: represents a subscriber to the channel 57 | class Subscriber implements ISubscriber { 58 | private String name; 59 | private Channel channel; 60 | 61 | public Subscriber(String name, Channel channel) { 62 | this.name = name; 63 | this.channel = channel; 64 | } 65 | 66 | @Override 67 | public void update() { 68 | System.out.println("Hey " + name + "," + channel.getVideoData()); 69 | } 70 | } 71 | 72 | public class ObserverDesignPattern { 73 | public static void main(String[] args) { 74 | // Create a channel and subscribers 75 | Channel channel = new Channel("CoderArmy"); 76 | 77 | Subscriber subs1 = new Subscriber("Varun", channel); 78 | Subscriber subs2 = new Subscriber("Tarun", channel); 79 | 80 | // Varun and Tarun subscribe to CoderArmy 81 | channel.subscribe(subs1); 82 | channel.subscribe(subs2); 83 | 84 | // Upload a video: both Varun and Tarun are notified 85 | channel.uploadVideo("Observer Pattern Tutorial"); 86 | 87 | // Varun unsubscribes; Tarun remains subscribed 88 | channel.unsubscribe(subs1); 89 | 90 | // Upload another video: only Tarun is notified 91 | channel.uploadVideo("Decorator Pattern Tutorial"); 92 | } 93 | } 94 | 95 | 96 | --------------------------------------------------------------------------------