219 lines
6.4 KiB
Markdown
Raw Permalink Normal View History

2020-03-19 12:51:33 +05:30
LLD 3
-----
Factory Pattern
---------------
1. Trying to validate address
```java
class Address {
String country, state, city, []addressLines, zip;
}
```
1. Algorithm for validating address will differ from country to country.
1. Different countries have different breakups.
- Some countries don't have states
- Japan has provinces
- Some European countries have counties
- Meaning of state could be different
- Could have different ways of writing the addresses
- US addresses are more structured
- Indian addresses have lots of different ways - c/o xyz
- Chinese people write addresses in Chinese
1. So, different classes for each country
```java
public class INValidator {
public bool validate(Address a) {}
}
public class USValidator {
public bool validate(Address a) {}
}
```
Now, let's say that I ship these validators as a library
Some client wants to use these validators to validate a random address
```java
public class ClientValidator {
public bool validate(Address a) {
if(a.country == 'India')
return new INValidator().validate(a);
else if(a.country == 'USA')
return new USValidator().validate(a);
...
}
}
```
1. **Is this good?**
- client needs to know the name of the class for each country
- difficult to test
- unknown country - Indonesia. Does a class exist for it?
- IN stands for India or Indonesia?
- could lead to correct addresses being invalidated or wrong addresses be accepted
1. **Pull into interface**
- ![24debe26.png](:storage/e65b85d8-61b9-4991-b67d-d0c285e92bb4/24debe26.png =300x)
- all these classes are multiple forms of the same thing
- interface `Validator`, which asks to implement method `valdiate`
- coding your classes against an interface
1. **Runtime polymorphism**: `Validator v = new INValidator();`
1. **Who should worry about the mapping from country name to Validator?**
- client should not
- I should
- Keep a map
1. Need to create a class whose responsibility is to keep this mapping
```java
class X {
// why private? don't allow client to change this
private static Map<String, Validator> validators;
public X() {
validators.put("USA", USValidator);
validators.put("USA", INValidator);
}
public Validator getValidator(String country) {
// return validators.get(country); - bad
// could lead to null pointer exception
if(validators.has(country))
return validators.get(country);
throw new InvalidCountryException();
}
}
```
1. Too many objects being created in the constructor. Will be used many times. Use Singleton Pattern.
- make constructor private
- create an instance variable
- expose a getinstance function
1. Client code
```java
public class ClientValidator {
public bool validate(Address a) {
return X.getInstance(
.getValidator(a.country)
.validate(a);
}
}
```
1. Client just knows about the interface Validator, and that there's a factory which gives you different implementations of the Validators.
1. Factory Design Pattern
1. Rename X to ValidatorFactory
1. Remember that factories should usually be singleton
1. Notice that we use a pattern that we've already used
1. Usecases -
Gotchas
- don't use this in any language
- Python has dispathcing libraries
- Strategy pattern
- Don't abstract too much
- unless you're a library author
-- --
Stackoverflow
-------------
- Interviewer asks you to implement Stackoverflow
- First step? Start coding?
- **Use Cases**
- Anyone can search and view questions
- Question, answers, comments
- Guest can only search. To add/vote you need to be a member
- Each question can have an active bounty
- Text can contain photos
- User can earn badges
- Admin can blcok users
- Moderator can close questions
- Identify entities - will become classes
- Identify attributes and behavior
- Identify relationships
- ![5d93c037.png](:storage/e65b85d8-61b9-4991-b67d-d0c285e92bb4/5d93c037.png =500x)
```python
class Question:
status: Enum
title: str
description: str
votes: int
def close(): pass
class Comment:
content: stre
votes: int
class Answer:
content: str
votes: int
accepted: bool
```
- ![Screenshot 2019-10-09 at 8.48.21 PM.png](:storage/e65b85d8-61b9-4991-b67d-d0c285e92bb4/0b1d9eeb.png =500x)
```python
class Bounty:
prize: int
expiry: DateTime
def claim(): pass
class Photo:
alt_text: str
url: str
```
- Note where we have composition or not
![f2f50632.png](:storage/e65b85d8-61b9-4991-b67d-d0c285e92bb4/f2f50632.png =600x)
```python
class Member:
age: int
sex: str
def create_question(): pass
class Moderator(Member):
def close_question(): pass
class Admin(Member):
def block_member(): pass
```
- **Direction of arrows.** Member -> Question = Member has instance of Question
- **Composition vs Association**
- ![741698f7.png](:storage/e65b85d8-61b9-4991-b67d-d0c285e92bb4/741698f7.png =400x)
```python
class Account:
password: str
creation_date: DateTime
def delete_account(): pass
```
- Badge
- badges are static
- same badge, multiple people can own
- same person can own multiple badges
- not composition, because deleting either doesn't delete the other
```python
class Badge:
text: str
```
- Search interface
- Guest account - doesn't extend member
- Guest uses search
- ![7b76882f.png](:storage/e65b85d8-61b9-4991-b67d-d0c285e92bb4/7b76882f.png =400x)
Movie Ticket Booking
--------------------
- bookmyticket
- list all the centers of halls - **PVR** (brand), etc
- each **cinema center** can have multiple **halls / audis**
- movie vs movie show (cost, etc)
- hall can run some movie at some time
- each movie can have multiple shows
- search by title, language
- show seating arrangement
- show list of reserved and available seats
- difference b/w the physical chair vs a seat
- pay via cash/card
- no two customers should have the same seat
- discount coupons