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 ;
}
}
Related
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/
Best way to implement factory pattern in Spring boot.
I've an interface and multiple implementations of it. During a request, I need to return the bean based on an input string.
There are multiple ways I can do it.. But whats the best way?
interface vehicle {
void drive();
string getVehicleName();
}
#Component
public class Car implements vehicle {
private static string prop = "car";
#Override
string getVehicleName() { return prop;}
#Override
void drive() {}
}
#Component
public class Bike implements vehicle {
private static string prop = "bike";
#Override
string getVehicleName() { return prop;}
#Override
void drive() {}
}
#Service
public class VehicleFactory {
#Autowired
private List<vehicle> vehicles;
private static final HashMap<String, vehicle> requestVehicleMap = new HashMap<>();
#PostConstruct
public void initVehicleFactory() {
for(vehicle vehicle : vehicles) {
requestVehicleMap.put(vehicle.getVehicleName(), request);
}
}
public static vehicle getVehicleImpl(String vehicleName) {
return requestVehicleMap.get(vehicleName);
}
}
This does give me correct class.
Also there is "qualifier" that can be used as Implementing custom factory pattern in Spring.
But is there better approach?
Interface and it's Implementation are good, I would just change the Factory class alone because you already I got the List of Implementation then Why again to initialise it in a Map
I will also comment the suggestions in the code
VehicleFactory
#Service
public class VehicleFactory {
#Autowired
private List<Vehicle> vehicles;
public Vehicle getVehicleImpl(String vehicleName) { // You have already declared as #Service then why use static
return vehicles.stream()
.filter(vehicle -> vehicle.getVehicleName().equalsIgnoreCase(vehicleName)) // This will filter the Impl you needed from others
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format(" Invlaid Vehicle Name - %s", vehicleName))); // Incase Impl is not found it should throw an error or handle in some other ways
}
}
So give it a try
I have faced this problem a few times in the past, but haven't really found a good solution/design for it.
The below example code will generate PDF doc from Entity (Company or Article)
public class Entity
{
int id;
}
public class Company extends Entity
{
private String HQ;
}
public class Article extends Entity
{
private String title;
}
public interface EntityPDFGenerator
{
void generate(Entity entity);
}
public class ArticlePDFGenerator implements EntityPDFGenerator
{
public void generate(Entity entity)
{
Article article = (Article) entity;
// create Article related PDF from entity
}
}
public class CompanyPDFGenerator implements EntityPDFGenerator
{
public void generate(Entity entity)
{
Company company = (Company) entity;
// create Company related PDF
}
}
Main class:
public class PDFGenerator
{
public void generate(Entity entity)
{
EntityPDFGenerator pdfGenerator = getConcretePDFGenerator(entity);
pdfGenerator.generate(entity);
}
// lets make the factory task simple for now
EntityPDFGenerator getConcretePDFGenerator(Entity entity)
{
if(entity instanceof Article){
return new ArticlePDFGenerator();
}else{
return new CompanyPDFGenerator();
}
}
}
In the above approach the problem is with the casting the Entity to the concrete type (casting can be dangerous in later stage of the code). I tried to make it with generics, but then I get the warning
Unchecked call to 'generate(T)'
Can I improve this code?
Here, you go with the suggested changes:
public interface EntityPDFGenerator<T extends Entity> {
void generate(T entity);
}
public class ArticlePDFGenerator implements EntityPDFGenerator<Article> {
public void generate(Article entity)
{
// create Article related PDF from entity
}
}
public class CompanyPDFGenerator implements EntityPDFGenerator<Company> {
public void generate(Company entity)
{
// create Company related PDF
}
}
Short answer
Generics is not the right tool here. You can make the casting explicit:
public class CompanyPDFGenerator implements EntityPDFGenerator
{
public void generate(Entity entity)
{
if (! (entity instanceof Company)) {
throw new IllegalArgumentException("CompanyPDFGenerator works with Company object. You provided " + (entity == null ? "null" : entity.getClass().getName()));
}
Company company = (Company) entity;
System.out.println(company);
// create Company related PDF
}
}
Or you can define some sort of data structure in the entity class and use only that in the printer:
public abstract class Entity
{
int id;
public abstract EntityPdfData getPdfData();
}
// ...
public class CompanyPDFGenerator implements EntityPDFGenerator
{
public void generate(Entity entity)
{
EntityPdfData entityPdfData = entity.getPdfData();
// create Company related PDF
}
}
Long answer
Generics is useful if you know the types at compile-time. I.e. if you can write into your program that actual type. For lists it looks so simple:
// now you know at compile time that you need a list of integers
List<Integer> list = new ArrayList<>();
In your example you don't know that:
public void generate(Entity entity)
{
// either Article or Company can come it. It's a general method
EntityPDFGenerator pdfGenerator = getConcretePDFGenerator(entity);
pdfGenerator.generate(entity);
}
Suppose you want to add type to the EntityPDFGenerator , like this:
public static interface EntityPDFGenerator<T extends Entity>
{
void generate(T entity);
}
public static class ArticlePDFGenerator implements EntityPDFGenerator<Article>
{
public void generate(Article entity)
{
Article article = (Article) entity;
// create Article related PDF from entity
}
}
public static class CompanyPDFGenerator implements EntityPDFGenerator<Company>
{
public void generate(Company entity)
{
Company company = (Company) entity;
// create Company related PDF
}
}
This looks nice. However, getting the right generator will be tricky. Java generics is invariant. Even ArrayList<Integer> is not a subclass of ArrayList<Number>. So, ArticlePdfGenerator is not a subclass of EntityPDFGenerator<T extends Entity>. I.e. this will not compile:
<T extends Entity> EntityPDFGenerator<T> getConcretePDFGenerator(T entity, Class<T> classToken)
{
if(entity instanceof Article){
return new ArticlePDFGenerator();
}else{
return new CompanyPDFGenerator();
}
}
I would suggest to move the getGenerator() method in the Entity class and override it in the Company and Article classes.
Unless, of course, there is a good reason not to.
I'm working on a small project where I want to have a list of a class called "DevelopmentEmployee", but only one of them is allowed to manipulate certain methods in another class "Project". The way I have implemented it, the class Project has a field called projectLeader, which is of the type DevelopmentEmployee. When a DevelopmentEmployee attempts to access methods in the class Project, I want to check if the DevelopmentEmployee is equal to the specific instance of Project's projectLeader.
Something like
public class Project {
private DevelopmentEmployee projectLeader;
private List < Activity > activities = new ArrayList < Activity > ();
public Project(DevelopmentEmployee pL) {
this.projectLeader = pL;
}
public void addActivity(String activityName) {
if (projectLeader.equals(DevelopmentEmployee * ) {
activities.add(activity);
}
}
}
But I can't figure out a way to make the access requirement work. How can the instance of the class Project know who is trying to access it?
You should also pass the DevelopementEmployee in addActivity for checking it against the projectLeader.
public void addActivity(String activityName,DevelopmentEmployee employee) {
if (projectLeader.equals(employee) {
activities.add(activity);
}
}
Then you need to override equals method in DevelopmentEmployee class, for proper checking of equality, like the one as shown below :
public boolean equals(DevelopementEmployee e){
if(e!=null && this.employeeId==e.employeeId)
return true;
else
return false;
}
Several possibilities come to mind:
Provide the instance of the one accassing the project method to the method:
public void addActivity(String activityName, DevelpmentEmployee user) {
if (projectLeader.equals(user)) {`
Create some class that holds information about active user and use that inside the methods:
public class Project {
private UserRegistry userRegistry;
private List<Activity> activities = new ArrayList<Activity>();
public Project(UserRegistry userRegistry) {
this.userRegistry = userRegistry;
}
public void addActivity(String activityName) {
if (userRegistry.isActiveUserProjectLeader()) {
activities.add(activity);
}
}
}
public class UserRegistry {
private DevelpmentEmployee projectLeader;
private DevelpmentEmployee activeUser;
private List<DevelpmentEmployee> user;
public void addUser(DevelpmentEmployee user) { ... }
public void makeProjectLeader(DevelpmentEmployee newLeader) { ... }
public void makeActiveUser(DevelpmentEmployee newActiveUser) { ... }
public boolean isActiveUserProjectLeader() { ... }
}`
I have an app with multiple classes:
MenuActivity, MenuThread, MenuView, MenuBot, MenuBall.
In the class "MenuView" I declare all the ib objects I need:
this.ball = new MenuBall(this, bot1);
this.bot1 = new MenuBot1(this, ball);
this.thread = new MenuThread(this,bot1,ball);
As you can see i didn't create yet the object bot1 but i already use it as a parameter in the object ball, which gives me the error.
Thank you for trying to help me !
You have to change (or add other) constructors of MenuBall and MenuBot1.
Thus, for example:
public class MenuBall {
private MenuBot1 menuBot1;
(...)
// this constructor doesn't need a MenuBot1 object.
public MenuBall(MenuView menuView) {
(...)
}
// setter for the menuBot1
public void setMenuBot1(MenuBot1 menuBot1) {
this.menuBot1 = menuBot1;
}
(...)
}
public class MenuBot1 {
private MenuBall menuBall;
(...)
// this constructor doesn't need a MenuBall object.
public MenuBot1(MenuView menuView) {
(...)
}
// setter for the menuBall
public void setMenuBall(MenuBall menuBall) {
this.menuBall = menuBall;
}
(...)
}
Then in MenuView class:
ball = new MenuBall(this);
bot1 = new MenuBot1(this);
ball.setMenuBot1(bot1);
bot1.setMenuBall(ball);
thread = new MenuThread(this, bot1, ball);
(...)