Java Inheritance - Building a BaseView for the MVP pattern - java

We are trying to implement the MVP pattern. Because it requires quite a lot of code just to have a functioning view, we try to use inheritance as much as possible. As I am pretty new to Java, I don't know exactly if I'm doing it right:
So, I started with a very simple Interface which all the views will implement (and the `getName`` method will be used for breadcrumb Feature):
public interface IView {
public String getName();
}
On top of that, I built a BaseView which will be used for most views:
public interface IBaseView extends IView {
public void addListener(IBaseViewListener l);
interface IBaseViewListener {
void viewEntered(Long id);
}
}
And the implementation
public class BaseView extends CustomComponent implements View, IBaseView{
private String name = "";
private List<IBaseViewListener> listeners;
public BaseView(String name) {
this.name = name;
listeners = new ArrayList<IBaseViewListener>();
buildLayout();
}
#Override
public void addListener(IBaseViewListener l) {
listeners.add(l);
}
protected void buildLayout() {
this.setId("base_view");
// initialize layout....
}
#Override
public void enter(ViewChangeEvent event) {
for (IBaseViewListener l : listeners) {
l.viewEntered(id);
}
}
#Override
public String getName() {
return name;
}
}
And last we have a ScaffoldingView which will be used for some views (mainly for mocking):
public interface IScaffoldingView extends IBaseView{
public void showTable(AbstractComponent t);
interface IScaffoldingViewListener extends IBaseViewListener {
void itemSelected(DataBaseObject selectedObject);
}
}
And the implementation:
public class ScaffoldingView extends BaseView implements IScaffoldingView{
private AbstractComponent table = null;
public ScaffoldingView(String name) {
super(name);
}
#Override
protected void buildLayout() {
// here is a lot more code...
}
public void showTable(AbstractComponent t) {
// here is a lot of code...
}
}
First of all:
- Does that approach make any sense? especially the access modifiers. I'm totally weak when it Comes to polymorphism :(
I am very unsure about the handling of the EventListeners. For example: In the constructor of the BaseView, I am implementing the addListener function.
Now, in the ScaffoldingView's, there will be a specialized IScaffoldingViewListener. Will the super class (BaseView) addListener() method be able to handle These IScaffoldingViewListeners?
edit: Sorry, I forgot to mention that View and CustomComponent are some classes of a 3rd Party Framework (Vaadin) which we use and which offer the enter Event in which we call the eventListeners (Presenter).

First, declaring an interface inside another interface is not quite clean, obscures the code quite a bit.
Second, about BaseView which extends CustomComponent, and implements IView and IBaseView, first a small detail, if it implements IBaseView, you do not need to implement IView, as IBaseView already extends IView, but the bigger issue i see is:
If you have a somewhere in some class, a method with an IBaseView as a parameter, but inside that function you expect to be able to use the overrided methods from CustomComponent, you won't be able to, you'll only have the methods declared on IBaseView.
If you wanted to use the CustomComponent methods, you'd had to do a cast inside that method, but that is not clean and a source of bugs, because if in the future, you add more classes that implement IBaseView but do not extend CustomComponent, that function will throw exceptions complaining about casting.
Also, about the ScaffoldingView, if you are going to use it only for mocking purposes in tests and you are extending the IBaseView behaviour, with more methods, if you test a method that has an IBaseView as parameter, you have the same exact situation as before, the method you are testing will not be aware of the IScaffoldingView declared methods, and then it won't use them, and your tests can't be trusted.
P.D.: if you are interested in learning about abstractions and inheritance design, i'd recomend you to check S.O.L.I.D. principles, there's a lot of literature in the web about those.
Edit: Response to your comment
First you need to ask yourself without thinking about internal details or implementations or testing or anything else, what are the behaviour my Views have? are they all behaving the same way? do i have different types of views or not really? Once you answer these questions and got an idea of what is going on, you'll have what it will need to design the interface hierarchy, and thats what is going to be exposed to the rest of the system.
You can (optionally) have abstract classes that derive from those interfaces, where you can provide some initialization, defaults, but, do not go further in offering more functionality than the interface offers, you can have some extra methods, but only for internal use.
And then you can derive the actual implementation of the views from the interface or the intermediate abstract classes if you have defined any.
Just think of this as a black box, in which the only thing you can see are the input and output interfaces, everything else that is going inside that box, the rest of the system doesn't and shouldn't need to know about.
Can't really give you specific solution because i'm not aware of the needs of your application.

Related

What is the point of a “sealed interface” in Java?

Sealed classes and sealed interfaces were a preview feature in Java 15, with a second preview in Java 16, and now proposed delivery in Java 17.
They have provided classic examples like Shape -> Circle, Rectangle, etc.
I understand sealed classes: the switch statement example provided makes sense to me. But, sealed interfaces are a mystery to me. Any class implementing an interface is forced to provide definitions for them. Interfaces don't compromise the integrity of the implementation because the interface is stateless on its own. Doesn't matter whether I wanted to limit implementation to a few selected classes.
Could you tell me the proper use case of sealed interfaces in Java 15+?
Basically to give a sealed hierarchy when there is no concrete state to share across the different members. That's the major difference between implementing an interface and extending a class - interfaces don't have fields or constructors of their own.
But in a way, that isn't the important question. The real issue is why you would want a sealed hierarchy to begin with. Once that is established it should be clearer where sealed interfaces fit in.
(apologies in advance for the contrived-ness of examples and the long winded-ness)
1. To use subclassing without "designing for subclassing".
Lets say you have a class like this, and it is in a library you already published.
public final class Airport {
private List<String> peopleBooked;
public Airport() {
this.peopleBooked = new ArrayList<>();
}
public void bookPerson(String name) {
this.peopleBooked.add(name);
}
public void bookPeople(String... names) {
for (String name : names) {
this.bookPerson(name);
}
}
public int peopleBooked() {
return this.peopleBooked.size();
}
}
Now, you want to add a new version to your library that will print out the names of people booked as they are booked. There are several possible paths to do this.
If you were designing from scratch, you could reasonably replace the Airport class with an Airport interface and design the PrintingAirport to compose with a BasicAirport like so.
public interface Airport {
void bookPerson(String name);
void bookPeople(String... names);
int peopleBooked();
}
public final class BasicAirport implements Airport {
private final List<String> peopleBooked;
public Airport() {
this.peopleBooked = new ArrayList<>();
}
#Override
public void bookPerson(String name) {
this.peopleBooked.add(name);
}
#Override
public void bookPeople(String... names) {
for (String name : names) {
this.bookPerson(name);
}
}
#Override
public int peopleBooked() {
return this.peopleBooked.size();
}
}
public final class PrintingAirport implements Airport {
private final Airport delegateTo;
public PrintingAirport(Airport delegateTo) {
this.delegateTo = delegateTo;
}
#Override
public void bookPerson(String name) {
System.out.println(name);
this.delegateTo.bookPerson(name);
}
#Override
public void bookPeople(String... names) {
for (String name : names) {
System.out.println(name);
}
this.delegateTo.bookPeople(names);
}
#Override
public int peopleBooked() {
return this.peopleBooked.size();
}
}
This isn't doable in our hypothetical though because the Airport class already exists. There are going to be calls to new Airport() and methods that expect something of type Airport specifically that can't be kept in a backwards compatible way unless we use inheritance.
So to do that pre-java 15 you would remove the final from your class and write the subclass.
public class Airport {
private List<String> peopleBooked;
public Airport() {
this.peopleBooked = new ArrayList<>();
}
public void bookPerson(String name) {
this.peopleBooked.add(name);
}
public void bookPeople(String... names) {
for (String name : names) {
this.bookPerson(name);
}
}
public int peopleBooked() {
return this.peopleBooked.size();
}
}
public final class PrintingAirport extends Airport {
#Override
public void bookPerson(String name) {
System.out.println(name);
super.bookPerson(name);
}
}
At which point we run into one of the most basic issues with inheritance - there are tons of ways to "break encapsulation". Because the bookPeople method in Airport happens to call this.bookPerson internally, our PrintingAirport class works as designed, because its new bookPerson method will end up being called once for every person.
But if the Airport class were changed to this,
public class Airport {
private List<String> peopleBooked;
public Airport() {
this.peopleBooked = new ArrayList<>();
}
public void bookPerson(String name) {
this.peopleBooked.add(name);
}
public void bookPeople(String... names) {
for (String name : names) {
this.peopleBooked.add(name);
}
}
public int peopleBooked() {
return this.peopleBooked.size();
}
}
then the PrintingAirport subclass won't behave correctly unless it also overrided bookPeople. Make the reverse change and it won't behave correctly unless it didn't override bookPeople.
This isn't the end of the world or anything, its just something that needs to be considered and documented - "how do you extend this class and what are you allowed to override", but when you have a public class open to extension anyone can extend it.
If you skip documenting how to subclass or don't document enough its easy to end up in a situation where code you don't control that uses your library or module can depend on a small detail of a superclass that you are now stuck with.
Sealed classes let you side step this by opening your superclass up to extension only for the classes you want to.
public sealed class Airport permits PrintingAirport {
// ...
}
And now you don't need to document anything to outside consumers, just yourself.
So how do interfaces fit in to this? Well, lets say you did think ahead and you have the system where you are adding features via composition.
public interface Airport {
// ...
}
public final class BasicAirport implements Airport {
// ...
}
public final class PrintingAirport implements Airport {
// ...
}
You might not be sure that you don't want to use inheritance later to save some duplication between the classes, but because your Airport interface is public you would need to make some intermediate abstract class or something similar.
You can be defensive and say "you know what, until I have a better idea of where I want this API to go I am going to be the only one able to make implementations of the interface".
public sealed interface Airport permits BasicAirport, PrintingAirport {
// ...
}
public final class BasicAirport implements Airport {
// ...
}
public final class PrintingAirport implements Airport {
// ...
}
2. To represent data "cases" that have different shapes.
Lets say you send a request to a web service and it is going to return one of two things in JSON.
{
"color": "red",
"scaryness": 10,
"boldness": 5
}
{
"color": "blue",
"favorite_god": "Poseidon"
}
Somewhat contrived, sure, but you can easily imagine a "type" field or similar that distinguishes what other fields will be present.
Because this is Java, we are going to want to map the raw untyped JSON representation into classes. Lets play out this situation.
One way is to have one class that contains all the possible fields and just have some be null depending.
public enum SillyColor {
RED, BLUE
}
public final class SillyResponse {
private final SillyColor color;
private final Integer scaryness;
private final Integer boldness;
private final String favoriteGod;
private SillyResponse(
SillyColor color,
Integer scaryness,
Integer boldness,
String favoriteGod
) {
this.color = color;
this.scaryness = scaryness;
this.boldness = boldness;
this.favoriteGod = favoriteGod;
}
public static SillyResponse red(int scaryness, int boldness) {
return new SillyResponse(SillyColor.RED, scaryness, boldness, null);
}
public static SillyResponse blue(String favoriteGod) {
return new SillyResponse(SillyColor.BLUE, null, null, favoriteGod);
}
// accessors, toString, equals, hashCode
}
While this technically works in that it does contain all the data, there isn't all that much gained in terms of type-level safety. Any code that gets a SillyResponse needs to know to check the color itself before accessing any other properties of the object and it needs to know which ones are safe to get.
We can at least make the color an enum instead of a string so that code shouldn't need to handle any other colors, but its still far less than ideal. It gets even worse the more complicated or more numerous the different cases become.
What we ideally want to do is have some common supertype to all the cases that you can switch on.
Because its no longer going to be needed to switch on, the color property won't be strictly necessary but depending on personal taste you can keep that as something accessible on the interface.
public interface SillyResponse {
SillyColor color();
}
Now the two subclasses will have different sets of methods, and code that gets either one can use instanceof to figure out which they have.
public final class Red implements SillyResponse {
private final int scaryness;
private final int boldness;
#Override
public SillyColor color() {
return SillyColor.RED;
}
// constructor, accessors, toString, equals, hashCode
}
public final class Blue implements SillyResponse {
private final String favoriteGod;
#Override
public SillyColor color() {
return SillyColor.BLUE;
}
// constructor, accessors, toString, equals, hashCode
}
The issue is that, because SillyResponse is a public interface, anyone can implement it and Red and Blue aren't necessarily the only subclasses that can exist.
if (resp instanceof Red) {
// ... access things only on red ...
}
else if (resp instanceof Blue) {
// ... access things only on blue ...
}
else {
throw new RuntimeException("oh no");
}
Which means this "oh no" case can always happen.
An aside: Before java 15 to remedy this people used the "type safe visitor" pattern. I recommend not learning that for your sanity, but if you are curious you can look at code ANTLR generates - its all a large hierarchy of differently "shaped" data structures.
Sealed classes let you say "hey, these are the only cases that matter."
public sealed interface SillyResponse permits Red, Blue {
SillyColor color();
}
And even if the cases share zero methods, the interface can function just as well as a "marker type", and still give you a type to write when you expect one of the cases.
public sealed interface SillyResponse permits Red, Blue {
}
At which point you might start to see the resemblance to enums.
public enum Color { Red, Blue }
enums say "these two instances are the only two possibilities." They can have some methods and fields to them.
public enum Color {
Red("red"),
Blue("blue");
private final String name;
private Color(String name) {
this.name = name;
}
public String name() {
return this.name;
}
}
But all instances need to have the same methods and the same fields and those values need to be constants. In a sealed hierarchy you get the same "these are the only two cases" guarantee, but the different cases can have non-constant data and different data from each other - if that makes sense.
The whole pattern of "sealed interface + 2 or more record classes" is fairly close to what is intended by constructs like rust's enums.
This also applies equally to general objects that have different "shapes" of behaviors, but they don't get their own bullet point.
3. To force an invariant
There are some invariants, like immutability, that are impossible to guarantee if you allow subclasses.
// All apples should be immutable!
public interface Apple {
String color();
}
public class GrannySmith implements Apple {
public String color; // granny, no!
public String color() {
return this.color;
}
}
And those invariants might be relied upon later on in the code, like when giving an object to another thread or similar. Making the hierarchy sealed means you can document and guarantee stronger invariants than if you allowed arbitrary subclassing.
To cap off
Sealed interfaces more or less serve the same purpose as sealed classes, you just only use concrete inheritance when you want to share implementation between classes that goes beyond what something like default methods can give.
Although interfaces have no state themselves, they have access to state, eg via getters, and may have code that does something with that state via default methods.
Therefore the reasoning supporting sealed for classes may also be applied to interfaces.
Suppose you write an authentication library, containing an interface for password encoding, ie char[] encryptPassword(char[] pw). Your library provides a couple of implementations the user can choose from.
You don't want him to be able to pass in his own implementation that might be insecure.
Could you tell me the proper use case of sealed interfaces in Java
15+?
I wrote some experimental code and a supporting blog to illustrate how sealed interfaces could be used to implement an ImmutableCollection interface hierarchy for Java that provides contractual, structural and verifiable immutability. I think this could be a practical use case for sealed interfaces.
The example includes four sealed interfaces: ImmutableCollection, ImmutableSet, ImmutableList and ImmutableBag. ImmutableCollection is extended by ImmutableList/Set/Bag. Each of the leaf interfaces permits two final concrete implementations. This blog describes the design goal of restricting the interfaces so developers cannot implement "Immutable" interfaces and provide implementations that are mutable.
Note: I am a committer for Eclipse Collections.
Interfaces are not always entirely defined by their API alone. Take, for example ProtocolFamily. This interface would be easy to implement, considering its methods, but the result would not be useful regarding the intended semantics, as all methods accepting ProtocolFamily as input would just throw UnsupportedOperationException, in the best case.
This is a typical example for an interface that would be sealed if that feature existed in earlier versions; the interface is intended to abstract the implementations exported by a library, but not to have implementations outside that library.
The newer type ConstantDesc mentions that intention even explicitly:
Non-platform classes should not implement ConstantDesc directly. Instead, they should extend DynamicConstantDesc…
API Note:
In the future, if the Java language permits, ConstantDesc may become a sealed interface, which would prohibit subclassing except by explicitly permitted types.
Regarding possible use cases, there is no difference between a sealed abstract class and a sealed interface, but the sealed interface still allows implementors extending different classes (within the limits set by the author). Or being implemented by enum types.
In short, sometimes, interfaces are used to have the least coupling between a library and its clients, without the intention of having client-side implementations of it.
Since Java introduced records in version 14, one use case for sealed interfaces will certainly be to create sealed records. This is not possible with sealed classes, because records cannot extend a class (much like enums).
Before java 15 developers used to think in a way that code reusability is the goal. But it's not true to all extents, in some cases we want wide accessibility but not extensibility for better security and also codebase management.
This feature is about enabling more fine-grained inheritance control in Java. Sealing allows classes and interfaces to define their permitted subtypes.
The sealed interface allows us to enable it to reason clearly all the classes that can implement it.

What is the way to create API Library in Java

I am creating an API of a list of checking functions. There is an object passed in as an argument to be checked.
The object is like below:
public class People{
private String name;
private String address;
private int age;
private String job;
public getter() ...
public setter() ...
}
I create a class including a list of checking function to make sure the provided information is valid or not. For example:
public class checkingFunctions {
public static boolean checkName(People ppl){
perform the name checking function;
}
public static boolean checkAge(People ppl){
perform the age checking function;
}
}
I know the above way works as an API so that other people can call checkingFunctions.checkName(ppl). But is this the correct way to build the API that will be exposed to others as jar file ? I was thinking to create an interface of checkingFunctions like below:
public interface ICheckingFunctions {
boolean checkName(People);
boolean checkAge(People);
}
And let the checkingFunctions class to implement it, like
public class checkingFunctions implements ICheckingFunctions {
}
BUt it won't compile because the checkName and checkAge can not be declared as static if it is overriding a superclass method.
Or should I just use the interface and let it implement the interface, but remove the static from all checking method. So, if others want to use my API, they just instantiate the interface, and use instance.checkName() to call method ? is that a good way ?
I am wondering whether there there exists an industry standard or design pattern standard to create such an interface so that others can call it.
Thanks a lot.
How to design such an API very much depends on how your API is intended to be used.
If it for example turns out, that your People class is best implemented as a final class, and you want to make sure, that it is always checked in the same consistent way, then providing a number of public static check... methods is certainly a reasonable way to go.
If on the other hand you do not know in advance how your People class should be checked, then I'd consider providing an ICheckingFunctions interface that declares the necessary check... methods. But if you go this route, you will perhaps also need to provide a way for the user to change the actually used implementation of ICheckingFunctions.
You should also consider, that while using an interface is certainly much more flexible and extensible, it is also more work to maintain and it could also provide a possible security risk - e.g. if you allow users to change the used ICheckingFunction, then you no longer have control of how your People class is checked.
One possible way to implement such an API using an interface is allowing users to register/unregister the used ICheckingFunction in your class. A very naive implementation could look like this:
public final class CheckingFunctions {
private static ICheckingFunctions checkFunction;
public static void registerCheckFunction(ICheckingFunctions checkFunction) {
CheckingFunctions.checkFunction = checkFunction;
}
public static boolean checkName(People ppl){
return checkFunction.checkName(ppl);
}
public static boolean checkAge(People ppl){
return checkFunction.checkAge(ppl);
}
}
This is of course just a minimal example. In an actual API you would have to decide quite a lot of additional details. For example:
Is there only ever a single ICheckingFunctions instance available? If there may be more registered ICheckingFunctions - how do you choose which of these functions are used?
Who is allowed to register/unregister an ICheckingFunctions instance?
May the ICheckingFunctions be called from different threads?
etc.
You must also consider in which environment your API is going to be used. If you for example want to support usage of your API in an OSGI environment, then you could e.g. supply your ICheckingFunctions as an OSGI service.
Last but not least I would consider the following: May your users subclass the People class? If yes, then it would perhaps be a good idea to make the ICheckingFunctions interface generic, and allow registrations of implementations for different classes. Here again a very naive example of this approach:
public final class CheckingFunctions {
public interface ICheckingFunctions<T extends People> {
boolean checkName(T p);
boolean checkAge(T p);
}
private static Map<Class<?>,ICheckingFunctions<?>> checkFunctions = new ConcurrentHashMap<>();
public static <T extends People> void registerCheckFunction(ICheckingFunctions<T> checkFunction, Class<T> c) {
checkFunctions.put(c, checkFunction);
}
private static <T extends People> ICheckingFunctions<T> getRegisteredCheckFunction(Class<T> c){
ICheckingFunctions<T> checkFunction = (ICheckingFunctions<T>) checkFunctions.get(c);
if (checkFunction == null) {
// provide some reasonable default?
throw new IllegalStateException();
}
return checkFunction;
}
public static <T extends People> boolean checkName(T ppl, Class<T> c){
return getRegisteredCheckFunction(c).checkName(ppl);
}
public static <T extends People> boolean checkAge(T ppl, Class<T> c){
return getRegisteredCheckFunction(c).checkAge(ppl);
}
}

Interfaces in java

Code 1:
public class User1 implements MyInterface
{
#Override
public void doCalculation() { }
}
public class User2 implements MyInterface
{
#Override
public void doCalculation() { }
}
interface MyInterface
{
public void doCalculation();
}
Code 2:
public class User1
{
public void doCalculation() { }
}
public class User2
{
public void doCalculation() { }
}
Here in my Code 1 I have MyInterface which has an empty method doCalculation().
That doCalculation() is used by user1 and user2 by implementing MyInterface.
Where as in my Code 2 I have two different classes with defined doCalculation() method.
In both the cases code1 and code2 I myself have to write the implementation. My method doCalculation() is just an empty method.
So what is the use of MyInterface here?
It only provides me the method name or skeleton (is that the only advantage of interface)?
Or else would I save any memory while using MyInterface?
Is that, it only provides the empty method for an class which implements it, then why not I define it by myself as I have done in my code2.
More than that is there any more advantage on using an interface.
Interfaces are used a lot because they are basically a blueprint of what your class should be able to do.
For example, if you are writing a video game with characters, you can have an interface that holds all the methods that a character should have.
For example
public interface Character {
public void doAction();
}
And you have 2 characters, for example an ally and an enemy.
public class Ally implements Character {
public void doAction() {
System.out.println("Defend");
}
}
public class Enemy implements Character {
public void doAction() {
System.out.println("Attack");
}
}
As you can see, both classes implement the interface, but they have different actions.
Now you can create a character which implements your interface and have it perform its action. Depending on if it's an enemy or an ally, it'll perform a different action.
public Character ally = new Ally();
public Character enemy = new Enemy();
And in your main program, you can create a method that accepts any object that implements your interface and have it perform it's action without knowing what kind of character it is.
void characterDoAction(Character char) {
char.doAction();
}
If you would give ally to this method, the output would be:
Defend
If you would give enemy to this method, the output would be:
Attack
I hope this was a good enough example to help you understand the benefits of using interfaces.
There are a lot of advantages of interface driven programming.
What does "program to interfaces, not implementations" mean?
Basically you are defining a contract in an interface and all the classes which implement the interface have to abide by the contract.
Answers to your queries:
1.It only provides me the method name or skeleton (is that the only advantage of interface)?
--> Its not just about providing the method name but also defining what the class implementing the interface can do.
2.Or else would I save any memory while using MyInterface?
--> Nothing to do with the memory
Is that, it only provides the empty method for an class which implements it, then why not I define it by myself as I have done in my code2.
--> see the advantages of interface driven programming.
4.More than that is there any more advantage on using an interface.
--> Plenty,specially dependency injection , mocking , unit testing etc.
A very good explanation can be found here when-best-to-use-an-interface-in-java. It really depends on what you're building and how much scalability, code duplications, etc you want/don't want to have.
Many classes use interfaces to perform some function, relying on other programmers to implement that interface respecting the contract that an interface govern. Such classes are, for example, KeyListeners, MouseListeners, Runnable, etc.
For example: JVM knows what to do with a Thread, how to start it, stop it, manipulate it, but it does not know what your Thread should do, so you have to implement the Runnable interface.
Interfaces offer you a level of abstraction which can be leveraged in other classes. For example, if you have an interface called GemetricFigure, in a class that prints girth of a GeometricFigure you could iterate over a list of all GeometricFigures like:
public class Canvas {
private List<GeometricFigure> figures;
public void print() {
for (GeometricFigure figure : figure) {
System.out.println(figure.getGirth());
}
}
}
And if the GeometricFigure has only that method:
public interface GeometricFigure {
public Double getGirth();
}
You wouldn't care how Square or Circle implement that interface. Otherwise, if there were no interface, you could not have a list of GeometricFigures in Canvas, but a list for every figure type.
With the interface approach you can do the following:
List<MyInterface> list = new ArrayList<MyInterface();
list.add(new User1());
list.add(new User2());
for(MyInterface myInterface : list) {
myInterface.doClaculation()
}
This does not work with the second approach. Interfaces are for the code that use your classes - not for your classes themselves.
You can use interfaces in many cases. Also the situation you describes: You needn't to know, which implementation you have.
For example you have anywhere in your code a method, that returns the current singed in user even you don't know if it is User1 or User2 implementation, however that both of them can calculate something by method doCalculation. I add a really dummy example of that situation:
public void dummyExampleCalculation() {
getCurrentUser().doCalculation();
}
public MyInterface getCurrentUser() {
if(...) {
return new User1();
} else {
return new User2();
}
}
That is what Object Oriented Programming is all about.Interfaces are used to perform polymorphism. You said, you can implementations in code2 for both the classes, what if in future there is user3 who needs to doCalculation. You can just implement that interface and write your calculation in your own form.
When you want to provide a basic functionality to all your users abstract classes comes into picture where in you can declare an abstract method do calculation and provide implementation of that basic functionalities which then each user will extend and can doCalculation in their own way.
Interface is like a contract that your implementing class should satisfy. Usually, you will write an interface and make all your other class's implement it with their own implementation.
Example:
interface IExporter {
public void export();
}
public class PDFExport implements IExporter {
public void export(){
//code for PDF Exporting
}
}
public class XLSExport implements IExporter {
public void export(){
//code for XLS Exporting
}
}
public class DOCExport implements IExporter {
public void export(){
//code for DOC Exporting
}
}
Interface in Java is used to impose an implementation rule on classes. That means you can declare the signature of functions in interfaces and then implement these function in various classes by exactly following the function signature.
You can see a clear and realistic example on the following webpage
http://www.csnotes32.com/2014/10/interface-in-java.html

OOP: How to write families of classes to work together?

Yesterday I asked this question, and the solution posted by #JB Nizet worked perfectly. However, that answer, as well as a few other answers/comments got me thinking in a different direction altogether.
Essentially, I have the following classes:
Load
HttpLoad extends Load
Target
HttpTarget extends Target
Controller
The Controller's job is to Target::fire() a Load, and doesn't care which Target is firing which Load:
// Inside Controller.java
Target target = getTarget();
Load load = getLoad();
target.fire(load);
However, I might some day write a FtpLoad extends Load, and I don't want to be able to fire a FtpLoad at an HttpTarget. So the essence of the above-referenced question was how do I do this, to which, the answer was generics.
However, as the answerer pointed out, this solution is a violation of the Liksov Substitution Principle. Other answerer/commenters seemed to indicate that what I was doing wasn't necessarily good OOP practices.
So now I'm asking: how do I expose an API so that the Controller can be Load- and Target-agnostic, but still enforce that the proper Load subclass is fired on the proper Target type, all without violating Liskov Substitution?
And, if this is impossible to do (without violating Liskov), then what is the normal approach to a problem like this? Thanks in advance!
If HttpTarget.fire allows any Load as parameter, it is its job to check if it can fire this Load. So either the Controller calls fire blindly, and fire checks if the given target can fire that kind of Load (with instanceof), or you include a function canFire in every target that implements this check and is called by the Controller.
The typing problem here is that HttpTarget is not a Liskov subtype of Target, because semantically it is attempting to strengthen the preconditions of Target#fire(Load) to require the Load be HttpLoad.
This can be trivially repaired by declaring Target#fire(Load) throws IncompatibleLoadException and having a default implementation that always throws, forcing Controller to deal with the fact that a mismatched Load can be passed in.
The easy way is to do some checking in your code to make sure the classes match up. You can use the instanceof keyword to check if it's the correct class.
Best is to implement abstract class or an interface and use instanceof as mentioned before.
With an abstract class:
public abstract class TargetLoad {
public abstract void fire(TargetLoad i);
}
public class Load extends TargetLoad {
#Override
public void fire(TargetLoad i) {
if (i instanceof Target) return;
// do fire stuff
}
}
public class Target extends TargetLoad {
#Override
public void fire(TargetLoad i) {
if (i instanceof Load) return;
// do fire stuff
}
}
with an interface:
public interface TargetLoad {
public void fire(TargetLoad i);
}
public class Load implements TargetLoad {
#Override
public void fire(TargetLoad i) {
if (i instanceof Target) return;
// do fire stuff
}
}
public class Target implements TargetLoad {
#Override
public void fire(TargetLoad i) {
if (i instanceof Load) return;
// do fire stuff
}
}
In your Controller you refer to your objects as TargetLoad
TargetLoad target = getTarget();
TargetLoad load = getLoad();
target.fire(load);
load.fire(target);
load.fire(load); //this will do nothing
target.fire(target); //this will do nothing
I strongly disagree with the slew of answers recommending to use instanceof. Well-written OOP code very rarely needs to use instanceof, and using instanceof will generally make your code awkward and difficult to maintain. As a general rule, avoid instanceof if at all possible.
The previous question you referred to provided a solution using generics. I'm not sure you left the generics code out of your question here; go back to your generic code. Now, add the following method to your driver.
private <L extends Load> void runSuite(TestSuite<L> suite) {
Target<L> target = testSuite.getTarget();
L load = testSuite.getLoad();
target.fire(load);
}

Visitor pattern implementation in java- How does this look?

Alrite, I am gonna jump straight to the code:
public interface Visitor {
public void visitInventory();
public void visitMaxCount();
public void visitCountry();
public void visitSomethingElse();
public void complete();
//the idea of this visitor is that when a validator would visit it, it would validate data
//when a persister visits it, it would persist data, etc, etc.
// not sure if I making sense here...
}
public interface Visitable {
public void accept(Visitor visitor);
}
here is a base implementation:
public class StoreValidator implements Visitor {
private List <ValidationError> storeValidationErrors = new ArrayList<ValidationError>();
public void addError(ValidationError error) {
storeValidationErrors.add(error);
}
public List<ValidationError> getErrors() {
return storeValidationErrors;
}
public void visitInventory() {
// do nothing
}
public void visitMaxCount() {
//do nothing
}
//... etc.. all empty implementations
}
You will see why I did an empty implementation here... I would write a validator now.. which extends StoreValidator
public XYZValidator extends StoreValidator {
#Override
public void visitInventory(Visitable visitable) {
// do something with visitable .. cast it to expected type
// invoke a DAO, obtain results from DB
// if errors found, do addError(new ValidationError()); with msg.
}
#Override
public void visitMaxCount(Visitable visitable) {
//do something with visitable..
}
// I wouldn't implement the rest coz they wouldn't make sense
// in XYZValidator.. so they are defined as empty in StoreValidator.
}
Now here is what a visitable would look like:
public Store implements Visitable {
public void accept(Visitor visitor) {
visitor.visitInventory();
visitor.visitMaxCount();
}
}
I could have code that does something like this on a list of Store objects:
List<Store> stores; //assume this has a list of stores.
StoreValidator validator = new XYZValidator(); //or I would get it from a validatorfactory
for(Store store: stores) {
store.accept(validator); // so even if you send a wrong validator, you are good.
}
Similarly you would have ABCValidator which would provide implementation for other methods (visitCountry / visitSomethinElse) and it would extend from StoreValidator. I would have another type of Object (not Store) defining accept method.
I do see a problem here...
Say, I need a FileValidator which is different from StoreValidator, I would expect it to have none of these business related validations such as visitInventory(), etc. But, by having a single interface Visitor, I would endup declaring all kinds of methods in Visitor interface. Is that correct? Is this how you do it?
I don't know if I got the pattern wrong, or if I am making any sense.
Please share your thoughts.
Some time ago I wrote something similar for my master thesis. This code is slightly
type safe than yours:
interface Visitable<T extends Visitor> {
void acceptVisitor(T visitor);
}
interface Visitor {
/**
* Called before any other visiting method.
*/
void startVisit();
/**
* Called at the end of the visit.
*/
void endVisit();
}
example:
interface ConstantPoolVisitor extends Visitor {
void visitUTF8(int index, String utf8);
void visitClass(int index, int utf8Index);
// ==cut==
}
class ConstantPool implements Visitable<ConstantPoolVisitor> {
#Override
public void acceptVisitor(ConstantPoolVisitor visitor) {
visitor.startVisit();
for (ConstanPoolEntry entry : entries) {
entry.acceptVisitor(visitor);
}
visitor.endVisit();
}
so yes, I think that this definitely a good and flexible design if, and only if, your data changes slower than your behaviour. In my example the data is Java bytecode, that is fixed (defined by the JVM specification). When "behaviour dominates" (I want to dump, compile, transform, refactor, etc my bytecode) the Visitor pattern let you to change/add/remove behaviour without touching your data classes. Just add another implementation of Visitor.
For the sake of simplicity assume that I must add another visit method to my Visitor interface: I would end in breaking all my code.
As alternative I would consider the strategy pattern for this scenario. Strategy + decorator is a good design for validation.
There is a problem with your code as given. The interface you give has methods such as
public void visitInventory();
but you then implement it in XYZValidator as
public void visitInventory(Visitable visitable)
The visitor pattern is a way to implement multiple dispatch in languages that do not do that automatically (such as Java). One of the requirements is that you have a group of related classes (i.e. a set of subclasses with a single super class). You don't have that here, so the visitor pattern is not appropriate. The task you are trying to do, however, is fine, it is just not the Visitor pattern.
In Java, you should think of the Visitor pattern if you have code like
public void count(Item item) {
if (item instanceof SimpleItem) {
// do something
} else if (item instanceof ComplexItem {
// do something else
} else ...
}
particulary if the subclasses of Item are relatively fixed.
I'm using a visitor pattern in a different way.. I have a specific Visitor interface for a type of object and this interface declares only one method - for visiting that object.. like this:
public interface TreeNodeVisitor {
void visit(TreeNode node);
}
the object TreeNode can accept TreeNodeVisitors which means he just calls it's visit method for the node and/or it's children..
The concrete implementation of the visitor implements the visit method and says what the visitor will do.. for example ContryVisitor, InventoryVisitor, etc
This approach should avoid your probleam..
You probably don't want to map a pattern directly to a single interface that everything following that pattern implements. Patterns are NOT Interfaces, they are general plans for implementing a solution.
In your example you would create a StoreVisitor interface and a FileVisitor interface for the different business objects that wish to use the Visitor pattern in the appropriate circumstances.
It might be that different Visitor implementations share common activities - so you could have a superinterface that defines those common functions. You could then code Visitable interfaces to use either the specific Visitable interface or it's superclass as appropriate.
For example, the FileVisitor and SQLTableVisitor interfaces might be a subclass of a DataStoreVisitor interface. Then:
VisitableStore accepts a StoreVisitor,
VisitableFile accepts a Filevisitor, or
VisitableDataStore accepts a DataStoreVistor (which might be an implementation of either FileVisitor or SQLTableVisitor).
forgive the random examples, I hope this makes sense.

Categories

Resources