SuperService:
package service;
public interface SuperService {
}
CustomerService:
package service.custom;
import dto.Customer;
import java.util.List;
public interface CustomerService{
boolean add(Customer customer);
Customer search(String id);
boolean update(String id, Customer customer);
boolean delete(String id);
List<Customer> getAll();
}
CustomerServiceImpl:
package service.custom.impl;
import dto.Customer;
public class CustomerServiceImpl{
public boolean add(Customer customer) {
return false;
}
}
ServiceFactory:
package service;
import service.custom.impl.CustomerServiceImpl;
import service.custom.impl.ItemServiceImpl;
import service.custom.impl.OrderServiceImpl;
import util.ServiceType;
public class ServiceFactory {
private static ServiceFactory instance;
private ServiceFactory(){
}
public static ServiceFactory getInstance(){
if(instance==null){
instance= new ServiceFactory();
}
return instance;
}
public <T extends SuperService> T getServiceType(ServiceType type){
switch (type){
case CUSTOMER:return (T) new CustomerServiceImpl();
case ITEM:return (T) new ItemServiceImpl();
case ORDER:return (T) new OrderServiceImpl();
}
return null;
}
}
CustomerFormController:
package controller;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField;
import dto.Customer;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import service.ServiceFactory;
import service.custom.CustomerService;
import util.ServiceType;
public class CustomerFormController {
@FXML
private JFXButton btnAdd;
@FXML
private JFXButton btnDelete;
@FXML
private JFXButton btnReload;
@FXML
private JFXButton btnSearch;
@FXML
private JFXButton btnUpdate;
@FXML
private TableColumn<?, ?> colAddress;
@FXML
private TableColumn<?, ?> colId;
@FXML
private TableColumn<?, ?> colName;
@FXML
private TableColumn<?, ?> colSalary;
@FXML
private TableView<?> tblCustomers;
@FXML
private JFXTextField txtAddress;
@FXML
private JFXTextField txtId;
@FXML
private JFXTextField txtName;
@FXML
private JFXTextField txtSalary;
@FXML
void btnAddOnAction(ActionEvent event) {
String idText = txtId.getText();
String nameText = txtName.getText();
String addressText = txtAddress.getText();
double salary = Double.parseDouble(txtSalary.getText());
Customer customer = new Customer(idText, nameText, addressText, salary);
CustomerService service = ServiceFactory.getInstance().getServiceType(ServiceType.CUSTOMER);
service.add(customer);
}
@FXML
void btnDeleteOnAction(ActionEvent event) {
}
@FXML
void btnReloadOnAction(ActionEvent event) {
}
@FXML
void btnSearchOnAction(ActionEvent event) {
}
@FXML
void btnUpdateOnAction(ActionEvent event) {
}
}
This is a layered architecture design and here I have tried to use the factory design pattern to pass a CustomerServiceImpl
object from the service layer to the controller/presentation layer. I was trying to understand bounded type generics and decided to do an experiment to understand the concept then only i ran into the problem. Can you help me understand why there is no compile error at CustomerService service = ServiceFactory.getInstance().getServiceType(ServiceType.CUSTOMER);
since the CustomerService
doesn't extend SuperService
and CustomerServiceImpl
doesn't implement CustomerService
so shouldn't the compile understand that a CustomerService
reference cannot be used for a CustomerServiceImpl
object?
You don´t get a Compile Error because you are casting here:
public <T extends SuperService> T getServiceType(ServiceType type){
switch (type){
case CUSTOMER:return (T) new CustomerServiceImpl();
case ITEM:return (T) new ItemServiceImpl();
case ORDER:return (T) new OrderServiceImpl();
}
return null;
}
With type erasure in place you basically casting all the Impls to SuperService.
Now since SuperService is an interface you won´t get a compile error, but you will get a runtime error!
It basically boils down to this:
Casting to unrelated interfaces does not give you a compile error.
More info can be found here: Why does it compile when casting to an unrelated interface?