6.4 KiB
LLD 3
Factory Pattern
-
Trying to validate address
class Address { String country, state, city, []addressLines, zip; }
-
Algorithm for validating address will differ from country to country.
-
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
-
-
So, different classes for each country
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
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); ... } }
-
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
-
Pull into interface
- 
- all these classes are multiple forms of the same thing
- interface
Validator
, which asks to implement methodvaldiate
- coding your classes against an interface
-
Runtime polymorphism:
Validator v = new INValidator();
-
Who should worry about the mapping from country name to Validator?
- client should not
- I should
- Keep a map
-
Need to create a class whose responsibility is to keep this mapping
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(); } }
-
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
-
Client code
public class ClientValidator { public bool validate(Address a) { return X.getInstance( .getValidator(a.country) .validate(a); } }
-
Client just knows about the interface Validator, and that there's a factory which gives you different implementations of the Validators.
-
Factory Design Pattern
-
Rename X to ValidatorFactory
-
Remember that factories should usually be singleton
-
Notice that we use a pattern that we've already used
-
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
- 
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
- 
class Bounty: prize: int expiry: DateTime def claim(): pass class Photo: alt_text: str url: str
- Note where we have composition or not

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
- 
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
class Badge: text: str
- Search interface
- Guest account - doesn't extend member
- Guest uses search
- 
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