172 lines
5.1 KiB
Markdown
Raw Permalink Normal View History

2020-03-19 12:51:33 +05:30
LLD 4
-----
Cascader Pattern
----------------
```java
public class Address {
String city, state, zip, lines[];
}
```
1. Validating address
- Need to validate each part
1. Algo(zip) < Algo(state) < Algo(city) < Algo(lines)
- both in difficulty and time complexity
1. Need to check combined as well
- `* <` Algo(combined)
1. 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
1. We provide this combined validator to our client
```java
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
}
}
```
1. Fail fast - prune the bad requests
- just like in recursion - branch and bound
1. Can we improve upon the &&?
- Could be more complex than &&
- Have multiple steps for each validator
1. Abstract it out into a loop
- Find the repeated thing
- Make a loop for it.
1. But class is different each time
- Can we make it same?
- Code classes against an interface
```java
public interface Validator {
bool validate(Address);
}
public class ZipValidator implements Validator {
bool validate(Address a) { ... }
}
```
1. Make the loop (using Runtime Polumorphism)
- What DS should we use to store the Validators?
```java
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;
}
}
```
1. Could we have used a Set instead of List?
- No. Order matters!
1. 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
1. 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
1. CombinedValidator can implement Validator
```java
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(),
)));
}
}
```
1. Lots of objects being created in constructor. Make it singleton.
1. Convert it into a factory (+singleton)
```java
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;
}
}
```
1. Cascade
- staircase
- fail: exit
- pass: move to next step
1. Client Code
```java
class ClientValidator {
bool validate(Address a) {
return ValidatorCascadeFactory.getInstance()
.getValidator(name)
.validate(a);
}
}
```
1. Note that in this code, we used Cascade, Factory, Singleton
1. Order important?
- yes, here
- not always
1. Address cleaning
- clean zip
- clean city
- clean State
- clean lines
1. Need to perform all. All are independent - don't effect one another
1. Can use a Set instead of a List
1. Must use List in substrategy
- first remove ,
- then remove space
- then lowercase
- ...
-- --