I have some handlers who implements interface. Each handler should serve some cases according to one or more types. I get the list of that handlers via autowired.
So when I want to use these handler in the iterate over them and check whether some of them handle the case, if so I run it on the case.
As describe here -
#Service
public class CarCreator implments ICreator{
#Override
public boolean shouldServe(IEntity entity){
entity.getType().equal(Type.Car);
}
#Override
public boolean crate(IEntity entity){ .. some code ...}
}
#Service
public class HouseCreator implments ICreator{
#Override
public boolean shouldServe(IEntity entity){
entity.getType().equal(Type.House);
}
#Override
public boolean crate(IEntity entity){ .. some code ...}
}
#Service
public class AnimalCreator implments ICreator{
#Override
public boolean shouldServe(IEntity entity){
entity.getType().equal(Type.Animal);
}
#Override
public boolean crate(IEntity entity){ .. some code ...}
}
interface ICreator{
boolean shouldServe(IEntity entity);
public boolean crate(IEntity entity);
}
public void EntitiesCreatorManger{
List<ICreator> creators;
#Autowired
public EntitiesCreatorManger(List<ICreator> creators){ this.creators = creators;}
public void createEntities(List<IEntity> entitites){
entities.stream.forEach(entity-> {
for(ICreator creator : creators){
if(creator.shouldServe(entity){
creator.create(entity);
break;
}
}
}
}
I want to do it with more elegant way and not for each list of interfaces in my system to use like this. Is there such way?
put all your ICreators in a lookup map:
Map<IEntity, ICreator> map = ...
ICreator creator = map.get(entity);
if(creator != null) {
...}
You seem to have an enumeration of types. Move the create logic onto the enum instances, and delegate to the create() call to the type.
public enum Type implements ICreator {
Car {
#Override
public void create(IEntity entity) {
// car creation
}
},
House {
#Override
public void create(IEntity entity) {
// house creation
}
},
Animal{
#Override
public void create(IEntity entity) {
// animal creation
}
};
}
public void EntitiesCreatorManager{
public void createEntities(List<IEntity> entities){
entities.forEach(entity -> entity.getType().create(entity));
}
}
Related
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.
Whats the recommended design approach/alternative to the situation below:
BaseCalculator:
BaseType prepareData()
useData(BaseType)
Derived calculators use derived type to override base functionality -
DerivedCalculator1:
BaseType prepareData(){ return DerivedType1}
useData(BaseType t1){ DerivedType1 t=(DerivedType1)t1 //typecast down and proceed....}
DerivedCalculator2
BaseType prepareData(){ return DerivedType2}
useData(BaseType t1){ DerivedType2 t=(DerivedType2)t1 //typecast down and proceed....}
Is there a design approach to avoid typecasting by the derived classes - as it always leaves the gate open for a run-time mishap?
One alternative is to move the polymorphic behavior into the implementations of the BaseType rather than in the implementations of BaseCalculator. For example:
public interface BaseType {
public void process(Calculator calc);
}
public class DerivedType1 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 1
}
}
public class DerivedType2 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 2
}
}
public class Calculator {
public void doSomething(BaseType bt) {
bt.process(this);
}
}
If that type of solution is insufficient, a more complex solution is the Visitor Pattern. The Visitor Pattern allows any arbitrary BaseType object to be handled by any arbitrary BaseCalculator using double-dispatch. The catch is that all BaseCalculator implementations must have an method to handle each of the BaseType implementations. For example:
public interface BaseType {
public void process(Calculator calc);
}
public class DerivedType1 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 1
}
}
public class DerivedType2 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 2
}
}
public interface BaseCalculator {
public void handle(DerivedType1 dt);
public void handle(DerivedType2 dt);
}
public class DerviedCalculator1 implements BaseCalculator {
#Override
public void handle(DerivedType1 dt) {
dt.process(this);
}
#Override
public void handle(DerivedType2 dt) {
dt.process(this);
}
}
public class DerviedCalculator2 implements BaseCalculator {
#Override
public void handle(DerivedType1 dt) {
dt.process(this);
}
#Override
public void handle(DerivedType2 dt) {
dt.process(this);
}
}
I am little confused how to avoid using casing in my manager method (last snippet of code) in terms of abstract class with it's derived classes (entities) and visitor design pattern eventually. Below I have an abstract class for entities called BaseEntity. It's not a real example, just pseudocode.
public abstract class BaseEntity {
#Reference
protected List<String> items = new ArrayList<>();
public BaseEntity() {
}
public List<String> getItems() {
return items;
}
public void setItems(List<String> items) {
this.items = items;
}
}
Below I have 3 derived classes from abstract class.
#Entity("CollectionA")
public class EntityA extends BaseEntity {
//code
}
#Entity("CollectionB")
public class EntityB extends BaseEntity {
//code
}
#Entity("CollectionC")
public class EntityC extends BaseEntity {
//code
}
Then I created an visitor to reuse that in my manager to avoid using instanceOf.
public interface UpdateEntityVisitor {
void create(EntityA entityA);
void create(EntityB entityB);
void create(EntityC entityC);
}
public class UpdateEntityVisitorImpl implements UpdateEntityVisitor {
private final Factory factory;
public UpdateEntityVisitorImpl() {
factory = new FactoryImpl();
}
public UpdateEntityVisitorImpl(Factory factory) {
this.factory = factory;
}
#Override
public void create(EntityA entityA) {
factory.getEntityA().create(entityA);
}
#Override
public void create(EntityB entityB) {
factory.getEntityB().create(entityB);
}
#Override
public void create(EntityC entityC) {
factory.getEntityC().create(entityC);
}
}
And finally it's my manager class which has below method, where I would like to avoid casting down from BaseEntity to appropriate classes. There is a way to achieve that reusing above visitor class in manager ?
public void updateEntity(BaseEntity entity) {
if (checkSmth()) {
updateCollectionA((EntityA) entity);
} else {
updateCollectionB((EntityB) entity);
}
}
I found this very useful library called typeOf https://github.com/nurkiewicz/typeof but I was wondering if there is other way to make it more clear to my current team.
Does using generics work?
public <T extends BaseEntity> void updateEntity(T entity)
{
if (checkSmth())
updateCollectionA(entity);
else
updateCollectionB(entity);
}
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
Suppose I have a class hierarchy in Java:
interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };
and I have another class in the same package:
class SpecialItemProcessor {
public void add(Item item)
{
/* X */
}
}
where I want to do something different for each item type, but I don't want to define that action in the different Item classes (MusicBox, TypeWriter, SoccerBall).
One way to handle this is:
class SpecialItemProcessor {
public void add(Item item)
{
if (item instanceof MusicBox)
{
MusicBox musicbox = (MusicBox)item;
... do something ...
}
else if (item instanceof MusicBox)
{
TypeWriter typewriter = (TypeWriter)item;
... do something ...
}
else if (item instanceof SoccerBall)
{
SoccerBall soccerball = (SoccerBall)item;
... do something ...
}
else
{
... do something by default ...
}
}
}
This works but it seems really clunky. Is there a better way to do this, when I know of special cases? (obviously if Item contains a method doSomethingSpecial then I can just call that item's method without caring what type it is, but if I don't want that differentiation to occur within the item itself how do I deal with it?)
In Java you can do multiple dispatch with a visitor(-like) pattern. The Item implementations don't need to contain the processing logic, they just need an accept() type of method.
public interface Item {
/** stuff **/
void processMe(ItemProcessor processor);
}
public interface ItemProcessor {
void process(MusicBox box);
void process(SoccerBall ball);
//etc
}
public class MusicBox implements Item {
#Override
public void processMe(ItemProcessor processor) {
processor.process(this);
}
}
public class ItemAddingProcessor implements ItemProcessor {
public void add(Item item) {
item.processMe(this);
}
#Override
public void process(MusicBox box) {
//code for handling MusicBoxes
//what would have been inside if (item instanceof MusicBox) {}
}
//etc
}
I think I'm going to use the idea of inversion of control and the visitor pattern:
interface Item {
public void accept(Visitor visitor);
...
public interface Visitor {
public void visit(Item item);
}
}
class MusicBox implements Item {
public interface Visitor extends Item.Visitor {
public void visitMusicBox(MusicBox item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof MusicBox.Visitor)
{
((MusicBox.Visitor)visitor).visitMusicBox(this);
}
}
}
class TypeWriter implements Item {
public interface Visitor extends Item.Visitor {
public void visitTypeWriter(TypeWriter item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof TypeWriter.Visitor)
{
((TypeWriter.Visitor)visitor).visitTypeWriter(this);
}
}
}
class SoccerBall implements Item {
public interface Visitor extends Item.Visitorr {
public void visitSoccerBall(SoccerBall item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof SoccerBall.Visitor)
{
((SoccerBall.Visitor)visitor).visitSoccerBall(this);
}
}
}
and then do the following, which at least reduces the instanceof to one check per add() call:
class SpecialItemProcessor
implements
MusicBox.Visitor,
TypeWriter.Visitor,
SoccerBall.Visitor,
Item.Visitor
{
public void add(Item item)
{
item.accept(this);
}
#Override public void visitMusicBox(MusicBox item)
{
...
}
#Override public void visitTypeWriter(TypeWriter item)
{
...
}
#Override public void visitSoccerBall(SoccerBall item)
{
...
}
#Override public void visit(Item item)
{
/* not sure what if anything I should do here */
}
}
Why not define some callback function to Item interface?
public Interface Item {
void onCallBack();
}
Then in each class that implements Item, such as MusicBox, it should implement the callback function.
public class MusicBox {
#override
public void onCallBack() {
// business logic
...
...
}
}
Then you could create a dispatcher, which you name is "SpecialItemProcessor".
public SpecialItemProcessor {
private final Item _item;
public SpecialItemProcessor(Item item) {
_item = item;
}
public dispatch() {
_item.onCallBack()
}
}
And then, in the Client class which contains the SpecialItemProcessor could just call the method, like:
public void XXXX() {
....
SpecialItemProcessor specialItemProcessor = new SpecialItemProcessor(new MusicBox());
specialItemProcessor.dispatch();
....
}
Actually, in C++, this is Dynamic Binding. And this is why pure abstract class exists...
You could create a bridge pattern for Item, in which the other side were the associated processes to do when add() is called. You could also add a factory method to the mix.
class SpecialItemProcessor {
public void add(Item item)
{
Process p = Item.createCorrespondingProcessor( p );
p.doWhenAddin();
}
}
Hope this helps.