mirror of
https://github.com/dholerobin/Lecture_Notes.git
synced 2025-03-15 13:49:59 +00:00
5.1 KiB
5.1 KiB
LLD 4
Cascader Pattern
public class Address {
String city, state, zip, lines[];
}
- Validating address
- Need to validate each part
- Algo(zip) < Algo(state) < Algo(city) < Algo(lines)
- both in difficulty and time complexity
- Need to check combined as well
* <
Algo(combined)
- Has been observed that most of the time, people make mistakes in Zip
- Does it make sense to validate everything else?
- No. Check zip first
- We provide this combined validator to our client
public class CombinedValidator { private static ZipValidator z = new ZipValidator(); private static StateValidator s = new StateValidator(); bool validate(Address a) { return z.validate(a) && s.validate(a) && ...; // order is important to fail fast } }
- Fail fast - prune the bad requests
- just like in recursion - branch and bound
- Can we improve upon the &&?
- Could be more complex than &&
- Have multiple steps for each validator
- Abstract it out into a loop
- Find the repeated thing
- Make a loop for it.
- But class is different each time
- Can we make it same?
- Code classes against an interface
public interface Validator { bool validate(Address); } public class ZipValidator implements Validator { bool validate(Address a) { ... } }
- Make the loop (using Runtime Polumorphism)
- What DS should we use to store the Validators?
public class CombinedValidator { private List<Validator> validators; public CombinedValidator() { validators = Arrays.asList( new ZipValidator(), new StateValidator(), ... ); } bool validate(Address a) { for(Validator v: validators) if(!v.validate(a)) return false; return true; } }
- Could we have used a Set instead of List?
- No. Order matters!
- Clients appear asking for different Combinations
- Either expose the programming interface - clients pass their own lists
- Many times, you onboard a client
- Communication over email / person like "we need to validate xyz using your code"
- You provide them with one function call for that
- Provide a combination for each client, associated with a client name
- c1 neess V1, V2, V3
- c2 needs V1, V4
- ...
- can use hashmap
- should we store lists in values?
- No, we can use CombinedValidator
- CombinedValidator can implement Validator
class X { Map<clientName, Validator> mapping; public X() { mapping.put("order_page", CombinedValidator(Arrays.asList( new ZipValidator(), new CityValidator(), new LinesValidator(), ))); mapping.put("KYC_check", CombinedValidator(Arrays.asList( new ZipValidator(), new CityValidator(), ))); } }
- Lots of objects being created in constructor. Make it singleton.
- Convert it into a factory (+singleton)
class ValidatorCascadeFactory { Map<clientName, Validator> mapping; private ValidatorCascadeFactory() { mapping.put("order_page", CombinedValidator(Arrays.asList( new ZipValidator(), new CityValidator(), new LinesValidator(), ))); mapping.put("KYC_check", CombinedValidator(Arrays.asList( new ZipValidator(), new CityValidator(), ))); } public CascadeFactory getInstance() // singleton public Validator getValidator(String clineName) // factory // note: exception handle in getValidator } public class ValidatorCascade implements Validator { private List<Validator> validators; public ValidatorCascade(List<Validator> validators); bool validate(Address a) { for(Validator v: validators) if(!v.validate(a)) return false; return true; } }
- Cascade
- staircase
- fail: exit
- pass: move to next step
- Client Code
class ClientValidator { bool validate(Address a) { return ValidatorCascadeFactory.getInstance() .getValidator(name) .validate(a); } }
- Note that in this code, we used Cascade, Factory, Singleton
- Order important?
- yes, here
- not always
- Address cleaning
- clean zip
- clean city
- clean State
- clean lines
- Need to perform all. All are independent - don't effect one another
- Can use a Set instead of a List
- Must use List in substrategy
- first remove ,
- then remove space
- then lowercase
- ...