Imagine you have a selling car business, and you want an application to filtering the cars by brand. Then your business logic could look like this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// business logic | |
public static List<Car> filterCarsByBrand(List<Car> cars, String brand) { | |
ArrayList<Car> filteredCars = new ArrayList<Car>(); | |
for (Car car : cars) { | |
if (brand.equals(car.getBrand())) { | |
filteredCars.add(car); | |
} | |
} | |
return filteredCars; | |
} | |
... | |
// from your programm, you can call it from this way | |
List<Car> filteredCars = filterCarsByBrand(cars, "Ferrari"); |
That it's ok. But now you want to filtering by brand and color too. You have to add a new method in order to support the new functionality. In this case, we can do it easily.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// business logic | |
public static List<Car> filterCarsByBrandAndColor(List<Car> cars, String brand, String color) { | |
// we can reuse the method to filtering by brand | |
List<Car> filteredCarsByBrand = filterCarsByBrand(cars, brand); | |
ArrayList<Car> filteredCars = new ArrayList<Car>(); | |
for (Car car : cars) { | |
if (color.equals(car.getColor())) { | |
filteredCars.add(car); | |
} | |
} | |
return filteredCars; | |
} | |
... | |
// from your programm, you can call it from this way | |
List<Car> filteredCars = filterCarsByBrand(cars, "Ferrari", "red"); |
What can we say about this code? In front of any new requirement, a new method is implemented. Then we have the phenomenon of method explosion.
We can try to do it better with a new interface called CarChecker.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// new interface | |
public interface CarChecker { | |
boolean check(Car car); | |
} | |
... | |
//business logic | |
public static List<Car> filterCars(List<Car> cars, CarChecker carChecker) { | |
ArrayList<Car> filteredCars = new ArrayList<Car>(); | |
for (Car car : cars) { | |
if (carChecker.check(car)) { | |
filteredCars.add(car); | |
} | |
} | |
return filteredCars; | |
} | |
... | |
// from your program | |
List<Car> filter1 = filterCars(input, new BrandCarChecker()); | |
List<Car> filter2 = filterCars(input, new BrandAndColorCarChecker()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
List<Car> cars = filterCars(input, new CarChecker() { | |
public boolean check(Car car) { | |
return "Ferrari".equals(car.getBrand()) && "red".equals(car.getColor()); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
List<Car> filteredCars = filterCars(input, car -> { | |
return "Ferrari".equals(car.getBrand()) && "red".equals(car.getColor()); | |
}); |
At this point, our code looks cool. But Java 8 includes something called Predicate. Then we can rewrite our business logic to this.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// business logic | |
public static List<Car> filterCars(List<Car> cars, Predicate<Car> carPredicate) { | |
ArrayList<Car> filteredCars = new ArrayList<Car>(); | |
for (Car car : cars) { | |
if (carPredicate.test(car)) { | |
filteredCars.add(car); | |
} | |
} | |
return filteredCars; | |
} | |
... | |
// from your program | |
List<Car> cars = filterCars(input, car -> {return "Ferrari".equals(car.getBrand()) && "red".equals(car.getColor());}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// business logic | |
public static void processCars(List<Car> cars, Predicate<Car> carPredicate, Consumer<Car> carConsumer) { | |
for (Car car : cars) { | |
if (carPredicate.test(car)) { | |
carConsumer.accept(car); | |
} | |
} | |
} | |
... | |
// from your program | |
processCars(input, c -> { return "Ferrari".equals(c.getBrand()); }, c -> System.out.println(c)); |
And that's all. Code more flexible and reusable.
Thanks lambdas.
No comments:
Post a Comment