Java how to re-transmit child call method to parent? - java

I have a two clases :
public class FlowItem {
}
public abstract class Flow extends FlowItem {
protected LinkedList<FlowItem> items = new LinkedList<FlowItem>();
public abstract void show(FlowItem item);
}
I have next implementation structure :
public class AuthFlow extends Flow {
public AuthFlow() {
items.add(new PrivacyFlow());
items.add(new ExtendedPrivacyFlow());
items.add(new FinalFlowItem());
}
public void show(FlowItem item) {
// drawing logic
}
}
PrivacyFlow and ExtendedPrivacyFlow also extended from Flow. FinalFlowItem extended from FlowItem.
The question is : how to use single\parent implementation of show(...) method?
I want to keep drawing logic in one place.

You show method is abstract, meaning that each class inheriting from it needs to implement the method. I am assuming that you have information in your child classes relevant to rendering, and in this case you could move said information into the Flow class with relative ease. You can use a data encapsulation method similar to hold relevant information.

What you have to do is simply change the show method in the parent class to be final, that way you prevent overriding in your subclasses.
public final void show(FlowItem item){
//your code here
}

Related

Creating child class based on class content

I have a class structure like this:
LineTemplate (abstract)
/ \
LineOut (abstract) LineIn (final)
/ \
LineOutTransfers (final) LineOutSells (final)
Both LineOut and LineIn should read a line from a file, check its content against a database and run multiple queries.
LineOut, however, contains two slightly different variations, which depend on the contents of the line. Due to the fact that LineOutTransfers and LineOutSells perform different actions when their methods are called, I decided to inherit and treat them as subclasses.
I created a public static LineTemplate __init() method within LineTemplate to determine whether it is a LineOut or LineIn class and return the correct type based on external conditions, and I wanted to implement a similar method to determine the correct type of LineOut subclass.
Since the LineOut child depends on the line content, however, I'm stuck at this point. The class should read the line, then convert itself to the correct child and then perform the checks. But this is impossible as I cannot cast a parent class into a child, if it is not already of that type (polymorphism).
I also thought about reading all the line inside LineOut's __init() method, and then passing the variables as arguments to its child constructor, but since there are a bunch of variables to be read and since it is done differently inside LineIn, it seemed to me like a bad practice.
Any ideas? Thanks in advance.
Can you add a convertWithContext(SomeClassRepresentingContext ctx) method to LineOut that will return a new LineOut that will be the correct subclass of LineOut?
Another approach would be to use a Factory method and supply it the line content and the context. Something like
LineOutFactory.instance().constructLineOut(String line, SomeClassRepresentingContext ctx);
In Java you cannot change the type of a class once it is created you can only build a new class based on the content of the existing class and possibly external context.
Favor composition over inheritance, so instead of
abstract class LineOut {
public void consume(Line l) {
// ...
subclassConsume(l);
// ...
}
protected abstract void subclassConsume(Line l);
}
// and
class LineOutTransfers extends LineOut {
protected abstract void subclassConsume(Line l) { ... }
}
class LineOutSells extends LineOut {
protected abstract void subclassConsume(Line l) { ... }
}
you should do this
abstract class LineOut {
private TransferLineHandler transferHandler;
private SellsLineHandler sellsHandler;
public void consume(Line l) {
// ...
if (isTransfer(l)) {
transferHandler.consume(l);
} else {
sellsHandler.consume(l);
}
// ...
}
protected abstract void subclassConsume(Line l);
}
// with
class TransferLineHandler {
public consume(l) { // stuff from LineOutTransfers }
}
class SellsLineHandler {
public consume(l) { // stuff from LineOutSells }
}
This removes the "dynamic subclassing" issue altogether and makes the code more testable.
Maybe a factory method would be useful for this scenario: https://refactoring.guru/design-patterns/factory-method

How to implement a Java method, that will call another method, based on the name of the calling class?

We have a Java class, WebCenterGrid. This class is full of methods to do things in a grid such as finding a row, finding a cell value, sorting a column. We have several classes that use this class. The classes using it all refer to different grids, but the functionality is the same.
The only thing that differs is how to create the grid. Some classes do a search which populates the grid (search also refreshes). Some do an updateList() to update the grid, etc.
I would like to add a method to WebCenterGrid to refresh the grid. The problem is as I said each method has a different name.
I somehow want to pass into WebCenterGrid the name of a method to call to do the refresh. I have done some searches and found something about lambda which I did not really understand.
I haven't used C++ in a while but there was some way to pass a method into those methods. This class is in Java not C++, but is there some sort of understandable equivalent?
public class WebCenterGrid {
....
....
public void refresh(Method meth) {
meth();
}
}
Basically, there are two ways.
One is to use reflection, this means: relying on runtime type information, commonly derived from raw strings. Like saying: I have some object of class X, and I want to invoke the method named "doTheFoo()" on that object.
See here for all the glory details.
A slightly better way is to use the MethodHandle class, instead of the "raw" reflection Method class. See here for handles.
But then: reflection is happening at runtime. Your code compiles fine, but if you get any detail wrong, it blows up at runtime.
Thus I suggest looking into lambdas, based on Function, see here.
Instead of having a Method parameter, accept an Interface, and the implementation will define what will be called.
You can use lambdas here as well if you'll define your interface as Functional Interface.
Example:
public class Main {
public static void main(String[] args) {
act(new Run());
act(new Swim());
// Passing a body of the function you want to execute
act(() -> System.out.println("walking"));
}
public static void act(Action action) {
action.act();
}
}
#FunctionalInterface
interface Action {
void act();
}
class Run implements Action {
#Override
public void act() {
System.out.println("running");
}
}
class Swim implements Action {
#Override
public void act() {
System.out.println("swimming");
}
}
Output:
running
swimming
walking
If you have predefined refresh logic, you can create association resolver based on mapping which will help you to define proper service based on some conditions.
public class Main {
static Map<ActionType, Action> actionResolver = new HashMap<>();
// Static init is just for brevity sake
static {
actionResolver.put(ActionType.RUN, new Run());
actionResolver.put(ActionType.WALK, new Walk());
actionResolver.put(ActionType.SWIM, new Swim());
}
public static void main(String[] args) {
act(ActionType.RUN);
act(ActionType.WALK);
act(ActionType.SWIM);
}
public static void act(ActionType actionType) {
Action action = actionResolver.get(actionType);
if (action == null)
throw new IllegalArgumentException("ActionType was not registered");
action.act();
}
}
enum ActionType {
RUN,
SWIM,
WALK
}
Output is the same as above.
Well, since we can't see any of your code, I'll suggest the following solution, that's based on my personal assumption about how your code works.
Please keep in mind that this method is not so scale-able and pretty inefficient if you have 100 different ways of creating grids.
However, if you have (e.g. 3) types of such ways for example, you can use constants!
See below:
public class WebCenterGrid {
//Declare constants with meaningful names for grid creation (add more as you like)
public static final int DEEP_COPY=1, SEARCH=2, REBUILD=3;
public void makeDeepCopy(){
//implementation goes here..
}
public void searchAndPopulate(){
//implementation goes here..
}
public void rebuildGrid(){
//implementation goes here..
}
public void refresh(int operation) {
switch(operation) {
//based on 'operation', call appropriate method!
case DEEP_COPY: this.makeDeepCopy(); break;
case SEARCH: this.searchAndPopulate(); break;
case REBUILD: this.rebuildGrid(); break;
//you can have a default operation for any parameter that is not
//in the list of our defined constants(i.e. the number 143)
default: simpleRefresh(); break;
}
}
}
So what makes the above solution work?
Basically, when you call refresh(int operation) from one of your other classes, you need to pass an int as a parameter. That integer is one of the constants defined at the very top of the class. According to which constant was passed, the switch case will determine which method to call.
EXAMPLE (Let's say that AwesomeGridCreator is a class that when it calls refresh(), in order to update a grid, it has to do a search and then populate the grid (like you mention in your question).
We name an integer (for simplicity) SEARCH_POPULATE and we give it ANY value we want. For example 286.
We can then use that constant from any other class, because we don't care what its value is (in this case 286, but the functionality it provides when calling refresh().
public class WebCenterGrid {
/*some code here*/
public static final int SEARCH_POPULATE = 286; //integer value doesn't matter
public void refresh(int operation) {
switch(operation) {
case SEARCH_POPULATE: this.searchAndPopulate(); break;
}
/*...some other code here, we don't care..*/
}
Then, at the 'calling' class:
public class AwesomeGridCreator{
//some code here
WebCenterGrid wcg = new WebCenterGrid();
//The parameter that we pass below (2), will make the refresh() method call
//the method that we defined in our switch cases ('searchAndPopulate()').
wcg.refresh(wcg.SEARCH_POPULATE);
}

how to inject interface to class in java?

i have my DTO class that is :
public class EmailResponse {
// Make public to avoid getters and setters
public Email email;
public RequestData reqData;
public EmailResponse() {
super();
}
}
and i want to implement to it this interface:
public interface IAssertionErrorDo {
public void onErrorDo();
}
but i want to do it during execution, i don't want to touch "EmailResponse" because it would not be ok to make it implements that interface due they don't belong to the same layer, i mean, EmailResponse would belong to service layer and IAssertionError would belong to test layer. I am using TestNG.
Do you know how i could do this? Regards
EDIT:
My implementation is this:
EmailResponse emailResponse = emailService.getUserEmail(userId);
And the reason i want to do this "injection" is because i have
public class LoggingAssert
extends Assertion {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingAssert.class);
private IAssertionErrorDo dataE;
#Override
public void onAssertFailure(IAssert a, AssertionError ex) {
LOGGER.info("[ERROR] " + a.getMessage());
if (this.dataE != null) {
this.dataE.onErrorDo();
}
}
public LoggingAssert setOnErrorDo(IAssertionErrorDo object) {
this.object = object;
return this;
}
}
loggingAssert.setOnErrorDo(emailResponse).assertNotNull(emailResponse.getEmail().getId(),
"Checking created email doesn't exists");
So i want to if assert fails execute method onErrorDo() from emailResponse
You could do
public class MyEmailResponse extends EmailResponse implements IAssertionErrorDo {
...
}
implementation calls in interfaces, you can call more than 1 interface if you want by adding commas to separate them..
to call interface methods you simply just use the method's name.
like this:
public class MyEmailResponse implements IAssertionErrorDo
{
public void onErrorDo() {//define it's behavior}
}
if you extend a class you use:
super.MyMethod()
to call the a method inside the extended class, but if you already have an extended class and want a method from another class you have to create an object for that class first then call it, thus:
MyClass mc = new MyClass();
if it is in a different package then
myPackage.MyClass mc = new myPackage.MyClass();
then you call your method from that class using the object you created, which is in this case mc.. so:
mc.MyMethod();
if you want it to return a variable then you will need to add a return statement in that method with the variable you want it to return.
interfaces are usually used for global an changing environments (dynamics), for example if you developed a program and it needs a driver to connect to databases then you will make an interface and send it to the database developers, and each one will fill the codes in that interface and send it back... this guarantees consistency.
when you implement an interface you have to define every method inside it (even if you leave it empty) and you cannot change the interface's methods names nor add... it is used in other areas as well, i don't think you need to use it in your case.

Trouble implementing strategy and composite pattern to give varying behaviour in a game

I'm running into real trouble trying to complete a practical that requires using strategy and composite pattern. I am trying to create a collection of vehicles which can have different behavior depending on the surface they are on. However, these vehicles can have more than one behaviour on a surface - for example, they could have snow drive and rain drive at the same time, if the weather conditions are set to snow and rain.
I have a class called AbstractVehicle, which has two concrete subclasses, Car and Boat.
I then have an interface called IBehaviour. Implementing this interface is two abstract classes called LandBehaviour and WaterBehaviour (which are the top tier of the composite pattern). Each of these have a collection of subclasses. Focussing solely on LandBehaviour, its subclasses are SnowBehaviour, StandardBehaviour and a few others including LandAssembly.
The idea was that I would put the code for the upper-tier of composite in LandBehaviour. Then, each of the concrete subclasses would have empty implementations of the add, remove and list parts of composite, with the LandAssembly class containing the code needed to actually combine various behaviours together.
This is intended to produce the result that, for example, a car could have both StandardBehaviour and SnowBehaviour at the same time.
Rather than posting large amounts of code (and there is a lot of it), I was hoping for some feedback on the basic structure I am trying to implement. I am getting a few errors right now such as null pointer exceptions and rather than spent a long time trying to fix them, I wanted to get an idea on whether the layout of the project was right to begin with.
Edit: Adding code - which generates a null pointer exception
This is my AbstractVehicle class:
public AbstractVehicle (IBehaviour behaviourIn) {
behaviour = behaviourIn;
}
public void setBehaviour(IBehaviour ib) {
behaviour = ib;
}
public IBehaviour getBehaviour() {
return behaviour;
}
public void move() {
behaviour.ensureCorrectBehaviour();
}
The car subclass:
public Car () {
super(new StandardBehaviour());
}
The IBehaviour interface:
public interface IBehaviour {
public void ensureCorrectBehaviour();
}
The LandBehaviour abstract class:
public void ensureCorrectBehaviour() {
}
public ILandBehaviour () {
}
private ILandBehaviour landBehaviour;
public ILandBehaviour (ILandBehaviour landBehaviour) {
this.landBehaviour = landBehaviour;
}
public ILandBehaviour getBehaviour() {
return landBehaviour;
}
public abstract void addBehaviour(ILandBehaviour behaviour);
public abstract void removeBehaviour(ILandBehaviour behaviour);
public abstract ILandBehaviour[] getBehaviours();
An example of a concrete behaviour subclass (RacingBehaviour):
public RacingBehaviour(ILandBehaviour landBehaviour) {
super(landBehaviour);
}
public RacingBehaviour() {}
#Override
public void ensureCorrectBehaviour() {
System.out.println("Vehicle is racing.");
}
public void addBehaviour(ILandBehaviour behaviour) {}
public void removeBehaviour(ILandBehaviour behaviour) {}
public ILandBehaviour[] getBehaviours() {
return null;
}
And finally the LandAssembly class:
public class LandAssembly extends ILandBehaviour {
private List<ILandBehaviour> behaviours;
public LandAssembly(ILandBehaviour landBehaviour) {
super(landBehaviour);
behaviours = new ArrayList<ILandBehaviour>();
}
public LandAssembly() {}
public void addBehaviour(ILandBehaviour behaviour) {
behaviours.add(behaviour);
}
public void removeBehaviour(ILandBehaviour behaviour) {
behaviours.remove(behaviour);
}
public ILandBehaviour[] getBehaviours() {
return behaviours.toArray(new ILandBehaviour[behaviours.size()]);
}
}
I am using this runner:
AbstractVehicle aCar = new Car(120);
aCar.move();
ILandBehaviour snow = new SnowBehaviour();
ILandBehaviour racing = new RacingBehaviour();
ILandBehaviour as = new LandAssembly();
as.addBehaviour(snow);
as.addBehaviour(racing);
Before I implemented the composite, everything was fine. I was able to use the client to create a new car, call its move() method, then change its behaviour, call move() again and see the difference. I'm aware however that I'm now kinda leaving the ensureCorrectBehaviour() method in my implementation of the composite pattern, which is obviously wrong. I'm also aware that after doing this, the "new" part of the Car constructor didn't work - I had to add an empty constructor each behaviour.
I can see glaring problems in the code I've created, I just don't quite see how to fix them.
If you are concerned about the design patterns, a class diagram would be extremely useful. You have many features, and you group those features into higher levels of abstractions (such as snow/land/water/etc.) But your vehicle only takes in one behavior. Does a vehicle need to be able to have multiple features? (Surely it does as you mention).
You might consider having concretely-defined strategies in your class, where each implementation of the strategy can vary.
public abstract class Bird
{
protected BirdCallStrategy callStrat;
protected FlyStrategy flyStrat;
}
public class Duck
{
public Duck()
{
callStrat = new QuackStrategy();
flyStrategy = new FlySouthForWinterStrategy(TimeOfYear);
}
}
public class Chicken
{
public Chicken()
{
callStrat = new CluckStrategy();
flyStrat = new NoFlyStrategy();
}
}
This works well if you have distinct abstractions for your strategies. In this case Flying and BirdCalling have nothing to do with each other, but they are allowed to vary by implementation at runtime (Quacking, chirping or flying, not flying, etc.)
If however, you want to create varying instances on the fly without subtyping, you might want to look into the Decorator pattern. The decorator pattern allows you to apply any combination of "features" to an instance at run-time.
So you might end up with an object that is instantiated such as:
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator(new SimpleWindow()));

Separating Service Logic from Data

I have been looking over a couple of classes I have in an android project, and I realized that I have been mixing logic with data. Having realized how bad this can be to the readability and the test-ability of my project, I decided to do some refactoring in order to abstract away all services logic to separate services modules. However, since I have been relying on Java's polymorphism, I got lost and need some guidance.
Suppose I have this "to-be-changed" layout for a super data class, and two sub-classes:
public class DataItem {
/* some variables */
public saveToDB(/* Some Arguments */) {
/* do some stuff */
}
public render() {
/* render the class */
}
}
public class ChildDataItemA extends DataItem {
#Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemA */
}
#Override
public render() {
/* render logic for ChildDataItemA */
}
}
public class ChildDataItemB extends DataItem {
#Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemB */
}
#Override
public render() {
/* render logic for ChildDataItemB */
}
}
Now, I thought about moving the saveToDB() and render() methods to a service class. However, sometimes I need to be able to call these method into instance of compiled type DataItem without knowing its runtime type. For instance, I might want to make the following call:
List<DataItem> dataList;
for (DataItem item: dataList) {
item.saveToDB();
item.render();
}
Additionally, I thought of doing the following:
public class ChildDataItemB extends DataItem {
#Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemB */
Service.saveToDBB();
}
#Override
public render() {
/* render logic for ChildDataItemB */
Service.renderB();
}
}
Where I still keep 'dummy' methods in each subclass that would call an appropriate service method. However, I do not think that this really achieves the separation I want since data classes will still know about services (bad!).
Any ideas on how to solve this?
Edit: Note that render() and saveToDB() are just generic examples of what these methods can be, so the problem is not really about choosing an ORM or SQL related techniques.
Visitor pattern to the rescue. Create a visitor interface and have each service implement this interface:
public interface DataItemVisitor {
// one method for each subtype you want to handle
void process(ChildDataItemA item);
void process(ChildDataItemB item);
}
public class PersistenceService implements DataItemVisitor { ... }
public class RenderService implements DataItemVisitor { ... }
Then have each DataItem implement an accept method:
public abstract class DataItem {
public abstract void accept(DataItemVisitor visitor);
}
public class ChildDataItemA extends DataItem {
#Override
public void accept(DataItemVisitor visitor) {
visitor.process(this);
}
}
public class ChildDataItemB extends DataItem {
#Override
public void accept(DataItemVisitor visitor) {
visitor.process(this);
}
}
Note that all accept implementations look the same but this refers to the correct type in each subclass. Now you can add new services without having to change the DataItem classes.
So you want to do:
List<DataItem> dataList;
for (DataItem item: dataList) {
service.saveToDB(item);
service.render(item);
}
For this you need to setup a system for your service to know more details from your DataItem subclass.
ORM's and serializers usually solve this via a metadata system, e.g. by finding an xml file with name matching the subclass, containing the properties to save or serialize.
ChildDataItemA.xml
<metaData>
<column name="..." property="..."/>
</metaData>
You could get the same result via reflection and annotations.
In your case, an application of the Bridge pattern could also work:
class DataItem {
public describeTo(MetaData metaData){
...
}
}
class Service {
public void saveToDB(DataItem item) {
MetaData metaData = new MetaData();
item.describeTo(metaData);
...
}
}
Your metadata could be decoupled from saving or rendering, so you can the same for both.
I would clean the "data" classes of render and saveToDB methods.
Instead, I would create a hierarchy of wrappers for DataItem (it does not have to mimic exactly the DataItem hierarchy). These wrappers will be the ones implementing those methods.
Additionally, I suggest that (if you can), you move to some ORM (Object-Relational Mapping) like Hibernate or JPA to get rid of the saveToDB method.
First of all the DataItem class should be clean, only with getters and setter and no logic at all, just like a POJO. moreover- your DataItem maybe should be abstract.
Now- for the logic, like others suggested I would use some ORM framework for the saveToDB part, but you said that it's not helping you cause it's android project and you have other methods like this as well.
So what I would do is to create an interface- IDataItemDAO, with the following logic:
public interface IDataItemDAO<T extends DataItem > {
public void saveToDB(T data, /* Some Arguments */);
... other methods that you need ...
}
I would create an abstract DAO for the DataItem and put it all the similar code of all DataItems:
public abstract class ChildDataItemADAO impelemets IDataItemDAO<DataItem> {
#Override
public void saveToDB(DataItem data, /* Some Arguments */); {
...
}
}
than I would create a DAO for each DataItem class that you have:
public class ChildDataItemADAO extends DataItemDAO impelemets IDataItemDAO<ChildDataItemA> {
#Override
public void saveToDB(ChildDataItemA data, /* Some Arguments */); {
super(data, ...);
//other specific saving
}
}
the other part is how to use the correct DAO for the correct instance, for this I would create a class that will bring me the correct DAO for the given instance, it is a very simple method if an if-else statements (or you can do it dynamically with a map of class and the DAO)
public DataItemDAO getDao(DataItem item) {
if (item instanceof ChildDataItemA) {
//save the instance ofcourse
return new ChildDataItemADAO();
}
}
so you should use it like this:
List<DataItem> dataList;
for (DataItem item: dataList) {
factory.getDao(item).saveToDB(item);
}
If you want separate logic from data you may try the following approach
Create your data class DataItem,ChildDataItemA, ChildDataItemB without the method operating on the data
Create an interface for some operations on you data class something like
public interface OperationGroup1OnDataItem {
public void saveToDB(DataItem dataItem/*plus other params*/) {
}
public void render(DataItem dataItem/*plus other params*/) {
}
......
}
Create a factory for implementing an OperationGroup provider
public class OperationFactoryProvider {
public static OperationGroup1OnDataItem getOperationGroup1For(Class class) {
....
}
}
Use it in you code:
List<DataItem> dataList;
for (DataItem item: dataList) {
OperationGroup1OnDataItem provider OperationFactoryProvider.getOperationGroup1For(item.class);
provider.saveToDB(item);
provider.render(item);
}
You can choose to implement the factory with a simple static map where you put the class (or the class fullName) as the key and an Object implementing the interface as the value; something like
Map<String,OperationGroup1OnDataItem> factoryMap= new HashMap<String,OperationGroup1OnDataItem>();
factoryMap.put(DataItem.class.getName(),new SomeClassThatImplementsOperationGroup1OnDataItemForDataItem());
factoryMap.put(ChildDataItemA.class.getName(),new SomeClassThatImplementsOperationGroup1OnDataItemForChildDataItemA());
The implementation of the getOperationGroup1For is:
return factoryMap.get(item.getClass().getName());
This is one example of separating logic from data, if you want separate logic from data your logic methods must be extracted from your data class; otherwise there is no separation. So I think every solution must start from removing logic methods.

Categories

Resources