├── .gitignore ├── .idea ├── .gitignore ├── material_theme_project_new.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── DesignPatterns.iml ├── README.md └── src ├── ATMMachine_StateDesignPattern ├── DTO │ ├── CreateTransactionRequestDTO.java │ ├── GetATMAmountRequestDTO.java │ └── UpdateATMStateRequestDTO.java ├── Enums │ ├── ATMState.java │ ├── CardNetworkType.java │ └── CardType.java ├── Main.java ├── apis │ ├── BackendAPI.java │ └── NodeBackendAPI.java ├── factories │ └── CardManagerFactory.java ├── models │ ├── ATM.java │ ├── Card.java │ ├── Credit.java │ ├── Debit.java │ ├── MasterCard.java │ ├── Visa.java │ └── VisaDebitCard.java ├── services │ ├── CardManagerService.java │ ├── CashDispenseServiceImpl.java │ ├── CashDispenserService.java │ ├── CreditCardManagerService.java │ └── DebitCardManagerService.java └── state │ ├── DispensingCashState.java │ ├── EjectingCardState.java │ ├── ReadCardDetailsAndPinState.java │ ├── ReadingCashWithdrawlDetailsState.java │ ├── ReadyForTransactionState.java │ └── State.java ├── CricBuzz_ObserverPattern_Pubsub ├── Main.java ├── models │ ├── Innings.java │ ├── Match.java │ ├── Player.java │ └── Team.java ├── producers │ ├── BcciProducer.java │ ├── ICCScoreProducer.java │ └── Producer.java └── subscribers │ ├── CommentarySubscriber.java │ ├── ScoreBoardSubscriber.java │ └── Subscriber.java ├── IteratorPattern_HandlingPaginatedAPI ├── BasicDemo.java ├── InMemoryDatabase.java ├── iterators │ ├── Iterator.java │ └── UserIterator.java ├── repositories │ ├── UserRepository.java │ └── UserRepositoryImpl.java └── services │ └── UserService.java ├── Main.java ├── NaiveATM └── ATM.java ├── PrototypePattern ├── Email.java ├── Main.java ├── PremiumEmail.java └── Prototype.java ├── RouteHandler_ChainOfResponsibilityPattern ├── DTO │ ├── Request.java │ └── Response.java ├── controllers │ └── TodoController.java ├── factory │ └── RequestHandlerFactory.java ├── handlers │ ├── AuthenticationHandler.java │ ├── AuthorisationHandler.java │ ├── FinishingHandler.java │ ├── HandlerB.java │ ├── RequestHandler.java │ ├── ValidateBodyHandler.java │ └── ValidateParamsHandler.java ├── schema │ └── Todo.java └── services │ ├── TokenService.java │ └── TokenServiceImpl.java └── SOLID ├── Amex.java ├── CreditCard.java ├── Main.java ├── Mastercard.java ├── RefundCompatibleCC.java ├── RefundLogic.java ├── Rupay.java ├── SameInstrumentRefund.java ├── SameWalletRefund.java └── Visa.java /.gitignore: -------------------------------------------------------------------------------- 1 | ### IntelliJ IDEA ### 2 | out/ 3 | !**/src/main/**/out/ 4 | !**/src/test/**/out/ 5 | 6 | ### Eclipse ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | bin/ 15 | !**/src/main/**/bin/ 16 | !**/src/test/**/bin/ 17 | 18 | ### NetBeans ### 19 | /nbproject/private/ 20 | /nbbuild/ 21 | /dist/ 22 | /nbdist/ 23 | /.nb-gradle/ 24 | 25 | ### VS Code ### 26 | .vscode/ 27 | 28 | ### Mac OS ### 29 | .DS_Store -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/material_theme_project_new.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DesignPatterns.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Homework 2 | 3 | 4 | ### Problem 1: 5 | 6 | Write your own MyVector class (in any language) 7 | 8 | #### Requirements: 9 | - The vector created should be able to store any type of data 10 | - The vector should be able to grow dynamically (similar to arraylist) 11 | - The vector should be able to shrink dynamically (similar to arraylist) 12 | - It should not use internal libraries that provide the same functionality like arraylist and internal vectors 13 | - Add more utility functions like isEmpty, size, etc. 14 | - Now users should not be able to directly access the data of this MyVector class, intead the strategy if accessing the data should be exposed by us. 15 | - One strategy can be to access data in forward sequential fashion 16 | - Another strategy can be to access data in reverse sequential fashion 17 | - Another strategy can be to access data in random fashion 18 | - Another strategy can be to access data in sequential fashion but with a jump of K elements 19 | - Another strategy can be to access data in bidirectional fashion -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/DTO/CreateTransactionRequestDTO.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.DTO; 2 | 3 | public class CreateTransactionRequestDTO { 4 | 5 | private final String atmId; 6 | 7 | public CreateTransactionRequestDTO(String atmId) { 8 | this.atmId = atmId; 9 | } 10 | 11 | public String getAtmId() { 12 | return atmId; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/DTO/GetATMAmountRequestDTO.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.DTO; 2 | 3 | public class GetATMAmountRequestDTO { 4 | 5 | private final String atmId; 6 | 7 | public GetATMAmountRequestDTO(String atmId) { 8 | this.atmId = atmId; 9 | } 10 | 11 | public String getAtmId() { 12 | return atmId; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/DTO/UpdateATMStateRequestDTO.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.DTO; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.ATMState; 4 | 5 | public class UpdateATMStateRequestDTO { 6 | 7 | private final String atmId; 8 | private final ATMState state; 9 | 10 | public UpdateATMStateRequestDTO(String atmId, ATMState state) { 11 | this.atmId = atmId; 12 | this.state = state; 13 | } 14 | 15 | public String getAtmId() { 16 | return atmId; 17 | } 18 | 19 | public ATMState getState() { 20 | return state; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/Enums/ATMState.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.Enums; 2 | 3 | public enum ATMState { 4 | 5 | READY_FOR_TRANSACTION, 6 | READ_CARD_DETAILS_AND_PIN, 7 | DISPENSING_CASH, 8 | EJECTING_CARD, 9 | READING_CASH_WITHDRAW_DETAILS; 10 | } 11 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/Enums/CardNetworkType.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.Enums; 2 | 3 | public enum CardNetworkType { 4 | VISA, 5 | MASTERCARD, 6 | AMERICAN_EXPRESS, 7 | RUPAY, 8 | DISCOVER; 9 | } 10 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/Enums/CardType.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.Enums; 2 | 3 | public enum CardType { 4 | 5 | DEBIT, 6 | CREDIT; 7 | } 8 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/Main.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern; 2 | 3 | public class Main { 4 | } 5 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/apis/BackendAPI.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.apis; 2 | 3 | import ATMMachine_StateDesignPattern.DTO.CreateTransactionRequestDTO; 4 | import ATMMachine_StateDesignPattern.DTO.GetATMAmountRequestDTO; 5 | import ATMMachine_StateDesignPattern.DTO.UpdateATMStateRequestDTO; 6 | 7 | public interface BackendAPI { 8 | 9 | int createTransaction(CreateTransactionRequestDTO createTransactionDTO); 10 | 11 | boolean updateState(UpdateATMStateRequestDTO updateATMStateDTO); 12 | 13 | 14 | int getATMAMount(GetATMAmountRequestDTO getATMAmountRequestDTO); 15 | } 16 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/apis/NodeBackendAPI.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.apis; 2 | 3 | import ATMMachine_StateDesignPattern.DTO.CreateTransactionRequestDTO; 4 | import ATMMachine_StateDesignPattern.DTO.GetATMAmountRequestDTO; 5 | import ATMMachine_StateDesignPattern.DTO.UpdateATMStateRequestDTO; 6 | 7 | public class NodeBackendAPI implements BackendAPI { 8 | // Should be only responsible for connecting to the backend and returning the response 9 | 10 | public int createTransaction(CreateTransactionRequestDTO createTransactionDTO) { 11 | // 1. Validations 12 | // if(createTransactionDTO.getAtmId() == null || createTransactionDTO.getAtmId().isEmpty()) { 13 | // throw new IllegalArgumentException("ATM ID cannot be null or empty"); 14 | // } 15 | 16 | // 2. Connect to the backend 17 | // To mimic the backend call let's return a new random transaction ID 18 | 19 | // 3. Return the response 20 | return (int) (Math.random() * 1000); 21 | } 22 | 23 | @Override 24 | public boolean updateState(UpdateATMStateRequestDTO updateATMStateDTO) { 25 | 26 | // Assume that there is the implementation that calls the backend to update the state of the ATM 27 | 28 | return true; // mimiced response 29 | } 30 | 31 | @Override 32 | public int getATMAMount(GetATMAmountRequestDTO getATMAmountRequestDTO) { 33 | return 10000; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/factories/CardManagerFactory.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.factories; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.CardType; 4 | import ATMMachine_StateDesignPattern.services.CardManagerService; 5 | import ATMMachine_StateDesignPattern.services.CreditCardManagerService; 6 | import ATMMachine_StateDesignPattern.services.DebitCardManagerService; 7 | 8 | public class CardManagerFactory { 9 | 10 | public static CardManagerService getCardManager(CardType cardType) { 11 | CardManagerService cardManagerService = null; 12 | if(cardType.equals(CardType.DEBIT)) { 13 | cardManagerService = new DebitCardManagerService(); 14 | } else if(cardType.equals(CardType.CREDIT)) { 15 | cardManagerService = new CreditCardManagerService(); 16 | } else { 17 | throw new IllegalArgumentException("Invalid Card Type"); 18 | } 19 | 20 | return cardManagerService; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/models/ATM.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.models; 2 | 3 | import ATMMachine_StateDesignPattern.DTO.UpdateATMStateRequestDTO; 4 | import ATMMachine_StateDesignPattern.apis.BackendAPI; 5 | import ATMMachine_StateDesignPattern.apis.NodeBackendAPI; 6 | import ATMMachine_StateDesignPattern.state.ReadyForTransactionState; 7 | import ATMMachine_StateDesignPattern.state.State; 8 | 9 | public class ATM { 10 | 11 | private final String atmId; 12 | private State state; 13 | private final BackendAPI backendAPI; 14 | 15 | public ATM(String atmId) { 16 | this.atmId = atmId; 17 | this.backendAPI = new NodeBackendAPI(); 18 | this.state = new ReadyForTransactionState(this); 19 | } 20 | 21 | public String getAtmId() { 22 | return atmId; 23 | } 24 | 25 | public void changeState(State newState) { 26 | this.state = newState; 27 | // now call the server to persist the state on the server also 28 | this.backendAPI.updateState(new UpdateATMStateRequestDTO(this.atmId, newState.getState())); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/models/Card.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.models; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.CardType; 4 | 5 | public class Card { 6 | 7 | private final long cardNumber; 8 | 9 | private final int pin; 10 | 11 | private final String name; 12 | 13 | private final CardType cardType; 14 | 15 | private final String bankName; 16 | 17 | public Card(long cardNumber, int pin, String name, CardType cardType, String bankName) { 18 | this.cardNumber = cardNumber; 19 | this.pin = pin; 20 | this.name = name; 21 | this.cardType = cardType; 22 | this.bankName = bankName; 23 | } 24 | 25 | public String getBankName() { 26 | return bankName; 27 | } 28 | 29 | public long getCardNumber() { 30 | return cardNumber; 31 | } 32 | 33 | public int getPin() { 34 | return pin; 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public CardType getCardType() { 42 | return cardType; 43 | } 44 | 45 | // toString 46 | @Override 47 | public String toString() { 48 | return "Card{" + "cardNumber=" + cardNumber + ", pin=" + pin + ", name=" + name + ", cardType=" + cardType + ", bankName=" + bankName + '}'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/models/Credit.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.models; 2 | 3 | public interface Credit { 4 | 5 | void makePinPayment(); 6 | } 7 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/models/Debit.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.models; 2 | 3 | public interface Debit { 4 | 5 | void makePinPayment(); 6 | } 7 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/models/MasterCard.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.models; 2 | 3 | public interface MasterCard { 4 | 5 | void connectToMasterCard(); 6 | } 7 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/models/Visa.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.models; 2 | 3 | public interface Visa { 4 | 5 | void connectToVisa(); 6 | } 7 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/models/VisaDebitCard.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.models; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.CardType; 4 | 5 | public class VisaDebitCard extends Card implements Visa, Debit { 6 | 7 | public VisaDebitCard(long cardNumber, int pin, String name, CardType cardType, String bankName) { 8 | super(cardNumber, pin, name, cardType, bankName); 9 | } 10 | 11 | @Override 12 | public void makePinPayment() { 13 | this.connectToVisa(); 14 | System.out.println("Making payment with pin"); 15 | } 16 | 17 | @Override 18 | public void connectToVisa() { 19 | System.out.println("Connecting to Visa"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/services/CardManagerService.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.services; 2 | 3 | import ATMMachine_StateDesignPattern.models.Card; 4 | 5 | public interface CardManagerService { 6 | 7 | boolean validateCard(Card card, String pin); 8 | 9 | boolean validateWithdrawl(int transactionId, double amount); 10 | 11 | boolean doTransaction(Card card, double amount, int transactionId); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/services/CashDispenseServiceImpl.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.services; 2 | 3 | import ATMMachine_StateDesignPattern.DTO.GetATMAmountRequestDTO; 4 | import ATMMachine_StateDesignPattern.apis.BackendAPI; 5 | import ATMMachine_StateDesignPattern.apis.NodeBackendAPI; 6 | import ATMMachine_StateDesignPattern.models.ATM; 7 | 8 | public class CashDispenseServiceImpl implements CashDispenserService { 9 | 10 | private final BackendAPI backendAPI; 11 | 12 | public CashDispenseServiceImpl() { 13 | this.backendAPI = new NodeBackendAPI(); 14 | } 15 | 16 | @Override 17 | public void dispenseCash(ATM atm, int amount) { 18 | // call the server to dispense the cash 19 | int atmAmount = this.backendAPI.getATMAMount(new GetATMAmountRequestDTO(atm.getAtmId())); 20 | 21 | if(atmAmount < amount) { 22 | throw new RuntimeException("ATM does not have enough cash to dispense"); 23 | } 24 | 25 | System.out.println("Dispensing cash: " + amount); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/services/CashDispenserService.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.services; 2 | 3 | import ATMMachine_StateDesignPattern.models.ATM; 4 | 5 | public interface CashDispenserService { 6 | 7 | public void dispenseCash(ATM atm, int amount); 8 | } 9 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/services/CreditCardManagerService.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.services; 2 | 3 | import ATMMachine_StateDesignPattern.models.Card; 4 | 5 | public class CreditCardManagerService implements CardManagerService{ 6 | @Override 7 | public boolean validateCard(Card card, String pin) { 8 | return true; 9 | } 10 | 11 | @Override 12 | public boolean validateWithdrawl(int transactionId, double amount) { 13 | return true; 14 | } 15 | 16 | @Override 17 | public boolean doTransaction(Card card, double amount, int transactionId) { 18 | // maybe we could have utilised the methods of card interfaces 19 | return true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/services/DebitCardManagerService.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.services; 2 | 3 | import ATMMachine_StateDesignPattern.models.Card; 4 | 5 | public class DebitCardManagerService implements CardManagerService{ 6 | @Override 7 | public boolean validateCard(Card card, String pin) { 8 | // ideally we should make these also connect to API 9 | return true; 10 | } 11 | 12 | @Override 13 | public boolean validateWithdrawl(int transactionId, double amount) { 14 | // ideally we should make these also connect to API 15 | return true; 16 | } 17 | 18 | @Override 19 | public boolean doTransaction(Card card, double amount, int transactionId) { 20 | // ideally we should make these also connect to API 21 | return true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/state/DispensingCashState.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.state; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.ATMState; 4 | import ATMMachine_StateDesignPattern.factories.CardManagerFactory; 5 | import ATMMachine_StateDesignPattern.models.ATM; 6 | import ATMMachine_StateDesignPattern.models.Card; 7 | import ATMMachine_StateDesignPattern.services.CardManagerService; 8 | import ATMMachine_StateDesignPattern.services.CashDispenseServiceImpl; 9 | import ATMMachine_StateDesignPattern.services.CashDispenserService; 10 | 11 | public class DispensingCashState implements State { 12 | private final ATM atm; 13 | private final CashDispenserService cashDispenserService; 14 | 15 | public DispensingCashState(ATM atm) { 16 | this.atm = atm; 17 | this.cashDispenserService = new CashDispenseServiceImpl(); 18 | } 19 | 20 | @Override 21 | public int initTransaction() { 22 | throw new IllegalStateException("Cannot init transaction while dispensing cash"); 23 | } 24 | 25 | @Override 26 | public boolean readCardDetailsAndPin(Card card, String pin) { 27 | throw new IllegalStateException("Cannot read card details and pin while dispensing cash"); 28 | } 29 | 30 | @Override 31 | public int dispenseCash(Card card, int amount, int transactionId) { 32 | CardManagerService manager = CardManagerFactory.getCardManager(card.getCardType()); 33 | boolean isTxnSuccessful = manager.doTransaction(card, amount, transactionId); 34 | if(isTxnSuccessful) { 35 | this.cashDispenserService.dispenseCash(this.atm, amount); 36 | 37 | } else { 38 | System.out.println("Something went wrong"); 39 | } 40 | this.atm.changeState(new EjectingCardState(this.atm)); 41 | 42 | return amount; 43 | } 44 | 45 | @Override 46 | public void ejectCard() { 47 | throw new IllegalStateException("Cannot eject card while dispensing cash"); 48 | } 49 | 50 | @Override 51 | public boolean readCashWithdrawDetails(Card card, int transactionId, int amount) { 52 | throw new IllegalStateException("Cannot read cash withdraw details while dispensing cash"); 53 | } 54 | 55 | @Override 56 | public boolean cancelTransaction(int transactionId) { 57 | throw new IllegalStateException("Cannot cancel transaction while dispensing cash"); 58 | } 59 | 60 | @Override 61 | public ATMState getState() { 62 | return ATMState.DISPENSING_CASH; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/state/EjectingCardState.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.state; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.ATMState; 4 | import ATMMachine_StateDesignPattern.models.ATM; 5 | import ATMMachine_StateDesignPattern.models.Card; 6 | 7 | public class EjectingCardState implements State{ 8 | 9 | private final ATM atm; 10 | 11 | public EjectingCardState(ATM atm) { 12 | this.atm = atm; 13 | } 14 | 15 | @Override 16 | public int initTransaction() { 17 | throw new IllegalStateException("Cannot init transaction while ejecting card"); 18 | } 19 | 20 | @Override 21 | public boolean readCardDetailsAndPin(Card card, String pin) { 22 | throw new IllegalStateException("Cannot read card details and pin while ejecting card"); 23 | } 24 | 25 | @Override 26 | public int dispenseCash(Card card, int amount, int transactionId) { 27 | throw new IllegalStateException("Cannot dispense cash while ejecting card"); 28 | } 29 | 30 | @Override 31 | public void ejectCard() { 32 | System.out.println("Card ejected, please take it"); 33 | this.atm.changeState(new ReadyForTransactionState(this.atm)); 34 | } 35 | 36 | @Override 37 | public boolean readCashWithdrawDetails(Card card, int transactionId, int amount) { 38 | throw new IllegalStateException("Cannot read cash withdraw details while ejecting card"); 39 | } 40 | 41 | @Override 42 | public boolean cancelTransaction(int transactionId) { 43 | throw new IllegalStateException("Cannot cancel transaction while ejecting card"); 44 | } 45 | 46 | @Override 47 | public ATMState getState() { 48 | return ATMState.EJECTING_CARD; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/state/ReadCardDetailsAndPinState.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.state; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.ATMState; 4 | import ATMMachine_StateDesignPattern.Enums.CardType; 5 | import ATMMachine_StateDesignPattern.factories.CardManagerFactory; 6 | import ATMMachine_StateDesignPattern.models.ATM; 7 | import ATMMachine_StateDesignPattern.models.Card; 8 | import ATMMachine_StateDesignPattern.services.CardManagerService; 9 | 10 | public class ReadCardDetailsAndPinState implements State { 11 | private final ATM atm; 12 | 13 | public ReadCardDetailsAndPinState(ATM atm) { 14 | this.atm = atm; 15 | } 16 | 17 | @Override 18 | public int initTransaction() { 19 | throw new IllegalStateException("Cannot init transaction while reading card details and pin"); 20 | } 21 | 22 | @Override 23 | public boolean readCardDetailsAndPin(Card card, String pin) { 24 | CardManagerService manager = CardManagerFactory.getCardManager(card.getCardType()); 25 | boolean isCardValid = manager.validateCard(card, pin); 26 | if(isCardValid) { 27 | this.atm.changeState(new ReadingCashWithdrawlDetailsState(this.atm)); 28 | } else { 29 | this.atm.changeState(new EjectingCardState(this.atm)); 30 | } 31 | return isCardValid; 32 | } 33 | 34 | @Override 35 | public int dispenseCash(Card card, int amount, int transactionId) { 36 | throw new IllegalStateException("Cannot dispense cash while reading card details and pin"); 37 | } 38 | 39 | @Override 40 | public void ejectCard() { 41 | throw new IllegalStateException("Cannot eject card while reading card details and pin"); 42 | } 43 | 44 | @Override 45 | public boolean readCashWithdrawDetails(Card card, int transactionId, int amount) { 46 | throw new IllegalStateException("Cannot read cash withdraw details while reading card details and pin"); 47 | } 48 | 49 | @Override 50 | public boolean cancelTransaction(int transactionId) { 51 | try { 52 | this.atm.changeState(new ReadyForTransactionState(this.atm)); 53 | return true; 54 | } catch (Exception e) { 55 | throw new IllegalStateException("Cannot cancel transaction while reading card details and pin"); 56 | } 57 | } 58 | 59 | @Override 60 | public ATMState getState() { 61 | return ATMState.READ_CARD_DETAILS_AND_PIN; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/state/ReadingCashWithdrawlDetailsState.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.state; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.ATMState; 4 | import ATMMachine_StateDesignPattern.factories.CardManagerFactory; 5 | import ATMMachine_StateDesignPattern.models.ATM; 6 | import ATMMachine_StateDesignPattern.models.Card; 7 | import ATMMachine_StateDesignPattern.services.CardManagerService; 8 | 9 | public class ReadingCashWithdrawlDetailsState implements State { 10 | 11 | private final ATM atm; 12 | 13 | public ReadingCashWithdrawlDetailsState(ATM atm) { 14 | this.atm = atm; 15 | } 16 | 17 | @Override 18 | public int initTransaction() { 19 | throw new IllegalStateException("Cannot init transaction while reading cash withdraw details"); 20 | } 21 | 22 | @Override 23 | public boolean readCardDetailsAndPin(Card card, String pin) { 24 | throw new IllegalStateException("Cannot read card details and pin without inserting card"); 25 | } 26 | 27 | @Override 28 | public int dispenseCash(Card card, int amount, int transactionId) { 29 | throw new IllegalStateException("Cannot dispense cash without reading card details and pin"); 30 | } 31 | 32 | @Override 33 | public void ejectCard() { 34 | throw new IllegalStateException("Cannot eject card without reading card details and pin"); 35 | } 36 | 37 | @Override 38 | public boolean readCashWithdrawDetails(Card card, int transactionId, int amount) { 39 | CardManagerService manager = CardManagerFactory.getCardManager(card.getCardType()); 40 | boolean isWithdrawlValid = manager.validateWithdrawl(transactionId, amount); 41 | if(isWithdrawlValid) { 42 | this.atm.changeState(new DispensingCashState(this.atm)); 43 | } else { 44 | this.atm.changeState(new EjectingCardState(this.atm)); 45 | } 46 | 47 | return isWithdrawlValid; 48 | } 49 | 50 | @Override 51 | public boolean cancelTransaction(int transactionId) { 52 | this.atm.changeState(new ReadyForTransactionState(this.atm)); 53 | return true; 54 | } 55 | 56 | @Override 57 | public ATMState getState() { 58 | return ATMState.READING_CASH_WITHDRAW_DETAILS; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/state/ReadyForTransactionState.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.state; 2 | 3 | import ATMMachine_StateDesignPattern.DTO.CreateTransactionRequestDTO; 4 | import ATMMachine_StateDesignPattern.Enums.ATMState; 5 | import ATMMachine_StateDesignPattern.apis.BackendAPI; 6 | import ATMMachine_StateDesignPattern.apis.NodeBackendAPI; 7 | import ATMMachine_StateDesignPattern.models.ATM; 8 | import ATMMachine_StateDesignPattern.models.Card; 9 | 10 | public class ReadyForTransactionState implements State { 11 | 12 | private final ATM atm; 13 | private final BackendAPI backendAPI; 14 | 15 | public ReadyForTransactionState(ATM atm) { 16 | this.atm = atm; 17 | this.backendAPI = new NodeBackendAPI(); 18 | } 19 | 20 | @Override 21 | public int initTransaction() { 22 | CreateTransactionRequestDTO createTransactionDTO = new CreateTransactionRequestDTO(this.atm.getAtmId()); 23 | 24 | int transactionId = this.backendAPI.createTransaction(createTransactionDTO); 25 | 26 | if(transactionId == 0) { 27 | throw new RuntimeException("Transaction could not be created"); 28 | } 29 | 30 | // Now that we have the transactionId from the backend, we should move the ATM to the next state 31 | this.atm.changeState(new ReadCardDetailsAndPinState(this.atm)); 32 | return transactionId; 33 | } 34 | 35 | @Override 36 | public boolean readCardDetailsAndPin(Card card, String pin) { 37 | throw new IllegalStateException("Cannot read card details and pin without inserting card"); 38 | } 39 | 40 | @Override 41 | public int dispenseCash(Card card,int amount, int transactionId) { 42 | throw new IllegalStateException("Cannot dispense cash without reading card details and pin"); 43 | } 44 | 45 | @Override 46 | public void ejectCard() { 47 | throw new IllegalStateException("Cannot eject card without reading card details and pin"); 48 | } 49 | 50 | @Override 51 | public boolean readCashWithdrawDetails(Card card, int transactionId, int amount) { 52 | throw new IllegalStateException("Cannot read cash withdraw details without reading card details and pin"); 53 | } 54 | 55 | @Override 56 | public boolean cancelTransaction(int transactionId) { 57 | throw new IllegalStateException("Cannot cancel transaction without reading card details and pin"); 58 | } 59 | 60 | @Override 61 | public ATMState getState() { 62 | return ATMState.READY_FOR_TRANSACTION; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/ATMMachine_StateDesignPattern/state/State.java: -------------------------------------------------------------------------------- 1 | package ATMMachine_StateDesignPattern.state; 2 | 3 | import ATMMachine_StateDesignPattern.Enums.ATMState; 4 | import ATMMachine_StateDesignPattern.models.Card; 5 | 6 | public interface State { 7 | 8 | int initTransaction(); 9 | 10 | boolean readCardDetailsAndPin(Card card, String pin); // returns true if card is valid and false otherwise 11 | 12 | int dispenseCash(Card card, int amount, int transactionId); // returns the amount dispensed 13 | 14 | void ejectCard(); 15 | 16 | boolean readCashWithdrawDetails(Card card, int transactionId, int amount); // returns true if cash withdrawl details are valid and false otherwise 17 | 18 | boolean cancelTransaction(int transactionId); // returns true if transaction is cancelled and false otherwise 19 | 20 | ATMState getState(); 21 | } 22 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/Main.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub; 2 | 3 | public class Main { 4 | } 5 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/models/Innings.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.models; 2 | 3 | public class Innings { 4 | 5 | private String currentOver; 6 | private String currentBall; 7 | private String currentRunRate; 8 | private String currentScore; 9 | private String wickets; 10 | 11 | public String getCurrentOver() { 12 | return currentOver; 13 | } 14 | 15 | public void setCurrentOver(String currentOver) { 16 | this.currentOver = currentOver; 17 | } 18 | 19 | public String getCurrentBall() { 20 | return currentBall; 21 | } 22 | 23 | public void setCurrentBall(String currentBall) { 24 | this.currentBall = currentBall; 25 | } 26 | 27 | public String getCurrentRunRate() { 28 | return currentRunRate; 29 | } 30 | 31 | public void setCurrentRunRate(String currentRunRate) { 32 | this.currentRunRate = currentRunRate; 33 | } 34 | 35 | public String getCurrentScore() { 36 | return currentScore; 37 | } 38 | 39 | public void setCurrentScore(String currentScore) { 40 | this.currentScore = currentScore; 41 | } 42 | 43 | public String getWickets() { 44 | return wickets; 45 | } 46 | 47 | public void setWickets(String wickets) { 48 | this.wickets = wickets; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/models/Match.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.models; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Match { 7 | 8 | private String matchId; 9 | private Team team1; 10 | private Team team2; 11 | private String venue; 12 | private String date; 13 | private String time; 14 | private String status; 15 | private Innings innings1; 16 | private Innings innings2; 17 | private List commentary; 18 | private boolean isFirstInnings; 19 | 20 | public Match(String matchId, Team team1, Team team2, String venue, String date, String time, String status, Innings innings1, Innings innings2, List commentary) { 21 | this.matchId = matchId; 22 | this.team1 = team1; 23 | this.team2 = team2; 24 | this.venue = venue; 25 | this.date = date; 26 | this.time = time; 27 | this.status = status; 28 | this.innings1 = innings1; 29 | this.innings2 = innings2; 30 | this.commentary = new ArrayList<>(); 31 | this.isFirstInnings = true; 32 | } 33 | 34 | public boolean isFirstInnings() { 35 | return isFirstInnings; 36 | } 37 | 38 | public void setFirstInnings(boolean isFirstInnings) { 39 | this.isFirstInnings = isFirstInnings; 40 | } 41 | 42 | public List getCommentary() { 43 | return commentary; 44 | } 45 | 46 | public void setCommentary(List commentary) { 47 | this.commentary = commentary; 48 | } 49 | 50 | public String getMatchId() { 51 | return matchId; 52 | } 53 | 54 | public void setMatchId(String matchId) { 55 | this.matchId = matchId; 56 | } 57 | 58 | public Team getTeam1() { 59 | return team1; 60 | } 61 | 62 | public void setTeam1(Team team1) { 63 | this.team1 = team1; 64 | } 65 | 66 | public Team getTeam2() { 67 | return team2; 68 | } 69 | 70 | public void setTeam2(Team team2) { 71 | this.team2 = team2; 72 | } 73 | 74 | public String getVenue() { 75 | return venue; 76 | } 77 | 78 | public void setVenue(String venue) { 79 | this.venue = venue; 80 | } 81 | 82 | public String getDate() { 83 | return date; 84 | } 85 | 86 | public void setDate(String date) { 87 | this.date = date; 88 | } 89 | 90 | public String getTime() { 91 | return time; 92 | } 93 | 94 | public void setTime(String time) { 95 | this.time = time; 96 | } 97 | 98 | public String getStatus() { 99 | return status; 100 | } 101 | 102 | public void setStatus(String status) { 103 | this.status = status; 104 | } 105 | 106 | public Innings getInnings1() { 107 | return innings1; 108 | } 109 | 110 | public void setInnings1(Innings innings1) { 111 | this.innings1 = innings1; 112 | } 113 | 114 | public Innings getInnings2() { 115 | return innings2; 116 | } 117 | 118 | public void setInnings2(Innings innings2) { 119 | this.innings2 = innings2; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/models/Player.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.models; 2 | 3 | public class Player { 4 | } 5 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/models/Team.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.models; 2 | 3 | import java.util.List; 4 | 5 | public class Team { 6 | 7 | private String name; 8 | private String teamId; 9 | private List players; 10 | 11 | public String getName() { 12 | return name; 13 | } 14 | 15 | public void setName(String name) { 16 | this.name = name; 17 | } 18 | 19 | public String getTeamId() { 20 | return teamId; 21 | } 22 | 23 | public void setTeamId(String teamId) { 24 | this.teamId = teamId; 25 | } 26 | 27 | public List getPlayers() { 28 | return players; 29 | } 30 | 31 | public void setPlayers(List players) { 32 | this.players = players; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/producers/BcciProducer.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.producers; 2 | 3 | import CricBuzz_ObserverPattern_Pubsub.models.Match; 4 | import CricBuzz_ObserverPattern_Pubsub.subscribers.Subscriber; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class BcciProducer implements Producer { 10 | 11 | Match match; 12 | private List subscribers; 13 | 14 | public BcciProducer(Match match) { 15 | this.subscribers = new ArrayList<>(); 16 | } 17 | 18 | public void scoreUpdated(String runs, String over, String ball, String wickets, boolean isFirstInnings) { 19 | // Some api or som3e mechanism to fetch data 20 | this.notifySubscribers(); 21 | } 22 | 23 | @Override 24 | public Match getMatchData() { 25 | return this.match; 26 | } 27 | 28 | @Override 29 | public void subscribe(Subscriber subscriber) { 30 | this.subscribers.add(subscriber); 31 | } 32 | 33 | @Override 34 | public void unsubscribe(Subscriber subscriber) { 35 | this.subscribers.remove(subscriber); 36 | } 37 | 38 | @Override 39 | public void notifySubscribers() { 40 | for(Subscriber sub : this.subscribers) { 41 | sub.update(this); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/producers/ICCScoreProducer.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.producers; 2 | 3 | import CricBuzz_ObserverPattern_Pubsub.models.Match; 4 | import CricBuzz_ObserverPattern_Pubsub.subscribers.Subscriber; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class ICCScoreProducer implements Producer { 10 | 11 | Match match; 12 | private List subscribers; 13 | 14 | public ICCScoreProducer(Match match) { 15 | this.subscribers = new ArrayList<>(); 16 | } 17 | 18 | public void scoreUpdated() { 19 | // We will call the api layer to get the data 20 | // and the api layer has the logic for server sent events 21 | this.notifySubscribers(); 22 | } 23 | 24 | @Override 25 | public Match getMatchData() { 26 | return this.match; 27 | } 28 | 29 | @Override 30 | public void subscribe(Subscriber subscriber) { 31 | this.subscribers.add(subscriber); 32 | } 33 | 34 | @Override 35 | public void unsubscribe(Subscriber subscriber) { 36 | this.subscribers.remove(subscriber); 37 | } 38 | 39 | @Override 40 | public void notifySubscribers() { 41 | for(Subscriber sub : this.subscribers) { 42 | sub.update(this); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/producers/Producer.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.producers; 2 | 3 | import CricBuzz_ObserverPattern_Pubsub.models.Match; 4 | import CricBuzz_ObserverPattern_Pubsub.subscribers.Subscriber; 5 | 6 | public interface Producer { 7 | 8 | Match getMatchData(); 9 | 10 | void subscribe(Subscriber subscriber); 11 | 12 | void unsubscribe(Subscriber subscriber); 13 | 14 | void notifySubscribers(); 15 | } 16 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/subscribers/CommentarySubscriber.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.subscribers; 2 | 3 | import CricBuzz_ObserverPattern_Pubsub.producers.Producer; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class CommentarySubscriber implements Subscriber { 9 | 10 | private List commentaries; 11 | private List producers; 12 | 13 | public CommentarySubscriber(List producers) { 14 | this.commentaries = new ArrayList<>(); 15 | this.producers = producers; 16 | for (Producer producer : producers) { 17 | producer.subscribe(this); 18 | } 19 | } 20 | 21 | @Override 22 | public void update(Producer producer) { 23 | this.commentaries.add(producer.getMatchData().getCommentary().get(producer.getMatchData().getCommentary().size() - 1)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/subscribers/ScoreBoardSubscriber.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.subscribers; 2 | 3 | import CricBuzz_ObserverPattern_Pubsub.models.Innings; 4 | import CricBuzz_ObserverPattern_Pubsub.models.Match; 5 | import CricBuzz_ObserverPattern_Pubsub.producers.Producer; 6 | 7 | import java.util.List; 8 | 9 | public class ScoreBoardSubscriber implements Subscriber{ 10 | 11 | private Match match; 12 | private List producers; 13 | public ScoreBoardSubscriber(Match match, List producers) { 14 | this.match = match; 15 | this.producers = producers; 16 | for (Producer producer : producers) { 17 | producer.subscribe(this); 18 | } 19 | } 20 | 21 | public void update(Producer producer) { 22 | boolean isFirstInnings = producer.getMatchData().isFirstInnings(); 23 | Innings inningsProducer = isFirstInnings ? producer.getMatchData().getInnings1() : producer.getMatchData().getInnings2(); 24 | 25 | Innings inningsSubscriber = isFirstInnings ? match.getInnings1() : match.getInnings2(); 26 | 27 | inningsSubscriber.setCurrentScore(inningsProducer.getCurrentScore()); 28 | inningsSubscriber.setCurrentOver(inningsProducer.getCurrentOver()); 29 | inningsSubscriber.setCurrentBall(inningsProducer.getCurrentBall()); 30 | inningsSubscriber.setWickets(inningsProducer.getWickets()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CricBuzz_ObserverPattern_Pubsub/subscribers/Subscriber.java: -------------------------------------------------------------------------------- 1 | package CricBuzz_ObserverPattern_Pubsub.subscribers; 2 | 3 | import CricBuzz_ObserverPattern_Pubsub.producers.Producer; 4 | 5 | public interface Subscriber { 6 | 7 | void update(Producer producer); 8 | } 9 | -------------------------------------------------------------------------------- /src/IteratorPattern_HandlingPaginatedAPI/BasicDemo.java: -------------------------------------------------------------------------------- 1 | package IteratorPattern_HandlingPaginatedAPI; 2 | 3 | import java.util.Iterator; 4 | 5 | public class BasicDemo { 6 | 7 | public static void main(String[] args) { 8 | Iterator it; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/IteratorPattern_HandlingPaginatedAPI/InMemoryDatabase.java: -------------------------------------------------------------------------------- 1 | package IteratorPattern_HandlingPaginatedAPI; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class InMemoryDatabase { 7 | 8 | private List users = new ArrayList<>(); 9 | 10 | public void seeder() { 11 | for(int i = 1; i <= 2000; i++) { 12 | users.add("User " + i); 13 | } 14 | } 15 | 16 | public List getUsers() { 17 | return users; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/IteratorPattern_HandlingPaginatedAPI/iterators/Iterator.java: -------------------------------------------------------------------------------- 1 | package IteratorPattern_HandlingPaginatedAPI.iterators; 2 | 3 | public interface Iterator { 4 | boolean hasNext(); 5 | T next(); 6 | } 7 | -------------------------------------------------------------------------------- /src/IteratorPattern_HandlingPaginatedAPI/iterators/UserIterator.java: -------------------------------------------------------------------------------- 1 | package IteratorPattern_HandlingPaginatedAPI.iterators; 2 | 3 | import IteratorPattern_HandlingPaginatedAPI.repositories.UserRepository; 4 | import IteratorPattern_HandlingPaginatedAPI.repositories.UserRepositoryImpl; 5 | 6 | import java.util.List; 7 | 8 | public class UserIterator implements Iterator>{ 9 | 10 | private final UserRepository userRepository; 11 | private int limit = 1; 12 | private int offset = 0; 13 | private List current; 14 | public UserIterator(int limit) { 15 | this.userRepository = new UserRepositoryImpl(); 16 | this.limit = limit; 17 | this.current = userRepository.findUsers(limit, offset); 18 | } 19 | 20 | @Override 21 | public boolean hasNext() { 22 | return !current.isEmpty(); 23 | } 24 | 25 | @Override 26 | public List next() { 27 | List result = current; 28 | this.offset += limit; 29 | this.current = this.userRepository.findUsers(limit, offset); 30 | return result; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/IteratorPattern_HandlingPaginatedAPI/repositories/UserRepository.java: -------------------------------------------------------------------------------- 1 | package IteratorPattern_HandlingPaginatedAPI.repositories; 2 | 3 | import java.util.List; 4 | 5 | public interface UserRepository { 6 | 7 | List findUsers(int limit, int offset); 8 | } 9 | -------------------------------------------------------------------------------- /src/IteratorPattern_HandlingPaginatedAPI/repositories/UserRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package IteratorPattern_HandlingPaginatedAPI.repositories; 2 | 3 | import IteratorPattern_HandlingPaginatedAPI.InMemoryDatabase; 4 | 5 | import java.util.List; 6 | 7 | public class UserRepositoryImpl implements UserRepository{ 8 | 9 | private final InMemoryDatabase db; 10 | 11 | public UserRepositoryImpl() { 12 | this.db = new InMemoryDatabase(); 13 | } 14 | 15 | @Override 16 | public List findUsers(int limit, int offset) { 17 | List allUsers = db.getUsers(); 18 | int start = (offset-1)*limit; // start of the paginated data 19 | int end = Math.min(start + limit, allUsers.size()); // end of the paginated data 20 | 21 | if(start >= allUsers.size()) { 22 | return List.of(); 23 | } 24 | 25 | return allUsers.subList(start, end); 26 | } 27 | } 28 | 29 | /** 30 | * When limit and offset based pagination is not good 31 | * 32 | * f10, f9, f8, f7, f6, f5, f4, f3, f2, f1 33 | * limit=3, offset=0 -> f10, f9, f8 (first 3 posts) 34 | * 35 | * f12, f11, f10, f9, f8, f7, f6, f5, f4, f3, f2, f1 36 | * limit=3, offset=3 -> Expected output(f7, f6, f5) but actual output(f9, f8, f7) 37 | * 38 | * Solution - Cursor based pagination 39 | * SELECT * from posts where createdAt < t8 order by createdAt desc limit 3 40 | */ 41 | -------------------------------------------------------------------------------- /src/IteratorPattern_HandlingPaginatedAPI/services/UserService.java: -------------------------------------------------------------------------------- 1 | package IteratorPattern_HandlingPaginatedAPI.services; 2 | 3 | import IteratorPattern_HandlingPaginatedAPI.iterators.Iterator; 4 | import IteratorPattern_HandlingPaginatedAPI.iterators.UserIterator; 5 | import IteratorPattern_HandlingPaginatedAPI.repositories.UserRepository; 6 | import IteratorPattern_HandlingPaginatedAPI.repositories.UserRepositoryImpl; 7 | 8 | import java.util.List; 9 | 10 | public class UserService { 11 | 12 | private final UserRepository userRepository; 13 | private final Iterator> userIterator; 14 | 15 | public UserService(UserRepository userRepository) { 16 | this.userRepository = new UserRepositoryImpl(); 17 | this.userIterator = new UserIterator(10); 18 | } 19 | 20 | public void getUsersOnPlatform() { 21 | 22 | /** 23 | this.userRepository.findUsers(10, 1); 24 | * 1. Here the Service layer has to keep track of current offset 25 | * 2. Wherever this pagination is reqd, we need to maintain offset there 26 | * 3. We don't know when to stop ? We might have to write a custom logic, to check if no more data is there 27 | * 28 | */ 29 | 30 | while(userIterator.hasNext()) { 31 | List users = userIterator.next(); 32 | System.out.println(users); 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Main.java: -------------------------------------------------------------------------------- 1 | //TIP To Run code, press or 2 | // click the icon in the gutter. 3 | public class Main { 4 | public static void main(String[] args) { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/NaiveATM/ATM.java: -------------------------------------------------------------------------------- 1 | package NaiveATM; 2 | 3 | public class ATM { 4 | 5 | // Enum for ATM states 6 | private enum ATMState { 7 | IDLE, TRANSACTION_IN_PROGRESS, CARD_INSERTED, AMOUNT_ENTERED, DISPENSING_CASH 8 | } 9 | 10 | // Instance variables 11 | private String atmId; // Unique identifier for the ATM 12 | private ATMState state; // Current state of the ATM 13 | 14 | // Constructor 15 | public ATM(String atmId) { 16 | this.atmId = atmId; 17 | this.state = ATMState.IDLE; // Default state is IDLE 18 | } 19 | 20 | // Start a transaction 21 | public int startTransaction() { 22 | if(state == ATMState.TRANSACTION_IN_PROGRESS) { 23 | throw new IllegalStateException("Transaction already in progress."); 24 | } 25 | if(state == ATMState.DISPENSING_CASH) { 26 | throw new IllegalStateException("Cannot start a new transaction while dispensing cash."); 27 | } 28 | if(state == ATMState.CARD_INSERTED) { 29 | throw new IllegalStateException("Cannot start a new transaction. Card already inserted."); 30 | } 31 | state = ATMState.TRANSACTION_IN_PROGRESS; 32 | int transactionId = generateTransactionId(); 33 | System.out.println("Transaction started with ID: " + transactionId + " on ATM: " + atmId); 34 | return transactionId; 35 | } 36 | 37 | // Cancel a transaction 38 | public void cancelTransaction() { 39 | if (state == ATMState.IDLE) { 40 | throw new IllegalStateException("No transaction to cancel."); 41 | } 42 | if(state == ATMState.DISPENSING_CASH) { 43 | throw new IllegalStateException("Cannot cancel transaction while dispensing cash."); 44 | } 45 | state = ATMState.IDLE; 46 | System.out.println("Transaction canceled on ATM: " + atmId); 47 | } 48 | 49 | // Read card details and validate 50 | public boolean readCard(String cardType, long cardNumber, int pin) { 51 | if (state != ATMState.TRANSACTION_IN_PROGRESS) { 52 | throw new IllegalStateException("Cannot read card. Start a transaction first."); 53 | } 54 | state = ATMState.CARD_INSERTED; 55 | boolean isValid = validateCardDetails(cardType, cardNumber, pin); 56 | if (!isValid) { 57 | state = ATMState.IDLE; 58 | } 59 | return isValid; 60 | } 61 | 62 | // Enter withdrawal amount 63 | public boolean enterAmount(double amount) { 64 | if (state != ATMState.CARD_INSERTED) { 65 | throw new IllegalStateException("Card must be inserted before entering an amount."); 66 | } 67 | state = ATMState.AMOUNT_ENTERED; 68 | return checkWithdrawalLimit(amount); 69 | } 70 | 71 | // Dispense cash 72 | public void dispenseCash(double amount) { 73 | if (state != ATMState.AMOUNT_ENTERED) { 74 | throw new IllegalStateException("Amount must be entered before dispensing cash."); 75 | } 76 | state = ATMState.DISPENSING_CASH; 77 | System.out.println("Dispensing cash: " + amount + " on ATM: " + atmId); 78 | state = ATMState.IDLE; // Reset state after dispensing 79 | } 80 | 81 | // Eject card 82 | public void ejectCard() { 83 | if (state == ATMState.IDLE) { 84 | throw new IllegalStateException("No card to eject."); 85 | } 86 | state = ATMState.IDLE; 87 | System.out.println("Card ejected from ATM: " + atmId); 88 | } 89 | 90 | // Private helper methods 91 | private int generateTransactionId() { 92 | return (int) (Math.random() * 100000); // Generate random transaction ID 93 | } 94 | 95 | private boolean validateCardDetails(String cardType, long cardNumber, int pin) { 96 | // Simulate card validation 97 | return true; // Assume valid for simplicity 98 | } 99 | 100 | private boolean checkWithdrawalLimit(double amount) { 101 | // Simulate withdrawal limit check 102 | return amount <= 1000; // Assume a max limit of 1000 103 | } 104 | } -------------------------------------------------------------------------------- /src/PrototypePattern/Email.java: -------------------------------------------------------------------------------- 1 | package PrototypePattern; 2 | public abstract class Email implements Prototype { 3 | 4 | private String sender; 5 | private String receiver; 6 | private String subject; 7 | private String body; 8 | 9 | // Regular constructor 10 | public Email(String sender, String receiver, String subject, String body) { 11 | this.sender = sender; 12 | this.receiver = receiver; 13 | this.subject = subject; 14 | this.body = body; 15 | } 16 | 17 | // Copy constructor 18 | public Email(Email source) { 19 | this.sender = source.sender; 20 | this.receiver = source.receiver; 21 | this.subject = source.subject; 22 | this.body = source.body; 23 | } 24 | 25 | // Force all subclasses to provide their own copy logic 26 | @Override 27 | public abstract Email copy(); 28 | 29 | // Getters / Setters 30 | public String getSender() { 31 | return sender; 32 | } 33 | 34 | public void setSender(String sender) { 35 | this.sender = sender; 36 | } 37 | 38 | public String getReceiver() { 39 | return receiver; 40 | } 41 | 42 | public void setReceiver(String receiver) { 43 | this.receiver = receiver; 44 | } 45 | 46 | public String getSubject() { 47 | return subject; 48 | } 49 | 50 | public void setSubject(String subject) { 51 | this.subject = subject; 52 | } 53 | 54 | public String getBody() { 55 | return body; 56 | } 57 | 58 | public void setBody(String body) { 59 | this.body = body; 60 | } 61 | 62 | public void displayEmail() { 63 | System.out.println("Sender: " + sender); 64 | System.out.println("Receiver: " + receiver); 65 | System.out.println("Subject: " + subject); 66 | System.out.println("Body: " + body); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/PrototypePattern/Main.java: -------------------------------------------------------------------------------- 1 | package PrototypePattern; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | Email e1 = new Email("hello@world.com", "", "Test email", "This is a test email"); 7 | 8 | // Create a copy object 9 | Email e2 = e1.copy(); // this is calling the copy constructor 10 | e2.setBody(""); 11 | 12 | e2.displayEmail(); 13 | 14 | PremiumEmail pe1 = new PremiumEmail("hellopremium@world.com", "", "Test premium email", "This is a test premium email", "cc", "bcc"); 15 | 16 | // Create a copy object 17 | PremiumEmail pe2 = pe1.copy(); // this is calling the copy constructor 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/PrototypePattern/PremiumEmail.java: -------------------------------------------------------------------------------- 1 | package PrototypePattern; 2 | public class PremiumEmail extends Email { 3 | 4 | private String cc; 5 | private String bcc; 6 | 7 | // Regular constructor 8 | public PremiumEmail(String sender, String receiver, String subject, String body, String cc, String bcc) { 9 | super(sender, receiver, subject, body); 10 | this.cc = cc; 11 | this.bcc = bcc; 12 | } 13 | 14 | // Copy constructor 15 | private PremiumEmail(PremiumEmail source) { 16 | super(source); // Calls Email(Email source) 17 | this.cc = source.cc; 18 | this.bcc = source.bcc; 19 | } 20 | 21 | // Required override of the abstract copy() method 22 | @Override 23 | public PremiumEmail copy() { 24 | return new PremiumEmail(this); 25 | } 26 | 27 | // Additional getters & setters 28 | public String getCc() { 29 | return cc; 30 | } 31 | 32 | public void setCc(String cc) { 33 | this.cc = cc; 34 | } 35 | 36 | public String getBcc() { 37 | return bcc; 38 | } 39 | 40 | public void setBcc(String bcc) { 41 | this.bcc = bcc; 42 | } 43 | 44 | @Override 45 | public void displayEmail() { 46 | // Reuse the parent display logic, then add extras 47 | super.displayEmail(); 48 | System.out.println("CC: " + cc); 49 | System.out.println("BCC: " + bcc); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/PrototypePattern/Prototype.java: -------------------------------------------------------------------------------- 1 | package PrototypePattern; 2 | 3 | public interface Prototype> { 4 | T copy(); 5 | } -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/DTO/Request.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.DTO; 2 | 3 | import java.util.Optional; 4 | 5 | public class Request { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/DTO/Response.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.DTO; 2 | 3 | public class Response { 4 | } 5 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/controllers/TodoController.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.controllers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | import RouteHandler_ChainOfResponsibilityPattern.factory.RequestHandlerFactory; 5 | import RouteHandler_ChainOfResponsibilityPattern.handlers.*; 6 | import RouteHandler_ChainOfResponsibilityPattern.schema.Todo; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class TodoController { 12 | 13 | 14 | 15 | private Todo createTodo(Request request) { 16 | RequestHandlerFactory.getHandlersForCreateTodo().handle(request); 17 | // return a new todo 18 | return new Todo(); 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/factory/RequestHandlerFactory.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.factory; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.handlers.*; 4 | import RouteHandler_ChainOfResponsibilityPattern.services.TokenServiceImpl; 5 | 6 | public class RequestHandlerFactory { 7 | 8 | public static RequestHandler getHandlersForCreateTodo() { 9 | 10 | return new ValidateParamsHandler( 11 | new ValidateBodyHandler( 12 | new AuthorisationHandler( 13 | new AuthenticationHandler( 14 | new FinishingHandler(), new TokenServiceImpl() 15 | ) 16 | ) 17 | ) 18 | ); 19 | } 20 | 21 | public static RequestHandler getHandlerForUpdateTodo() { 22 | return new ValidateParamsHandler( 23 | new HandlerB( 24 | new ValidateBodyHandler( 25 | new AuthorisationHandler( 26 | new AuthenticationHandler( 27 | new FinishingHandler(), new TokenServiceImpl() 28 | ) 29 | ) 30 | ) 31 | ) 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/handlers/AuthenticationHandler.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.handlers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | import RouteHandler_ChainOfResponsibilityPattern.services.TokenService; 5 | 6 | public class AuthenticationHandler implements RequestHandler { 7 | 8 | private final RequestHandler nextHandler; 9 | private final TokenService tokenService; 10 | 11 | public AuthenticationHandler(RequestHandler nextHandler, TokenService tokenService) { 12 | this.nextHandler = nextHandler; 13 | this.tokenService = tokenService; 14 | } 15 | 16 | @Override 17 | public void handle(Request request) { 18 | this.tokenService.validateToken(request); 19 | System.out.println("AuthenticationHandler: Authenticating the request"); 20 | 21 | this.nextHandler.handle(request); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/handlers/AuthorisationHandler.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.handlers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public class AuthorisationHandler implements RequestHandler { 6 | private final RequestHandler nextHandler; 7 | 8 | public AuthorisationHandler(RequestHandler nextHandler) { 9 | this.nextHandler = nextHandler; 10 | } 11 | @Override 12 | public void handle(Request request) { 13 | System.out.println("AuthorisationHandler: Authorising the request"); 14 | this.nextHandler.handle(request); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/handlers/FinishingHandler.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.handlers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public class FinishingHandler implements RequestHandler { 6 | 7 | @Override 8 | public void handle(Request request) { 9 | System.out.println("Finishing the request"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/handlers/HandlerB.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.handlers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public class HandlerB implements RequestHandler { 6 | 7 | private RequestHandler nextHandler; 8 | 9 | public HandlerB(RequestHandler nextHandler) { 10 | this.nextHandler = nextHandler; 11 | } 12 | 13 | @Override 14 | public void handle(Request request) { 15 | System.out.println("HandlerB is handling the request"); 16 | nextHandler.handle(request); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/handlers/RequestHandler.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.handlers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public interface RequestHandler { 6 | 7 | void handle(Request request); // What to do in a handler goes here 8 | } 9 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/handlers/ValidateBodyHandler.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.handlers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public class ValidateBodyHandler implements RequestHandler { 6 | 7 | private final RequestHandler nextHandler; 8 | 9 | public ValidateBodyHandler(RequestHandler nextHandler) { 10 | this.nextHandler = nextHandler; 11 | } 12 | @Override 13 | public void handle(Request request) { 14 | // Above the next handler call, whatever is written is executed before 15 | System.out.println("ValidateBodyHandler: Validating the request body"); 16 | 17 | this.nextHandler.handle(request); 18 | 19 | // below the handler, whatever is written is executed after the next handler 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/handlers/ValidateParamsHandler.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.handlers; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public class ValidateParamsHandler implements RequestHandler { 6 | 7 | private final RequestHandler nextHandler; 8 | 9 | public ValidateParamsHandler(RequestHandler nextHandler) { 10 | this.nextHandler = nextHandler; 11 | } 12 | @Override 13 | public void handle(Request request) { 14 | System.out.println("ValidateParamsHandler: Validating the request parameters"); 15 | 16 | this.nextHandler.handle(request); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/schema/Todo.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.schema; 2 | 3 | public class Todo { 4 | } 5 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/services/TokenService.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.services; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public interface TokenService { 6 | 7 | boolean validateToken(Request request); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/RouteHandler_ChainOfResponsibilityPattern/services/TokenServiceImpl.java: -------------------------------------------------------------------------------- 1 | package RouteHandler_ChainOfResponsibilityPattern.services; 2 | 3 | import RouteHandler_ChainOfResponsibilityPattern.DTO.Request; 4 | 5 | public class TokenServiceImpl implements TokenService { 6 | 7 | @Override 8 | public boolean validateToken(Request request) { 9 | System.out.println("TokenServiceImpl: Validating token"); 10 | // fetches token from header 11 | // if token is not found return 404 token missing 12 | // validates the token using the key 13 | // if token is invalid then return not authenticated 14 | return true; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/SOLID/Amex.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public class Amex extends CreditCard implements RefundCompatibleCC { 4 | 5 | public RefundLogic refundAlgorithm; 6 | 7 | public Amex(RefundLogic refundAlgorithm) { 8 | this.refundAlgorithm = refundAlgorithm; 9 | } 10 | 11 | @Override 12 | public void swipeAndPay() { 13 | System.out.println("Amex Card swipeAndPay"); 14 | } 15 | 16 | @Override 17 | public void onlinePayment() { 18 | System.out.println("Amex Card onlinePayment"); 19 | } 20 | 21 | @Override 22 | public void tapAndPay() { 23 | System.out.println("Amex Card tapAndPay"); 24 | } 25 | 26 | @Override 27 | public void refundAmount() { 28 | refundAlgorithm.doRefund(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SOLID/CreditCard.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public abstract class CreditCard { 4 | 5 | private String cardNumber; 6 | private String cardHolder; 7 | private String expiryDate; 8 | private int cvv; 9 | 10 | // Getters and Setters 11 | 12 | public abstract void swipeAndPay(); 13 | public abstract void onlinePayment(); 14 | public abstract void tapAndPay(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/SOLID/Main.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | CreditCard cc1 = new Amex(new SameWalletRefund()); 6 | CreditCard cc2 = new Visa(new SameInstrumentRefund()); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/SOLID/Mastercard.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public class Mastercard extends CreditCard implements RefundCompatibleCC { 4 | 5 | public RefundLogic refundAlgorithm; 6 | 7 | public Mastercard(RefundLogic refundAlgorithm) { 8 | this.refundAlgorithm = refundAlgorithm; 9 | } 10 | 11 | @Override 12 | public void swipeAndPay() { 13 | System.out.println("Mastercard Card swipeAndPay"); 14 | } 15 | 16 | @Override 17 | public void onlinePayment() { 18 | System.out.println("Mastercard Card onlinePayment"); 19 | } 20 | 21 | @Override 22 | public void tapAndPay() { 23 | System.out.println("Mastercard Card tapAndPay"); 24 | } 25 | 26 | @Override 27 | public void refundAmount() { 28 | refundAlgorithm.doRefund(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SOLID/RefundCompatibleCC.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public interface RefundCompatibleCC { 4 | 5 | void refundAmount(); 6 | } 7 | -------------------------------------------------------------------------------- /src/SOLID/RefundLogic.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public interface RefundLogic { 4 | void doRefund(); 5 | } 6 | -------------------------------------------------------------------------------- /src/SOLID/Rupay.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public class Rupay extends CreditCard implements RefundCompatibleCC { 4 | 5 | public RefundLogic refundAlgorithm; 6 | 7 | public Rupay(RefundLogic refundAlgorithm) { 8 | this.refundAlgorithm = refundAlgorithm; 9 | } 10 | 11 | @Override 12 | public void swipeAndPay() { 13 | System.out.println("Rupay Card swipeAndPay"); 14 | } 15 | 16 | @Override 17 | public void onlinePayment() { 18 | System.out.println("Rupay Card onlinePayment"); 19 | } 20 | 21 | @Override 22 | public void tapAndPay() { 23 | System.out.println("Rupay Card tapAndPay"); 24 | } 25 | 26 | @Override 27 | public void refundAmount() { 28 | refundAlgorithm.doRefund(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/SOLID/SameInstrumentRefund.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public class SameInstrumentRefund implements RefundLogic { 4 | 5 | @Override 6 | public void doRefund() { 7 | 8 | System.out.println("Refund done in the same instrument"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/SOLID/SameWalletRefund.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public class SameWalletRefund implements RefundLogic { 4 | 5 | @Override 6 | public void doRefund() { 7 | System.out.println("Refund done in the same wallet"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/SOLID/Visa.java: -------------------------------------------------------------------------------- 1 | package SOLID; 2 | 3 | public class Visa extends CreditCard implements RefundCompatibleCC { 4 | 5 | public RefundLogic refundAlgorithm; 6 | 7 | public Visa(RefundLogic refundAlgorithm) { 8 | this.refundAlgorithm = refundAlgorithm; 9 | } 10 | 11 | @Override 12 | public void swipeAndPay() { 13 | System.out.println("Visa Card swipeAndPay"); 14 | } 15 | 16 | @Override 17 | public void onlinePayment() { 18 | System.out.println("Visa Card onlinePayment"); 19 | } 20 | 21 | @Override 22 | public void tapAndPay() { 23 | System.out.println("Visa Card tapAndPay"); 24 | } 25 | 26 | @Override 27 | public void refundAmount() { 28 | refundAlgorithm.doRefund(); 29 | } 30 | } 31 | --------------------------------------------------------------------------------