resolve the instance of interface implementation - java

For e.g. If I have a interface and two implementation classes. Then I have class where I have to validate based on the implementation instance because each has its own validation. Now I m using instanceof to resolve this. Is there a better way to do this than the below code I have written?
public interface TestService{
public boolean testMethod();
}
public class TestServiceImpA implements TestService{
public boolean testMethod(){
return true;
}
//some other implementation
}
public class TestServiceImpB implements TestService{
public boolean testMethod(){
return false;
}
//some other implementation
}
import org.api.TestService;
public class ClassB {
public void methodValidator(TestService service){
//here I have to write some validation for each type.
//I have done this like
if(service instanceof TestServiceImpA)
{
TestType testype = TestUtil.getTestType(service.getId());
//now I need to validate testype based on this instaceof the interface
}
if(service instanceof TestServiceImpb)
{
}
}
}

Related

Abstract method with different parameters Java

public abstract class CommonClass {
abstract void send(<what should i put here???>) {}
}
public class ClassA extends CommonClass {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass {
void send(List<Post> postList) {
// do stuff
}
}
I am new to OODP, I am trying to have a method that is able to take in any kind of List data so that I can abstract things out. How can i do this?
You could make it generic on some type T. Like,
public abstract class CommonClass<T> {
abstract void send(List<T> al);
}
And then, to implement it - use the generic. Like,
public class ClassA extends CommonClass<Comments> {
#Override
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
Also, as discussed in the comments, your class names could be improved to be more intuitive; something like,
public abstract class AbstractSender<T> {
abstract void send(List<T> al);
}
and then
public class CommentSender extends AbstractSender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender extends AbstractSender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
That has the advantage(s) of being more readable and easier to reason about (I can tell what a PostSender does by reading the name, ClassB not so much).
Finally, this looks like a case where an interface would work since your abstract class is purely virtual (and should be preferred since you can implement multiple interface, but can only extend from a single parent class);
public interface ISender<T> {
void send(List<T> al);
}
public class CommentSender implements ISender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender implements ISender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
In order to achieve this, you can take multiple approaches, I would suggest looking into Generics: https://docs.oracle.com/javase/tutorial/java/generics/index.html
With that said, there is one approach that is the most elegant and simple: you can supply a List<T> where T is a generic type.
public abstract class CommonClass<T> {
abstract void send(List<T>) {}
}
public class ClassA extends CommonClass<Comment> {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
void send(List<Post> postList) {
// do stuff
}
}
You can do that with the help of generics. https://www.tutorialspoint.com/java/java_generics.htm
Example
The abstract class
public abstract class CommonClass {
public abstract <T> void send(List<T> data);
}
Its child
public class Child extends CommonClass {
public <T> void send(List<T> data) {
// code here
}
}
Retrieving the list's contents
Retrieving the generified list's contents is similar to retrieving any list's contents. In the scope of the method, "T" is a type of object contained in the list.
for (T t : data) {
// to check if t is a string
if (t instanceof String) {
// code
}
}
You can also use lambdas to retrieve every element in the list.

Interface segregation principle application

I'm wondering if the Interface segregation principle applys to my codebase.
Here's some example code:
First Class:
public class EntityGroup {
public List<Entity> tests;
//returns true if the EntityGroup is valid
public boolean validate() {
for (Entity test : tests) {
if (!test.validateFieldA() || !test.validateFieldB()) {
return false;
}
}
return true;
}
}
Second Class:
public abstract class Entity {
protected String fieldA;
public abstract boolean validateFieldA();
public abstract boolean validateFieldB();
}
Third Class:
public class EntityChild extends Entity {
private String fieldB;
#Override
public boolean validateFieldA() {
if (fieldA.equals("valid")) {
return true;
} else {
return false;
}
}
#Override
public boolean validateFieldB() {
if (fieldB.equals("valid")) {
return true;
} else {
return false;
}
}
}
Fourth Class:
public class EntityChild2 extends Entity {
#Override
public boolean validateFieldA() {
if (fieldA.equals("valid")) {
return true;
} else {
return false;
}
}
#Override
public boolean validateFieldB() {
return true;
}
}
This is a greatly simplified example from my real codebase but I think it illustrates the problem well. My EntityChild2 class is forced to implement a method it does not need or want to know about.
I know that it would be more correct to have a Interface that would contain the validateFieldB() method and only have EntityChild implement that interface.
With the understanding that this would take a significant amount of effort to refactor into this solution, I'm having a hard time justifying the time it would take to implement this solution in my real code base.
What potential problems will I run into down the line by leaving my code this way?
What benefits will I gain from refactoring my code to have a separate interface for validateFieldB()?
tldr: Why is the Interface Segregation Principle so important?
Wrong Abstraction
You make use of the interface segregation principle but with wrong abstractions.. Your different Entity-types differ only in they behavior.
Because of the shared behavior you have duplicate code in the methods validateFieldA of EntityChild and EntityChild2 . The method validateFieldB looks very similar to validateFieldA just the filed for checking the equality is an other.
You only need one Entity
Strategy Pattern
With the Strategy-Pattern you will have no duplicate code:
class EqualValidationStategy() implements ValidationStategy<T> {
#Override
public boolean check(T a, T b) {
return a.equals(b)
}
}
class TrueValidationStategy() implements ValidationStategy<T> {
#Override
public boolean check(T a, T b) {
return true;
}
}
Entity
public class Entity {
private String fieldA;
private String fieldB;
private ValidationStategy<String> validationForA;
private ValidationStategy<String> validationForB;
// all-args consturctor
#Override
public boolean validateFieldA() {
return validationForA.check(fieldA, "valid");
}
#Override
public boolean validateFieldB() {
return validationForB.check(fieldB, "valid");
}
}
// Validates fieldA and "ignores" fieldB
Entity example = new Entity(fieldA,
fieldB,
new EqualValidationStategy(),
new TrueValidationStategy());

Java Generic Interfaces with multiple implementations

I have the following scenario:
public abstract class BaseTask{...}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public interface TaskService<T extends BaseTask>{
void process(T task);
}
#Service #Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
}
#Service #Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{
}
public class ProcessingService{
#Autowired #Qualifier("taskServiceA")
private TaskService<TaskA> taskAService;
#Autowired #Qualifier("taskServiceB")
private TaskService<TaskB> taskBService;
public void process(Order o){
BaseTask task = o.getTask();
getTaskService(o).start(task);
}
private <T extends BaseTask> TaskService<T> getTaskService(Order o){
if("atype".equals(o.type)){
return (TaskService<T>) taskAService;
} else if("btype".equals(o.type)){
return (TaskService<T>) taskBService;
}
}
}
Update: I have reworded the question because the answers I was getting was not what I was looking for.
My questions is related to the getTaskService method.
Why do I need to cast the return value like this
return (TaskService) taskAService;
Is there another way to implement the getTaskService() method without having to do the cast?
I will really appreciate if someone can provide some explanation or better implementation for the getTaskService method.
How about this?
No need of any if conditions.
Later if someone does add another implementation of BaseTask they don't have to change any other code.
Also I recommend changing "atype" to Enum and using Map<EnumTask, ? extends BaseTask> serviceMap; instead of String.
Your final invocation of Tasks can be without any checks
#Service
class ProcessingService {
#Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
Other classes
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
#Service #Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
#Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
#Service #Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
#Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
Because type T is resolved wherever the method is used. The following statement is valid:
TaskService<TaskA> s = getTaskService(o);
So is:
TaskService<TaskB> s = getTaskService(o);
So within the method getTaskService, you don't know much about T.
The correct way to do this would be:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
The assignment above would have to become:
TaskService<? extends BaseTask> s = getTaskService(o);

data access object pattern with abstract factories, creation over generic types

I'm developing a database application for android devices.
First thing I need to do is creating the data access layer.
For this I want to use DAO-Pattern with abstract factories.
For all DAOs i have one Interface witch contains the declaration that all data object needs to implement. (in my case: IDataObject)
The specific DAOs are all represented by its own interface, extending the base interface of all DAOs.
base interface:
public interface IDataObject {
public IDataId getId();
public void write() throws MyDataWriteException;
public void validate() throws MyDataValidException;
}
a extensions:
public interface IDataSample1 extends IDataObject {
public void setNotice(String notice);
public String getNotice();
public void setDate(Date date);
public Date getDate();
}
To create an data object I want use abstract to use abstract factories, something like:
public interface IDataFactory<Template extends IDataObject> {
public List<Template> getAll();
public Template get(IDataId id);
public List<Template> getList(DataAccessArgument arg);
public List<Template> getList(List<DataAccessArgument> argList);
}
and the implementation:
public class DataSample1Fac implements IDataFactory<IDataSample1> {
public DataSample1Fac () {
}
public List<IDataSample1> getAll() {
return null;
}
public IDataSample1 get(IDataId id) {
return null;
}
public List<IDataSample1> getList(DataAccessArgument arg) {
return null;
}
public List<IDataSample1> getList(List<DataAccessArgument> argList) {
return null;
}
}
I don't get any error so far, but now I want to implement an factory builder:
public class DataFactoryBuilder {
private DataFactoryBuilder() {
}
public static<T extends IDataObject> IDataFactory<T> getFactory(){
if (T instanceof IDataSample1)
return new DataSample1Fac();
return null;
}
}
I get following errors(line 8):
T cannot be resolved to a variable
and (line 9)
Type mismatch: cannot convert from DataSample1Fac to IDataFactory<T>
Don't know how to fix this, any suggestions?
I would refactor Your's DataFactoryBuilder to something like that:
class DataFactoryBuilder {
private DataFactoryBuilder() {
}
public static IDataFactory<? extends IDataObject> getFactory(Class<? extends IDataObject> clazz){
if (IDataSample1.class.isAssignableFrom(clazz)) {
return new DataSample1Fac();
}
return null;
}
}
I got following solution:
public static <T extends IDataObject> IDataFactory<T> getFactory(Class<T> type) {
if (IDataSample1.class.isAssignableFrom(type)) {
DataSample1Facfac = new DataSample1Fac();
return (IDataFactory<T>) fac;
}
}
but i get an warning on: return (IDataFactory) fac;
Type safety: Unchecked cast from DataSample1Fac to IDataFactory<T>
I think that is not a problem, I just have to supress it

Change return value of final class in tests

Does somebody know how to change the return value of the method in the final class.
I'm trying to test the ToBeTested class and I want to get true as the result.
I tried to use Powermockito but didn't find a solution.
public final class ToBeChanged {
public static boolean changeMyBehaviour() {
return false;
}
}
public class ToBeTested {
public boolean doSomething () {
if (ToBeChanged.changeMyBehaviour)
return false;
else
return true;
}
}
I do not want to declare the ToBeChanged class as a field in the ToBeTested class.
So there is no way to change the implemented classes itself.
With the JMockit tool, the test would be like this:
#Test
public void doSomething(#Mocked ToBeChanged mock)
{
new NonStrictExpectations() {{ ToBeChanged.changeMyBehaviour(); result = true; }};
boolean res = new ToBeTested().doSomething();
assertTrue(res);
}
Hide the static dependency behind an interface. Mock the interface.
Since you don't want to have a field on your class, simply pass the interface as a method parameter (alternatively get an instance through a factory, just don't use tight coupling)
public final class ToBeChanged {
public static boolean changeMyBehaviour() {
return false;
}
}
public interface MyInterface {
boolean changeMyBehaviour();
}
public class MyInterfaceImpl implements MyInterface {
#Override
public boolean changeMyBehaviour() {
return ToBeChanged.changeMyBehaviour();
}
}
class ToBeTested {
public boolean doSomething (MyInterface myInterface) {
return !myInterface.changeMyBehaviour();
}
}
class TheTest {
#Test
public void testSomething() {
MyInterface myMock = mock(MyInterface.class);
when(myMock.changeMyBehaviour()).thenReturn(true);
new ToBeTested().doSomething(myMock);
}
}

Categories

Resources