What is the usage of the IVisitable interface in Visitor Pattern? - java

Im really trying to understand the importance of this interface, but beside helping us to write more quickly, the methods in the concrete classes (by only implementing the methods) I just can't find the need to use it.
The definition is this
an abstraction which declares the accept operation. This is the
entry point which enables an object to be "visited" by the visitor
object.
Each object from a collection should implement this abstraction in
order to be able to be visited
."
Its clear, but still you can manualy write those accept methods in every single class(which is lot of unnecessary work I agree) but still beside that you can get a class to be visitable, without the IVisitable interface...
//IVisitable.java
package Visitor;
/**
*
* #author dragan
*/
public interface IVisitable {
public void accept (Visitor v);
}
// Bgirl.java
public class Bgirl implements IVisitable{
int _br_godina;
public Bgirl(int g) {
br_godina = g;
}
public int getBr_godina() {
return _br_godina;
}
public void accept (Visitor v){
v.visit(this);
}
}
// Main.java
package Visitor;
/**
*
* #author dragan
*/
public class Main {
public static void main(String[] args) {
Bgirl terra = new Bgirl(5);
System.out.println(terra.getBr_godina());
VisitorImplement v = new VisitorImplement();
}
}
// VisitorImplement.java
package Visitor;
/**
*
* #author dragan
*/
public class VisitorImplement implements Visitor{
#Override
public void visit(Bgirl prva) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
prva._br_godina = 3;
}
// #Override
// public void visit(Bboy prvi) {
// // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
// System.out.println("BBOY VISIT");
//
// }
//
}

Look into your main() method: you can just directly call terra._br_godina = 3 and thus no need to use any visitor.
A visitor is useful when you don't know the concrete type of your terra and even don't know which method should be called to fullfil your wish. All you have is just an abstract type or interface e.g. Girl (or IVisitable). So, to demonstrate the usefulness of Visitor Pattern, your main() method should be like this:
public static void main(String[] args) {
IVisitable terra = new Bgirl(5);
// Want to set _br_godina of terra to 3 but do not and cannot know
// which method should be called
// Let's create a visitor and let him visit her,
// he knows how to set _br_godina of her to 3
VisitorImplement v = new VisitorImplement();
terra.accept(v); // luckily, every girl accepts the "accept()"
}

Related

Using java 8 default methods to achieve multiple inheritance

I would like to use JAVA 8 default methods as a means for implementing multiple inheritance. So I have a repetitive code represented by the addValue() method that I need to move from the implementations to the interface.
interface IX {
ArrayList list = new ArrayList();
default void addValue(Object o) {
this.list.add(o);
}
}
class A implements IX {
//no addValue implementation here
}
class B implements IX {
//no addValue implementation here
}
class Main {
public static void main(String [] args) {
A a = new A();
B b = new B();
a.addValue(this);
b.addValue(this);
}
}
I would like to know
if this is a valid usage of default methods
If the a.addValue(this) syntax is correct
If two different list objects will be created
Java does not allow you to have multiple inheritance of state, only behavior.
If you want to share the declaration of an instance field you would need to place it in an abstract class.
if this is a valid usage of default methods
I use default methods heavily, but since I value immutability, i rarely place methods that mutate state in an interface.
Since (currently) all interface methods are public, if I need to inherit methods that mutate state I will place them (as protected) in abstract classes.
If the a.addValue(this) syntax is correct
No. Since you are in the static main method there is no "this".
What do you want to add to this list?
If two different list objects will be created
In your example only one (global) list will be created.
It is also important to note that ArrayList is not thread safe and in general should not be used in a global field, CopyOnWriteArrayList (or similar) should be used instead.
The example below:
/**
* The Interface IX.
*/
public static interface IX {
/**
* Gets the list.
*
* #return the list
*/
List<Object> getList();
/**
* Adds the value.
*
* #param o the o
*/
default void addValue(Object o) {
this.getList()
.add(o);
}
}
/**
* The Class AbstractIX.
*/
public static abstract class AbstractIx implements IX {
/** The list. */
protected List<Object> list = new ArrayList<>();
#Override
public List<Object> getList() {
return this.list;
}
}
/**
* The Class A.
*/
public static class A extends AbstractIx {
// no addValue implementation here
}
/**
* The Class B.
*/
public static class B extends AbstractIx {
// no addValue implementation here
}
/**
* The Class Main.
*/
public static class Main {
/**
* The main method.
*
* #param args the arguments
*/
public static void main(String[] args) {
A a = new A();
B b = new B();
a.addValue(1);
a.addValue(2);
b.addValue(1);
System.out.println("List a size should be 2: " + a.getList()
.size());
System.out.println("List b size should be 1: " + b.getList()
.size());
}
}
If two different list objects will be created
A single object is created
If the a.addValue(this) syntax is correct
No, try to add some string. The size of the list comes out to be 2
you can use sysout statements to figure such things out. :)
Thanks,
Amar

Calling a method from an argument

I apologize if this is a duplicate question, I want to be able to call a method that is defined in the constructors argument list from a different method.
What follows is code that won't compile, but its really the only way I can think of describing my question. I also hope my explanation makes sense.
Main.java
....
Class0 instance = new Class0(arg0, arg1, arg2, new Class1(){
//do something
//do something else
//do more stuff
}
)
library.go(instance);
....
The point I want to get across here is that a new instance of Class0 is initialized with an anonymous function.
The instance is then passed to an instance of Library.
Class0.java
....
public Class1 action = null;
public Class0(int arg0, int arg1, int arg2, Class1 class) {
setArg0(arg0);
setArg1(arg1);
setArg2(arg2);
setAction(class);
}
public setAction(Class1 class) {
action = class;
}
public action() {
class;
}
....
Class0 is constructed from the constructor method and sets the function to the action field, it remains uncalled but stored for later.
action() calls the function passed into the constructor.
Library.java
....
public void go(Class0 class0) {
class0.action();
}
....
For the most part Library.java is out of my control, it is an conduit for a third-party library.
go calls the stored function of the instance object, declared in main, through its action method.
Does anything like this even remotely exist in java? Is there any other way to achieve the same thing?
Edit: This assumes java 7.0 or earlier. It works in java 8, but lambda expressions are most likely preferred.
It appears that you want to implement a callback interface.
create an interface with a method.
use the interface as a parameter to a method (constructor in your case).
the interface is just a reference to some object, so call the method.
Here is some code:
Kapow.java
public interface Kapow
{
void callbackMethod();
}
KapowImpl.java
public class KapowImpl implements Kapow
{
#Override
public void callbackMethod()
{
System.out.println("Kapow!");
}
}
Main.java
public final class Main
{
private static void callIt(final Kapow theCallback)
{
theCallback.callbackMethod();
}
public static void main(String[] args)
{
Kapow kapowObject = new KapowImpl();
callIt(kapowObject);
}
}
A good example of a "method type declaration" is java.awt.event.ActionListener (see below). In Java 8 or higher you can use use lambda expressions to simplify the usage, but the principle is still the same - an interface with one method declaration stands for the logical method.
/*
* Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.awt.event;
import java.util.EventListener;
/**
* The listener interface for receiving action events.
* The class that is interested in processing an action event
* implements this interface, and the object created with that
* class is registered with a component, using the component's
* <code>addActionListener</code> method. When the action event
* occurs, that object's <code>actionPerformed</code> method is
* invoked.
*
* #see ActionEvent
* #see Tutorial: Java 1.1 Event Model
*
* #author Carl Quinn
* #since 1.1
*/
public interface ActionListener extends EventListener {
/**
* Invoked when an action occurs.
*/
public void actionPerformed(ActionEvent e);
}
Here's a quick example on how to use that pattern:
public static void main(String[] args) {
ActionListener squeezeAction = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Ouch!");
}
};
performAction(squeezeAction);
}
public static void performAction(ActionListener method) {
method.actionPerformed(null); //invoke method
}
With lambda expressions (requires JRE 1.8 or higher) this can be simplified to:
public static void main(String[] args) {
ActionListener squeezeAction = e -> System.out.println("Ouch!");
performAction(squeezeAction);
}
public static void performAction(ActionListener method) {
method.actionPerformed(null); //invoke method
}
Or as a reference to an existing method:
public class Test {
public static void main(String[] args) {
ActionListener squeezeAction = Test::squeeze;
performAction(squeezeAction);
}
public static void sqeeze(ActionEvent e) {
System.out.println("Ouch!");
}
public static void performAction(ActionListener method) {
method.actionPerformed(null); //invoke method
}
}

Java - Calling a public method (not public void)

I have this code but I am unsure how to call the public create() method with the public static void main(String[] args) method in a different class. I have searched the net but found nothing on just public methods just public void methods.
Here is the code
mainclass.java:
public class Mainclass {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
create createObject = new create();
createObject.create();
System.out.println("dammit");
}
}
create.java
public class Create extends javax.swing.JPanel {
public create() {
initComponents();
setDate();
}
}
That is actually a constructor. You call it with new.
create panel = new create();
Having a class with a lowercase name is highly unorthodox.
That is a constructor, not a normal method. You can see that it has the same name as the class it's in. It's called here:
create createObject = new create();
BTW, calling a class create makes me a sad panda.
public create() {
initComponents();
setDate();
}
create() Is a constructor so when you say Create createObject = new Create(); the without parametrized constructor will automatically call.
read here for constructor
and please follow the java naming conventions class name always start with caps letter.
Starting with something Off-topic but you might want to read about the Java Naming Convention to understand how to name your classes/methods/variables in Java.
Constructors as we know have declarations that look like method declarations—except that they use the name of the class and have no return type. So you can have something like this:
public class create extends javax.swing.JPanel {
/** Normal Constructor */
public create() {
}
/**
* Normal method for initialization.
*/
public void create(){
initComponents();
setDate();
}
}
I tend to prefer having a specific method to handle object initialization (or setup, if you may) for my classes i.e. kept all business logic separate from object creation mechanism. So, if I were you, I would've renamed my method as public void doCreate() and initialized everything over there. (This is subjective and a matter of preference). With this case, my MainClass would have changed something like this:
public class MainClass {
/**
* #param args
*/
public static void main(String[] args) {
create createObject = new create();
createObject.doCreate();
System.out.println("dammit");
}
}

Why do we start Visitor by calling Acceptor.accept(), and not Visitor.visit()?

In Wikipedia sample and in GoF book, usage of Visitor pattern is started by calling accept method on some acceptor. But why is it this way? Why can't we start calling visit method with desired acceptor as an argument? We can still make visitor behavior depend on 2 types -- of visitor and of acceptor (double dispatch) -- and we can eliminate redundant call (as it seems to me).
Here's sample code to illustrate this:
public interface Visitor {
void visit(AcceptorA acceptor);
void visit(AcceptorB acceptor);
}
//
// Visitor which sings
//
class SingingVisitor implements Visitor {
public void visit(AcceptorA acceptor) {
System.out.println("sing A");
}
public void visit(AcceptorB acceptor) {
System.out.println("sing B");
}
}
//
// Visitor which talks
//
class TalkingVisitor implements Visitor {
public void visit(AcceptorA acceptor) {
System.out.println("talk A");
}
public void visit(AcceptorB acceptor) {
System.out.println("talk B");
}
}
//
// Acceptor subclasses
//
class AcceptorA implements BaseAcceptor {
}
class AcceptorB implements BaseAcceptor {
}
//
// Launcher class
//
class VisitorMain {
public static void main(String[] args) {
Visitor v = new TalkingVisitor();
AcceptorA a = new AcceptorA();
AcceptorB b = new AcceptorB();
v.visit(a);
v.visit(b);
v = new SingingVisitor();
v.visit(a);
v.visit(b);
}
}
Consider:
class House implements HouseAcceptor {
HouseAcceptor kitchen;
HouseAcceptor livingRoom;
void accept(HouseVisitor visitor) {
visitor.visit(this);
kitchen.accept(visitor);
livingRoom.accept(visitor);
}
}
class Kitchen implements HouseAcceptor {
void accept(HouseVisitor visitor) {
visitor.visit(this);
}
}
class LivingRoom implements HouseAcceptor {
void accept(HouseVisitor visitor) {
visitor.visit(this);
}
}
class SpeakingHouseVisitor implements HouseVisitor {
void visit(HouseAcceptor acceptor) {
System.out.println("Inside a HouseAcceptor");
}
void visit(House acceptor) {
System.out.println("Inside a House");
}
void visit(Kitchen acceptor) {
System.out.println("Inside a Kitchen");
}
void visit(LivingRoom acceptor) {
System.out.println("Inside a LivingRoom");
}
}
...
HouseAcceptor acceptor = new House();
HouseVisitor visitor = new SpeakingHouseVisitor();
...
// Doing it your way
visitor.visit(acceptor);
// Output: Inside a HouseAcceptor
// Doing it the right way
acceptor.accept(visitor);
// Output:
// Inside a House
// Inside a Kitchen
// Inside a LivingRoom
Note that if you do it your way, the runtime type of your acceptor will not make a difference: the static type will be used. By doing double dispatch you ensure that both runtime types are used.
Using your version, the following will not compile:
List<BaseAcceptor> list = ...
for(BaseAcceptor ba: list)
vi.visit(ba)
The java compiler cannot determine (statically) what ba will be, so it cannot decide at compile time which visit method to call. You would need to write an additional method:
public void visit(BaseAcceptor ba){
if(ba instanceof AcceptorA)
visit((AcceptorA)ba);
else if(ba instanceof AcceptorB)
visit((AcceptorB)ba);
}
This is not necessary using the visitor pattern.
Because Visitors have no knowledge of how to navigate the private internal fields of a composed Object.
If you called Visitor.visit(something) then it would have to figure out if that something had private fields which needed transversal. To do that, you need that something to accept your Visitor. Once you decide that navigation must be in the visited objects (and not the Visitor), then you realize that you need a call back to the Visitor to tell it what the next element in the navigation path is. Typically that's the accept(...) method; however, if you attempted to make accept(...) just a wrapper to initiate navigation (by delegation to the parameter), then you need a second set of methods to tell the Visitor you're entering X now, your entering Y now.
By using the GOF approach, one can safely subclass an item being visited and modify the visiting path to include or skip additional fields. This would not impact the existing Visitors because their interface would not change. One wouldn't need to recompile subclasses of the Visitor either.
By using your suggested approach, when one added a new type into the hierarchy of to-be-visited items, one would then need to recompile all the visitors, even the visitors had no interest in the new type.
A good compromise would be:
public interface Visitable {
public void accept(Visitor v);
}
were all your "data hierarchy" implements Visitable, and your Visitor has a "convenience method" like so
public abstract class Visitor {
public void initiate(Visitable v) {
v.accept(this);
}
public abstract void accept(...);
public abstract void accept(...);
public abstract void accept(...);
}
But it's up to you if having an interface is preferable to such a base class. To me I'd favor the more loosely coupled interface, but opinions differ.
you have no double dispatch. accept usually takes an abstract visitor as an argument.

Restrict Constructor to Sibling use - Java

This might not be possible but I am trying to create a constructor that only classes that share a super class can access, almost a reverse logic of the protected modifier. I assume there is no modifier to accomplish this directly, but knowing what I am trying to accomplish, any suggestions?
public Account extends SomeEntity {
//default public
public Account() {
}
// I am wanting this constructor to be only available to sibling classes.
// (those that share the same super class )
<modifier> Account(Element accountElement) {
}
}
public Accounts extends SomeEntity {
private List<Account> accountList;
//default public
public Accounts() {
Account newAcct = new Account(element);
//looped loading up Generic list of Account
this.accountList.add(newAcct);
}
I am working with RESTful web services and building the Objects out of XML responses, the problem is if I GET a listing of accounts, to build that into a list of Account Objects I would have to query the web service for each individual account even though I already have the information, and that seems entirely inefficient.
BUT
I don't want to give a general user, of the API I'm building, to be able to instantiate an Account Object this way. (With an Element)
There is no language construct like this. Package (=default) access is the only Java mechanism in town, as of 1.6.
I'm sure you could do nasty things with the stack, but I wouldn't recommend them.
I'd take a look at the factory pattern. You can probably play games with the access modifiers of the factory method(s) to get something close to what you want. You might also be able to play with reflection inside the factory method to get something closer to what you want than what package access gets you.
Sorry but I still don't get the point of this design. If a method is added to a class, its implementation will probably use private data to this class only, and therefore no guarantee can be made to 'sibling' classes that this data is also available for them. In other words, if your wish was granted, how would you guarantee that constructor Account(Object arg0) implementation won't use private data to Account class? (and therefore invisible to Accounts class)
It seems to me like you desire your code to provide the same interface for a single account and a list of accounts - extending SomeEntity class. That can be accomplished more elegantly with a composite pattern.
http://en.wikipedia.org/wiki/Composite_pattern
if your intent however is to provide a custom constructor that only subclasses will use, why not declare the custom constructor in SomeEntity and making this class abstract?
also, remember you can do this:
public Account() {
this(new arg0());
}
Account(Object arg0) {
}
Not sure if this helps, though.
There is a way to emulate the C++'s friend feature, and thus achieve the result you want.
Warning: This is a contrived technique that should be used only if you have no other solution!
Since no modifier does what you want in this case, the trick is to move the access restriction to another place, where modifiers apply. To do that, add a key parameter to the constructor. That key is of a class that can only be instantiated by the allowed "sibling" classes, i.e. by the subclasses of a given class.
The restriction is thus moved to the common superclass, where restraining the creation of the key is possible with the usual modifiers.
Here is an example:
public class CommonSuperClass {
public static final class Key {
private Key() {}
}
// This is the only way to create a key, and it's protected
protected final Key createKey() {
return new Key();
}
}
public class Account {
// The restricted constructor can even be public
public Account(Key key) {
// Everybody can try with null, but we're not that stupid
// Of course any RuntimeException can be thrown instead
if (key == null) throw new UnsupportedOperationException();
}
}
public class AllowedSibling extends CommonSuperClass {
public void foo() {
// I'm allowed
new Account(this.createKey());
}
}
public class DeniedClass {
public void foo() {
// This doesn't compile
new Account(new Key());
// This will throw an exception
new Account(null);
}
}
This is a very strange requisite, and I think no access modifier can do what you want. Anyway, I recommend that you just make the constructors public and document them as "for internal use only".
If you really need to limit access you can use this wordy solution:
public class Base {
protected interface Factory {
Base getInstance(Element e);
}
private static Map<Class<?>, Factory> registry = new HashMap<Class<?>, Factory>();
protected static void register(Class<?> c, Factory f) { registry.put(c, f); }
protected static <T extends Base> T create(Class<T> c, Element e) {
return (T) registry.get(c).getInstance(e);
}
}
public class Derived1 extends Base {
protected Derived1(Element e) { }
private static class Derived1Factory implements Factory {
public Derived1 getInstance(Element e) {
return new Derived1(e);
}
}
static {
register(Derived1.class, new Derived1Factory());
}
}
public class Derived2 extends Base {
protected Derived2(Element e) { }
private static class Derived2Factory implements Factory {
public Derived2 getInstance(Element e) {
return new Derived2(e);
}
}
static {
register(Derived2.class, new Derived2Factory());
}
public void method() {
Element e = null;
...
// Put some element in e
...
// This is what you were trying to do
Derived1 d1 = create(Derived1.class, e);
}
}
public class SomeEntity
protected void init(Element accountElement) {}
public class Account extends SomeEntity
public Account()
....
protected void init(Element accountElement)
....
public class Accounts extends SomeEntity
Account newAcct = new Account();
newAcct.init(element);
Here's what I would try (I have not tested this method):
<modifier> Account(Object arg) {
if (!super.getClass().isAssignableFrom(this.getClass())) {
throw new AssertionError("This constructor is only available to super classes.");
} else {
// Continue...
}
}

Categories