I have a Car object that has several properties. Each of its properties are populated using a service (generally one property per service). Each of those services generally call a 3rd party web service (e.g. carClient) to get its data. Most of my services also have logic on how to populate its Car object field. For example:
#Service
#RequiredArgsConstructor
public class CarPriceService {
// client of a 3rd party web service interface
// I don't have control over this interface.
private final CarClient carClient;
public void setAutoPrice(Set<Car> cars) {
// in this case, only one call to the web service
// is needed. In some cases, I need to make two calls
// to get the data needed to set a Car property.
Map<String, BigDecimal> carPriceById =
carClient.getCarPrice(cars.stream().map(c->c.getId()).collect(Collector.toSet()));
for (Car car : cars) {
// in this case the poulating logic is simple
// but for other properties it's more complex
BigDecimal autoPrice = autoPriceById.get(car.getId());
car.setAutoPrice(autoPrice);
}
}
}
The order of populating the Car properties is sometimes important. For example, CarValueService sets car.value using car.condition which is set by CarConditionService.
Is there a design pattern that works for handling the gradual build of an object over services? I'm aware of the Builder pattern but not sure how it would apply here.
Some kind of Pipeline Pattern1, 2 variant comes to mind. For instance,
final class Test {
public static void main(String[] args) {
final Car car = new Car();
CarTransformer.of(c -> System.out.println("Install wheels!"))
.then(c -> System.out.println("Install engine!"))
.then(c -> System.out.println("Paint!"))
.transform(car);
}
static final class Car {}
static interface CarTransformer {
default CarTransformer then(final CarTransformer step) {
return (car) -> {
this.transform(car);
step.transform(car);
};
}
static CarTransformer of(final CarTransformer step) {
return step;
}
void transform(Car car);
}
}
Obviously you probably wouldn't inline all transformations, but you get the idea. Here we use function composition to create the pipeline, but you could also just store transformations in a list.
Furthermore, if building the transformation pipeline is complex, you could could add the builder pattern in the mix. E.g.
final class Test {
public static void main(String[] args) {
final Car car = new CarBuilder()
.installEngine("V8")
.installWheel("front-left")
.installWheel("rear-right")
.paint("metallic blue")
.build();
}
static final class Car {}
static interface CarTransformer {
default CarTransformer then(final CarTransformer step) {
return (car) -> {
this.transform(car);
step.transform(car);
};
}
static CarTransformer of(final CarTransformer step) {
return step;
}
void transform(Car car);
}
static final class CarBuilder {
private CarTransformer transformer;
CarBuilder() {
transformer = CarTransformer.of(c -> {});
}
CarBuilder paint(final String color) {
return then(c -> System.out.println("Paint in " + color));
}
CarBuilder installWheel(final String wheel) {
return then(c -> System.out.println("Install " + wheel + " wheel!"));
}
CarBuilder installEngine(final String engine) {
return then(c -> System.out.println("Install " + engine + " engine!"));
}
private CarBuilder then(final CarTransformer transformer) {
this.transformer = this.transformer.then(transformer);
return this;
}
Car build() {
final Car car = new Car();
transformer.transform(car);
return car;
}
}
}
Pipeline design pattern implementation
https://java-design-patterns.com/patterns/pipeline/
Related
I have an OOP approach to calculating a special code. There is a list of strategies that uses the chain of responsibility approach to calculate my value;
interface ChainStrategy {
Strategy getNext();
String getCode(SomeDto dto);
default String getDefaultVlue() {
return "";
};
}
class StrategyA implements ChainStrategy {
Strategy next;
StrategyA() {}
StrategyA(Strategy next) {
this.next = next;
}
Strategy getNext() {
return next;
}
public String getCode(SomeDto dto) {
if(dto.isA()) {
String result = dto.getA();
//this code could be placed in the abstract class to fulfill DRY
if(result == null) {
if(next!=null) {
result = next.getCode(dto);
}
else {
result = getDefaultVlue();
}
}
return result;
}
}
class StrategyB implements ChainStrategy {
// mostly the same code with different result calculation logic
}
class Client {
ChainStrategy strategy = new StrategyA(new StrategyB());
System.out.println(strategy.getCode())
}
}
This is "Java < 8" code that meets SOLID principles and can be easily tested. Usually, the real logic is more complicated than just dto.getA()
But it is just a chain of functions so I rewrite it:
interface ChainStrategy {
String getCode(SomeDto dto);
}
class CombineStrategy implements ChainStrategy {
private static final Function<SomeDto, Optional<String>> STRATEGY_A = dto -> Optional.of(dto).filter(SomeDto::isA).map(SomeDto::getA());
private static final Function<SomeDto, Optional<String>> STRATEGY_B = dto -> Optional.of(dto).filter(SomeDto::isB).map(SomeDto::getB());
private static final Function<SomeDto, String> STRATEGY_DEFAULT = dto -> "";
String getCode(SomeDto dto) {
Stream.of(STRATEGY_A, STRATEGY_B).map(st->st.apply(dto))
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst()
.orElseGet(() -> STRATEGY_DEFAULT.apply(dto));
}
}
And my questions:
This code has problems with a single responsibility and "open-close" principles. And I can't test my functions individually. But creating separate classes for my functions looks like an overhead. Do we need these principles in functional programming?
I can rewrite "String getCode" to another static function. And store all these functions as a static Util class. But I don't want to lose ability to dynamically substitute my ChainFunction in the runtime. How do people combine static functions and dynamic binding in functional languages?
I've tried to do some stuff with generics already but it seems I cannot personally find any simple solution. Still I think it'd be a sin to leave these 3 similar methods alone as they are.
public List<PassengerPlane> getPassengerPlanes() {
List<PassengerPlane> passengerPlanes = new ArrayList<>();
for (Plane plane : planes) {
if (plane instanceof PassengerPlane) {
passengerPlanes.add((PassengerPlane) plane);
}
}
return passengerPlanes;
}
public List<MilitaryPlane> getMilitaryPlanes() {
List<MilitaryPlane> militaryPlanes = new ArrayList<>();
for (Plane plane : planes) {
if (plane instanceof MilitaryPlane) {
militaryPlanes.add((MilitaryPlane) plane);
}
}
return militaryPlanes;
}
public List<ExperimentalPlane> getExperimentalPlanes() {
List<ExperimentalPlane> experimentalPlanes = new ArrayList<>();
for (Plane plane : planes) {
if (plane instanceof ExperimentalPlane) {
experimentalPlanes.add((ExperimentalPlane) plane);
}
}
return experimentalPlanes;
}
What do you need is generic method, but the problem is that instanceof cannot check against type parameter (it is in fact erased during compilation), it requires actual class reference. So, you may provide this to the method explicitly:
public <T extends Plane> List<T> getPlanes(Class<T> claz) {
List<T> result = new ArrayList<>();
for (Plane plane : planes) {
if (claz.isInstance(plane)) {
result.add(claz.cast(plane));
}
}
return result;
}
Note how instanceof and explicit cast changed to calls to .isInstance() and .cast()
Use it like
getPlanes(PassengerPlane.class)
You can make things a bit shorter with Streams, but I'm not sure there's a way to get around using instanceof here:
public List<PassengerPlane> getPassengerPlanes() {
return planes.stream().filter(t -> t instanceof PassengerPlane)
.map(t -> (PassengerPlane) t).collect(Collectors.toList());
}
public List<MilitaryPlane> getMilitaryPlanes() {
return planes.stream().filter(t -> t instanceof MilitaryPlane)
.map(t -> (MilitaryPlane) t).collect(Collectors.toList());
}
public List<ExperimentalPlane> getExperimentalPlanes() {
return planes.stream().filter(t -> t instanceof ExperimentalPlane)
.map(t -> (ExperimentalPlane) t).collect(Collectors.toList());
}
Here's how I would approach the problem using generics:
public <T> List<T> getTPlanes(Class<T> clazz) { //declare the method to take a type generic
List<T> tPlanes = new ArrayList<>(); //initialize an ArrayList of that type
planes.stream() //stream the planes list
.filter(clazz::isInstance) //filter it down to only planes of the type that we want
.forEach((p) -> tPlanes.add((T) p)); //add each plane left in the stream to our new ArrayList, and cast it to the type generic
return tPlanes; //return the ArrayList we just created and populated
}
You do need to do a cast somewhere: Here is a solution with a single method that takes the subtype.
import java.util.*;
import java.util.stream.*;
public class Example {
public static class Plane { }
public static class PassengerPlane extends Plane { }
public static class MilitaryPlane extends Plane { }
public static class ExperimentalPlane extends Plane { }
private static List<Plane> planes =
List.of(new PassengerPlane(),
new MilitaryPlane(),
new ExperimentalPlane());
public static <T extends Plane> List<T> getPlanesOfType(Class<T> type, List<Plane> planes) {
List<T> list =
planes.stream()
.filter(t -> type.isAssignableFrom(t.getClass()))
.map(t -> type.cast(t))
.collect(Collectors.toList());
return list;
}
public static void main(String[] args) throws Exception {
System.out.println(getPlanesOfType(PassengerPlane.class, planes));
System.out.println(getPlanesOfType(MilitaryPlane.class, planes));
System.out.println(getPlanesOfType(ExperimentalPlane.class, planes));
System.out.println(getPlanesOfType(Plane.class, planes));
}
}
[Example$PassengerPlane#7b227d8d]
[Example$MilitaryPlane#7219ec67]
[Example$ExperimentalPlane#45018215]
[Example$PassengerPlane#7b227d8d, Example$MilitaryPlane#7219ec67, Example$ExperimentalPlane#45018215]
You could either use the single method to replace all three or use it to implement.
If your problem is really so short, probably it won't be worthy the effort. However, this is a typical problem for Visitor Pattern (especially if your duplicate code is larger).
Step 1
Create a Visitor interface to visit each type of Plane:
interface Visitor {
void visit(MilitaryPlane militaryPlane);
void visit(ExperimentalPlane experimentalPlane);
void visit(PassengerPlane passengerPlane);
}
... and implement it in a way that starts with a List<Plane> that can be enriched by each of the .visit():
class PlaneVisitor implements Visitor {
private final List<Plane> planes;
PlaneVisitor(List<Plane> planes) {
this.planes = requireNonNull(planes);
}
#Override
public void visit(MilitaryPlane militaryPlane) {
planes.add(militaryPlane);
}
#Override
public void visit(ExperimentalPlane experimentalPlane) {
planes.add(experimentalPlane);
}
#Override
public void visit(PassengerPlane passengerPlane) {
planes.add(passengerPlane);
}
public List<Plane> getPlanes() {
return planes;
}
}
Step 2 - Enable visitors in your classes
Add an abstract method in your base class Plane to accept the visitor:
public abstract class Plane {
//...
abstract void accept(Visitor visitor);
//...
}
Then implement this method in each sub-class to let the Visitor instance visit itself (this). Example for PassengerPlane (same logic for all the other classes):
public class PassengerPlane extends Plane {
//...
#Override
void accept(Visitor visitor) {
visitor.visit(this);
}
//...
}
Step 3 - Adapt your function
Your function can now loop through the list of planes not caring about the type. It will be resolved by the visitor:
public List<Plane> getPlanes() {
PlaneVisitor planeVisitor = new PlaneVisitor(new ArrayList<>());
for (Plane plane : planes) {
plane.accept(planeVisitor);
}
return planeVisitor.getPlanes();
}
Note that you need to add a bit of methods / interfaces to do this. Since your code is very small, you can imagine to leave it like it is even if it's not very "elegant". However, the above example can be of inspiration if your code is actually supposed to do more than what you're showing us.
It can be done in this way by introduced a method that do common part:
private static <T> List<T> createFilteredList(List<Plane> inList, Class<T> clazz) {
List<T> outList = new ArrayList<>();
for (Plane value : inList) {
if (clazz.isInstance(value)) {
outList.add(clazz.cast(value));
}
}
return outList;
}
Then it can be used like this:
public List<PassengerPlane> getPassengerPlanes() {
return createFilteredList(planes, PassengerPlane.class);
}
public List<MilitaryPlane> getPassengerPlanes() {
return createFilteredList(planes, MilitaryPlane.class);
}
public List<ExperimentalPlane> getPassengerPlanes() {
return createFilteredList(planes, ExperimentalPlane.class);
}
So, you have an iterable of Plane as an input.
A Plane can be PassengerPlane, MilitaryPlane or ExperimentalPlane.
What you are trying to do is to filter a collection of planes by a predicate. A predicate is a function that takes a Plane and answers true or false. A filter uses a predicate to figure out whether to include a given item into the result or to skip.
If you are using Java 8 or later version, you can use the Streams API.
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
Produce a stream from the planes iterable.
Apply filter to it (intermediate operation).
Collect the results to list.
Using Stream API you can convert the methods above into one-liners. Like this:
planes.stream().filter(plane -> plane instanceof MilitaryPlane).collect(toList());
Then, probably, you won't need a separate neat method for it.
But if you want some reusable piece of code, then you have to figure out what is the parameter here. In the code above it is a specific plane implementation:
public List<Plane> filterPlanes(Iterable<Plane> planes, Class<? extends Plane> planeImplementation)
So, you can build a predicate with this parameter:
plane -> planeImplementation.isInstance(plane)
If you have a Plane supertype, you can make the subclasses inherit the getPlanes() method. this.getClass will extract only the planes of the subclass calling the method from the list. This way, you don't have to pass a class to the method, as it can be derived from the subclass that is calling it.
public abstract class Plane {
public Plane(){}
public List<Plane> getPlanes() {
List<Plane> result = new ArrayList<>();
for (Plane plane : planes) {
if (this.getClass().isInstance(plane)) {
result.add(this.getClass().cast(plane));
}
}
return result;
}
}
class PassengerPlane extends Plane {
}
class MilitaryPlane extends Plane {
}
class ExperimentalPlane extends Plane {
}
public class PlaneList {
public String name;
public static ArrayList<Plane> planes = new ArrayList<>();
public PlaneList(){
planes.add(new MilitaryPlane());
planes.add(new MilitaryPlane());
planes.add(new MilitaryPlane());
planes.add(new PassengerPlane());
planes.add(new PassengerPlane());
planes.add(new ExperimentalPlane());
}
}
I tested it like so:
public class Main {
public static void main(String[] args) {
PlaneList list = new PlaneList();
Plane plane = new PassengerPlane();
for(Plane p : plane.getPlanes()){
System.out.println(p.toString());
}
}
}
output:
com.company.PassengerPlane#7dc36524
com.company.PassengerPlane#35bbe5e8
I am trying to map values from one enum to the other based on some calculation or conditional logic that I need to perform to set the correct enum value for the class variable. How can I do this without using too many if/else, switch statements?
Enum BRAND {
MINI, FERRARI, PAGANI
}
and another enum
Enum ENGINE {
LEVEL1, LEVEL2, LEVEL3
}
And I have a class like :
Class Car() {
int model;
int year;
Engine engine;
// I want to calculate set the engine depending on the brand based on conditional logic
public carEngineCalculator (Brand b) {
Car mycar = new Car();
if (mycar.isSuperCar(b) {
if (mycar.isCrazyGood(b)) {
mycar.engine = ENGINE.LEVEL1;
} else {
mycar.engine = ENGINE.LEVEL2;
}
} else {
mycar.engine = ENGINE.LEVEL3;
}
... //And the conditions can be more complex
}
public boolean isSuperCar(Brand b) {
if (b.FERRARI || b.PAGANI) {
return true;
}
return false;
}
public boolean isCrazyGood(Brand b) {
return ...;
}
}
There can be more than one such conditions that need to be checked in order to set the values and I want to avoid nasty if/else/switch statements as shown above. Is there a more functional way of doing this.
Using predicates as I said would look like this:
public enum Brand {
MINI,
FERRARI,
PAGANI
}
public enum Engine {
LEVEL1,
LEVEL2,
LEVEL3
}
public class Entry {
public final Predicate<Car> pred;
public final Engine engine;
public Entry(Predicate<Car> pred, Engine engine) {
this.pred = pred;
this.engine = engine;
}
}
public class Car {
int model;
int year;
Engine engine;
public void carEngineCalculator(Brand b) {
Car mycar = new Car();
List<Entry> cases = new ArrayList<>();
cases.add(new Entry(c -> c.isSuperCar(b) && c.isCrazyGood(b), Engine.LEVEL1));
cases.add(new Entry(c -> c.isSuperCar(b) && !c.isCrazyGood(b), Engine.LEVEL2));
cases.add(new Entry(c -> !c.isSuperCar(b), Engine.LEVEL3));
mycar.engine = cases.stream().filter(x -> x.pred.test(mycar)).findFirst().get().engine;
}
public boolean isSuperCar(Brand b) {
if ((b == Brand.FERRARI) || (b == Brand.PAGANI)) {
return true;
}
return false;
}
public boolean isCrazyGood(Brand b) {
return false;
}
}
You create a List with Predicates and Results and use stream, filter and findFirst to go through the list and find the right result. If the conditions are simpler than you don't need predicates and test it a little bit different.
If the mapping is one-to-one for Brand and Engine, you could do something like this:
enum Brand {
MINI(Engine.LEVEL1),
FERRARI(Engine.LEVEL2),
PAGANI(Engine.LEVEL3);
private final Engine engine;
private Brand(Engine engine) {
this.engine = engine;
}
public final Engine getEngine() {
return engine;
}
}
Another option:
enum Brand {
MINI(false, false),
FERRARI(true, true),
PAGANI(false, true);
private final boolean superCar;
private final boolean crazyGood;
private Brand(boolean superCar, boolean crazyGood) {
this.superCar = superCar;
this.crazyGood = crazyGood;
}
public final Engine getEngine() {
if (superCar) {
return (crazyGood) ? Engine.LEVEL1 : Engine.LEVEL2;
}
return Engine.LEVEL3;
}
}
If the mapping is not one-to-one and you need to somehow dynamically calculate the engine based on some parameters, you could also use this:
enum Brand {
MINI {
#Override
public Engine getEngine(boolean superCar, boolean crazyGood) {
return (superCar && crazyGood) ? Engine.LEVEL1 : Engine.LEVEL2;
}
},
FERRARI {
#Override
public Engine getEngine(boolean superCar, boolean crazyGood) {
return superCar ? Engine.LEVEL1 : Engine.LEVEL3;
}
},
PAGANI {
#Override
public Engine getEngine(boolean superCar, boolean crazyGood) {
return Engine.LEVEL3;
}
};
public abstract Engine getEngine(boolean superCar, boolean crazyGood);
}
Or something like this, where you have some defaults and override just for special cases:
enum Brand {
MINI,
FERRARI {
#Override
public Engine getEngine(boolean superCar, boolean crazyGood) {
return superCar ? Engine.LEVEL1 : Engine.LEVEL3;
}
},
PAGANI;
public Engine getEngine(boolean superCar, boolean crazyGood) {
return Engine.LEVEL3;
}
}
There are a lot of possibilities using just enums, which I actually prefer to complex if/else or switch statements. Of course it depends on what exactly you want to do and since there is not much info provided, I cannot really give the best answer. Hope that this helps you.
First, move your isSuperCar and isCrazyGood methods into Brand, rather than have them take a Brand parameter. You could similarly add a static factory method to Engine that encapsulates the logic you're trying to encode. That doesn't wholly avoid the "nasty if/else/switch statements", but it's likely to be a lot more readable.
For example:
public Car(Brand b) {
this.engine = Engine.forBrand(b);
}
and then:
enum Engine {
LEVEL1, LEVEL2, LEVEL3
public static Engine forBrand(Brand b) {
if (b.isSuperCar()) {
return b.isCrazyGood() ? LEVEL1 : LEVEL2;
}
return LEVEL3;
}
}
Note also that your isSuperCar method can simply be:
return b.equals(Brand.FERRARI) || b.equals(Brand.PAGANI);
There's never a need to write if (...) return true; else return false; or anything similar - just use the boolean expression in the if statement directly.
I would probably store the brand in the Car class, but that is another issue. I would have a static map in the Car class that keeps track of which engines go with each brand (as Ralf Renz suggested):
Class Car {
int model;
int year;
Engine engine;
static Map<Brand, Engine> carEngineMap = new HashMap<>();
public static void setBrandEngine(Brand b, Engine e) {
carEngineMap.put(b, e);
}
// I want to calculate set the engine depending on the brand based on conditional logic
public carEngineCalculator (Brand b) {
Car mycar = new Car();
mycar.engine = carEngineMap.get(b);
}
public boolean isSuperCar(Brand b) {
if (b.FERRARI || b.PAGANI) {
return true;
}
return false;
}
public boolean isCrazyGood(Brand b) {
return ...;
}
}
You would then put the conditions in separately for each brand, like
Car.setBrandEngine(Brand.FERRARI, Engine.LEVEL2);
Car.setBrandEngine(Brand.PAGANI, Engine.LEVEL1);
...
create enum with predicates, CONDITION(brand, engine, condition) and supply your condition there. Afterwards:
Conditions.values().foreach(condition -> {
condition.isApplicable(variblesDto) ? return condition.apply() : continue;
});
and you update your Enum anytime you need new condition. It will also go in order of Enum, so you could play with that
I have a client like with a constructor which is quite lengthy in terms of the argument list , e.g,
Class Client {
private ServiceA _serviceA;
private ServiceB _serviceB;
....
private ServiceE _serviceE;
public Client(ServiceA serviceA, ServiceB serviceB,...ServiceE service E) { ... }
public doTask1(TypeA typeA) { //only serviceA, serviceB service being used... }
public doTask2(TypeB typeB) { //only serviceD, serviceE being used ... }
}
I want to use a service facade here to prune the constructor argument list. However, I am pretty confused as the core responsibility of the facade implementation. So I have written down a facade with the services as the class variables and their getters , as below:
Class Facade {
private ServiceA _serviceA;
private ServiceB _serviceB;
....
private ServiceE _serviceE;
getters () ...
}
Is this correct way to abstract facade in this case. If not , what would have been the proper way to refactor the Client class?
Facedes has a completely different intent: they are created to encapsulate and hide the underlying structure and behaviour of classes. Take an example of a car. It's made of many components: on-board computer, fuel pump, engine etc. If you want to start it, just press the start button:
class FuelPump {
private boolean pumpTurnedOn;
public FuelPump() {
pumpTunrnedOn=false;
}
public boolean isPumpTunredOn() {
return pumpTurnedOn;
}
public void setPumpTurnedOn (boolean newState) {
pumpTurndeOn=newState;
if (newState) {
System.out.println ("fuel pump now is on");
} else {
System.out.println ("fuel pump now is turned off");
}
}
}
class Engine {
private boolean engineStarted;
public Engine() {
engineStarted=false;
}
public boolean isEngineStarted() {
return engineStarted;
}
public void setEngineStarted (boolean newState) {
engineStarted=newState;
if (newState) {
System.out.println("engine now is on");
} else {
System.out.println("engine now is turned off");
}
}
}
// this is the Car facade:
class Car {
private FuelPump fuelPump;
private Engine engine;
// + other components of Car
public Car () {
fuelPump = new FuelPump();
engine = new Engine();
}
public void startCar() {
fuelPump.setPumpTurnedOn(true);
engine.setEngineStarted(true);
// + other methods of start procedures with other components
System.out.println("Your car has been startded");
}
public void stopCar() {
engine.setEngineStarted(false);
fuelPump.setPumpTurnedOn(false);
// + other methods on other components for shutting down car
}
}
The client code snippet:
Car car=new Car();
car.startCar();
// later on
car.stopCar();
As you may see the client doesn't know anything about the underlying components to start the car. It has only to use the startCar() method, and the Car facade will do the rest. Facade is a structural pattern.
If you have many constructor arguments and want to reduece them use one of the creational patterns. In case you have compulsory and non compulsory fields I suggest using the builder pattern.
For example your compulsory constructor arguments are Service_A and Service_B and Service_C to Service_E are not required.
Then your ClientBuilder class should like be this:
class ClientBuilder{
private static Service_A serviceA; // required
private static Service_B serviceB; // required
private static Service_C serviceC;
private static Service_D serviceD;
private static Service_E serviceE;
// since this builder is singleton
private static ClientBuilder builderInstance = new ClientBuilder();
private ClientBuilder () {};
public static ClientBuilder getBuilderInstance (Service_A service_A, Service_B service_B){
serviceA = service_A;
serviceB = service_B;
serviceC = null;
serviceD = null;
serviceE = null;
return builderInstance;
}
public static ClientBuilder addServiceC (Service_C service_C) {
serviceC = service_C;
return builderInstance;
}
public static ClientBuilder addServiceD (Service_D service_D) {
serviceC = service_D;
return builderInstance;
}
public static ClientBuilder addServiceE (Service_E service_E) {
serviceE = service_E;
return builderInstance;
}
public static Client build(){
return new Client (serviceA, ServiceB, ServiceC, ServiceD, ServiceE);
}
In this case you can instantinate your Client class only with the mandatory arguments. The best thing is the not required arguments' order are interchangeable:
Client aClient = ClientBuilder.getBuilderInstance(aServiceA, aServiceB)
.addServiceE(aServiceE)
.addServiceC(aServiceC)
.build();
Now aClient has been created with services A,B,C,E and serviceD remains null. Later you can set it by appropriate setter. The getters and setters must be in your Client class.
To put it in a nutshell, with builder class you can reduce the number of constructor arguments only for the mandatory and set up optional fields later with setters.
You can read more details in the Gang of Four book or if you are a serious Java fun I suggest Head First's Design Patterns book.
Hope I could help you, bye!
I have a class of entity which have a lot of field and I would like to create observable entity to this class so I can use this to Binding.
The entity's code can't be change. how can I do it?
Let's assume that my code look like that:
class Car {
private Wheel wheel;
private Engine engine;
private Door door;
// and a lot of field.
}
and I want to create ObservableCar that become invalidate each time any of the field change.
The car code doesn't change. And the class of the field too.
How can I do it?
Thanks in advance.
Implement your Car class using JavaFX properties:
public class Car {
private final ObjectProperty<Wheel> wheel = new SimpleObjectProperty<>();
public ObjectProperty<Wheel> wheelProperty() {
return wheel ;
}
public final Wheel getWheel() {
return wheelProperty().get();
}
public final void setWhee(Wheel wheel) {
wheelProperty.set(wheel);
}
// other properties...
}
Now you can create a ObjectBinding<Car> that invalidates when any of the properties invalidate:
public class CarBinding extends ObjectBinding<Car> {
private final Car car ;
public CarBinding(Car car) {
this.car = car ;
bind(car.wheelProperty(), car.engineProperty(), ...);
}
#Override
public Car computeValue() {
return car ;
}
}
If it's more convenient, you can build the binding directly into your car class:
public class Car {
// properties as before...
private final ObjectBinding<Car> carBinding = new ObjectBinding<Car>() {
{
bind(wheelProperty(), engineProperty(), ...);
}
#Override
public Car computeValue() {
return Car.this ;
}
}
public ObjectBinding<Car> asBinding() {
return carBinding ;
}
}