What I mean is:
public class SomeBackingBean {
protected String someString;
public void setSomeString (String str) {
this.someString = str;
}
public String getSomeString {
return someString;
}
}
It was just a general case for a general answer.
Now second example:
public abstract class AbstractBean<T extends EntityInterface> {
protected T entity;
public void setEntity (T t) {
this.entity = t;
}
public void getEntity () {
return entity;
}
protected ReturnType calculateSomethingCommon () {
//use entity (knowing that it implements EntityInterface)
//to implement some common for all subclasses logic
}
}
public class ConcreteBean extends AbstractBean<ConcreteEntity> {
...
//and here we can write only specific for this bean methods
...
}
Is second example an example of bad practice too?
In general, protected variables violate object oriented principles. You're giving other objects direct access to member variables. By doing so, you form tighter coupling and it makes it harder to change the variable, since other objects are directly using it. It also means you can't do things like validate when it's set, add logging around getters/setters, etc.
If, for example, you have a PropertyChangeListener registered to properties for a bean, any registered listeners might not be notified if a protected property is changed directly by a sub-class.
Related
Suppose I have this:
public class A {
public String foo() { return "A"; }
}
public class B extends A {
public String foo() { return "B"; }
public String superFoo() { return super.foo(); }
}
public class C extends B {
public String foo() { return "C"; }
}
Here, new C().superFoo() returns "A".
Is there a way I can polymorphically make new C().superFoo() invoke B.foo() (and hence return "B") without the need to override superFoo() in C?
I tried with reflection (redefining B.superFoo() like this: return getClass().getSuperclass().getDeclaredMethod("foo").invoke(this)), hoping that with getDeclaredMethod I could reference the exact method implementation in superclass, but I get "C" in that case (hence, polymorphism is applied).
I was searching for a solution that doesn't require me to redeclare superFoo() whenever I add a new subclass to the hierarchy.
TL;DR
Going through the question and comments, it seems like the ask here is to incrementally build up on a behavior. Taking a different perspective, I would prefer Composition over Inheritance in this scenario.
You can use Decorator pattern and compose the instances together; which in turn gives you a reference to the parent's foo() implementation. One of the other benefits is that you can extend/change the behavior at runtime, which is not possible with a static inheritance design.
About Decorator Pattern
Decorator pattern can be used to attach additional responsibilities to an object either statically or dynamically.
Component - Interface for objects that can have responsibilities added to them dynamically.
ConcreteComponent - Defines an object to which additional responsibilities can be added.
Decorator - Maintains a reference to a Component object and defines an interface that conforms to Component's interface.
Concrete Decorators - Concrete Decorators extend the functionality of the component by adding state or adding behavior.
Sample Code
Let's take a Pizza baking process as an example.
Component interface - Defines the contract that a Pizza must be baked.
public interface Pizza {
void bake();
}
ConcreteComponent class - This is your implementation of the interface which can stand alone by itself. It should not extend the Decorator and it appears at the innermost position when the objects are composed together (see client code at the end)
public class VeggiePizza implements Pizza {
#Override
public void bake() {
System.out.println("I'm a Veggie Pizza in the making :)");
}
}
Decorator - Specifies a contract for extending the functionality of the ConcreteComponent.
public abstract class Topping implements Pizza {
private Pizza pizza;
public Topping(Pizza pizza) {
this.pizza = pizza;
}
#Override
public void bake() {
pizza.bake();
}
}
Concrete Decorator - These implementations add to the functionality of the ConcreteComponent by nesting their constructors together (one of the ways to compose!). The concrete decorator can appear anywhere while composing, except for the innermost position (see client code below).
Here we are defining two toppings - Mushroom and Jalapeno.
public class Mushroom extends Topping {
public Mushroom(Pizza pizza) {
super(pizza);
}
#Override
public void bake() {
addMushroom();
super.bake();
}
private void addMushroom() {
System.out.println("Adding mushrooms...");
}
}
public class Jalapeno extends Topping {
public Jalapeno(Pizza pizza) {
super(pizza);
}
#Override
public void bake() {
addJalapenos();
super.bake();
}
private void addJalapenos() {
System.out.println("Adding jalapenos...");
}
}
Client code - How do you compose the ConcreteDecorator and ConcreteComponenttogether?
public void bakePizza() {
Pizza pizza = new Mushroom(new Jalapeno(new VeggiePizza()));
pizza.bake();
}
Notice that we build upon the VeggiePizza by wrapping the objects around with additional behavior from Mushroom and Jalapeno. Here, the ConcreteComponent is the innermost VeggiePizza, while our ConcreteDecorators are Jalapeno and Mushroom.
Note: Constructor composition is only one of the ways to compose. You can compose object together via setters or use a Dependency Injection framework.
Output
Adding mushrooms...
Adding jalapenos...
I'm a Veggie Pizza in the making :)
Following will return B though I've omitted various safety features for the sake of brevity and used commons-lang because you don't want to have to do this stuff yourself! At a minimum, this code assumes every class defines foo() and the you never directly call a.superFoo()! :)
public String superFoo() {
return superXXX("foo");
}
private <T> T superXXX(String name, Object... args) {
Method overriddenMethod = MethodUtils.getAccessibleMethod(getClass(), name);
Iterator<Method> methods = MethodUtils.getOverrideHierarchy(overriddenMethod, EXCLUDE).iterator();
methods.next(); // this is C
Method parentMethod = methods.next(); // This is B;
try {
return (T)parentMethod.invoke(this, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
FYI. There may well be an AspectJ/Javassist/Bytebuddy style solution possible as well whereby you can reimplement the superFoo method on all children of A to be super.foo()
I have a situation where my application can be in exactly one of a several "modes". Since these are discrete values I'd like to model them using an enum type.
With each state my application needs to perform a slightly different functionality, which I'd like to model using the plug-in pattern. I've defined an interface and provided a few implementations.
I'd now like my enumeration to return the plug-in that is appropriate for it's state. I'd like to do the following:
public enum Mode {
ONE {
#Override
public MyType get() { return factory.getFirst(); }
},
TWO {
#Override
public MyType get() { return factory.getSecond(); }
};
#Autowired private MyTypeFactory factory;
public abstract MyType get();
// Other methods removed for clarity
}
However this isn't going to work. This is because I'm using spring injection to add the plug-in factory to the enum (enum constants are static and spring injected variables are instance variables so I'll get a compilation error)
I can't create the MyType instances directly from the enum because they will require dependency injection
How do I get around this?
This probably isn't the best solution (and I'd love to see something better suggested), but this is what I did in the end:
Modify the Factory so it reads:
public class MyTypeFactory {
private static MyTypeFactory me;
#PostConstruct
public void initialise() {
if (me == null) {
me = this;
}
}
public static MyTypeFactory getInstance() {
return me;
}
// The same code as before - getFirst(), getSecond() etc
}
So, a (singleton) spring managed bean that looks a bit like an old GOF singleton! The important difference is that there is a publicly accessible default (no argument) constructor
I can then modify my enum to read:
public enum Mode {
ONE {
#Override
public MyType get() { Factory.getInstance().getFirst(); }
},
TWO {
#Override
public MyType get() { Factory.getInstance().getSecond(); }
};
public abstract MyType get();
// Other methods removed for clarity
}
The enum can get access the factory via the static getInstance method when get() is called
I have an abstract class, called Base that handles a bunch of logic for handling some data I have. The API looks like this:
// Class has no abstract methods, but is uninstantiable
public abstract class Base {
private Param param;
protected Base() {}
protected void setParam(Param param) {
this.param = param
}
public void doThing() {
// Code here to do a common thing
}
public void doOtherThing() {
// Code here to do another common thing
}
protected void handle(Object... objects) {
// This code delegates work to a scripting language via the param
// It is not type safe and the array of objects needed will vary depending
// on the implementing class.
}
}
Of course, the weird thing here is the handle(Objects...) method. To show how it is used, look at one of the subclasses:
public class Person extends Base {
protected Person(Param param) {
super();
setParam(param);
}
public void handle(String name, int age) {
// Expose a type safe interface to the world
super.handle(name, age);
}
}
As you can see, the subclasses hide super.handle, which is protected, for certain arguments so that consumers of this class can have type safe interactions without passing around Arrays of objects. The problem is, I would like to create these from a factory that enforces having one instance of the subclass per param. Currently, this factory looks like this:
public class Factory {
Map<Param, Person> persons;
Map<Param, Other> others; // Other also extends Base
public Person getPerson(Param param) {
Person person = persons.get(param);
if (person == null) {
person = new Person(param);
persons.put(param, person);
}
return person;
}
public Other getOther(Param param) {
Other other = others.get(param);
if (other == null) {
other = new Other(param);
other.put(param, other);
}
return other;
}
}
Obviously, this sucks, but I can think of no better way to handle this case due the strange nature of interacting with a scripting language via the param, which relies on string construction to execute code. Does anyone have any guidance on how to clean up this design?
One could generalize the factory class, with some generics and reflection for instantiating at runtime a specific subclass type:
import java.util.HashMap;
import java.util.Map;
public class Factory<T> {
private Map<Param, T> instances = new HashMap<Param, T>();
public final T create(Class<T> clazz, Param param) throws Exception {
T cur = instances.get(param);
if (cur == null) {
cur = clazz.newInstance();
((Base)cur).setParam(param);
instances.put(param, cur);
}
return cur;
}
}
Subclasses should have the no-args constructor, not public; for consistency remove the with-param one:
public class Person extends Base {
protected Person(){}
public void handle(String name, int age) {
// Expose a type safe interface to the world
super.handle(name, age);
}
}
An example of usage:
public class TestFactory {
public static void main(String[] args) throws Exception {
Factory<Person> factory = new Factory<Person>();
Person p = factory.create(Person.class, new Param());
}
}
Of course I know this is not a pattern and it is not the more elegant code I could be proud of, but still avoid you having to change the factory for each new subclass, it does not use static methods and keeps in a single point the caching logic.
I have the following
public abstract class MyData
{
private String sID;
public void setsID(String sID) {
this.sID= sID;
}
public String getsID() {
return sID;
}
}
This base class is being extended by 2 other classes
public class DataTypeOne extends MyData
{
private String sName;
public void setsName(String sName) {
this.sName= sName;
}
public String getsName() {
return sName;
}
}
public class DataTypeTwo extends MyData
{
private String sSummary;
public void setsSummary(String sSummary) {
this.sSummary= sSummary;
}
public String getsSummary() {
return sSummary;
}
}
I am initializing this class as follows
MyData oDataOne = new DataTypeOne();
MyData oDataTwo = new DataTypeTwo();
Reason for that is that I have a factory method which shall give me the class based on type (One or two)
With oDataOne & oDataTwo, I am able to access getsID() from the base class but not the getters & setters of the respective class.
How can I access those? I
You can't access a method that doesn't exist. All you've promised your Java compiler is that oDataOne and oDataTwo are MyData objects. Since the MyData class doesn't have the implementation-specific methods, you cannot ask Java to call those methods (since it doesn't think they exist).
If you want to access those methods, you need to either cast the object to a class that actually has the right methods, or you can add abstract method stubs to your base class, which will tell Java that those methods actually exist.
Type casting is simpler to write in the short term, but less clear, and you may run into more trouble down the road:
((DataTypeOne) oDataOne).getsName();
((DataTypeTwo) oDataOne).getsSummary(); // Throws ClassCastException!
Adding abstract stubs is more robust, but may not make sense if not all concrete subclasses should implement all abstract methods:
public abstract class MyData {
public abstract void setsName(String name);
public abstract String getsName();
public abstract void setsSummary(String summary);
public abstract String getsSummary();
}
public class DataTypeOne extends MyData {
public String getsName() {
// implement
}
public void setsName(String name) {
// implement
}
// Still have to implement these!!!
public String getsSummary() {
// raise an exception or something if appropriate
}
public void setsSummary(String summary) {
// raise an exception or something if appropriate
}
}
// Same for DataTypeTwo
Since you declared the variable as a MyData, you can only access the methods of MyData. You can get to the subclass methods by casting it to DataTypeOne or DataTypeTwo:
((DataTypeOne)oDataOne).getsName()
But you need to be sure it is of type DataTypeOne or you will get a ClassCastException
MyData oDataOne = new DataTypeOne();
this says, that your oDataOne object is of the type MyData. Even if it is created as a DataTypeOne, java can only be sure that it is defiantly a MyData instance.
If you are sure that the MyData instance is in reality also a DataTypeOne instance, you can cast and then access the DataTypeOne methods + the MyData methods.
To make sure that an object is of a specific type test:
if(oDataOne instanceOf DataTypeOne){
((DataTypeOne) oDataOne).getsName(); // this will return the Name if oDataOne is really of the type DataTypeOne
}
An object of type MyData has no knowledge of whether any other classes extends it or not, so there is no way to access members of those classes.
You will have to cast your object to the specific type to access the specific members.
If you find yourself in this situation, you can be pretty sure that your design is flawed. If you need to perform a specific action for each type of MyData extension, add a method, e.g specialAction() to the interface and hide the specifics in there. That eliminates the entire need to find out which subclass you are dealing with.
I have a following problem I want to solve ellegantly:
public interface IMyclass
{
}
public class A
{
public void Init(IMyclass class){?}
public IMyclass CreateMyClass(){?}
}
At the start of the system I want to define dynamic type of IMyClass by using Init() and during the run of the system i would like to create new instances of the type I defined at init.
Notes:
1. IMyclass must be interface
2. The dynamic type of IMyclass known only at init (i have no constructor after :) )
3. I could do it using a reflection or definition method clone at IMyclass is there any better solutions?
Thank you.
You could pass a provider into class A
public class A
{
IMyClassProvider _provider;
public void Init(IMyClassProvider provider)
{
_provider = provider;
}
public IMyclass CreateMyClass()
{
return _provider.Create();
}
}
Or maybe with a constructor delegate
public class A
{
Func<IMyclass> _ctor;
public void Init(Func<IMyclass> ctor)
{
_ctor = ctor;
}
public IMyclass CreateMyClass()
{
return _ctor();
}
}
Note that both of these examples will blow up if Init has not been called before CreateMyClass, you would need some checking or better is doing your init in the constructor.
Have I understood the question correctly?
This is a kind of dependency injection, you should read:
http://en.wikipedia.org/wiki/Dependency_injection
http://www.martinfowler.com/articles/injection.html#FormsOfDependencyInjection
Basically, you have a class A that is populated with factories (or providers) at initialization. Then you use A instead of calling new.
A quick example:
interface Provider<V> {
V instance(Object... args);
}
class Dispatch {
// you can make a singleton out of this class
Map<Class, Provider> map;
<T> void register(Class<T> cl, Provider<? extends T> p) {
// you can also bind to superclasses of cl
map.put(cl, p);
}
<T, I extends T> void register(Class<T> cl, final Class<I> impl) {
register(cl, new Provider<I>() {
I instance(Object... args) {
// this class should be refactored and put in a separate file
// a constructor with arguments could be found based on types of args values
// moreover, exceptions should be handled
return impl.newInstace();
}
});
}
<T> T instance(Class<T> cl, Object... args) {
return map.get(cl).instance(args);
}
}
// usage
interface MyIf { ... }
class MyIfImpl implements MyIf { ... }
Dispatch d = new Dispatch();
d.register(MyIf.class, new Provider<MyIf>() {
MyIf instance(Object... args) {
return new MyIfImpl();
}
});
// or just
d.register(MyIf.class, MyIfImpl.class);
MyIf i = d.instance(MyIf.class);
Edit:
added register(Class, Class)
If you just want to instantiate the same class in CreateMyClass() without further configuration you can use reflection.
public class A
{
private Class prototype;
public void Init(IMyClass object) {
this.prototype = object.getClass();
}
public IMyClass CreateMyClass() {
return prototype.newInstance();
}
}
I suspect you want more than this, and if so you'll need to explain how you want to use this. You may be looking for the Builder or Factory patterns.
You'll need Reflection at some point due to visibility. If you can accept Reflection once up-front and not have to use it again, that would probably be ideal, yes?
You could put a getInstance() method on a hidden interface (located in the same package as IMyClass, MyClassImpl, and A, but not ClientOfA), and then pass a prototype of MyClassImpl to A.init().
// -- You wish you would have thought of the word prototypeable! ...maybe?
interface IMyClassPrototypeable extends IMyClass
{
public IMyClass getInstance();
}
class MyClassImpl implements IMyClassPrototypeable // -- and IMyClass by extension.
{
// -- Still not visible outside this package.
public IMyClass getInstance()
{
return new MyClassImpl();
}
}
class A
{
private IMyClassPrototypeable prototype;
// -- This method is package-private.
void init( IMyClassPrototypeable prototype )
{
this.prototype = prototype;
}
public IMyClass createMyClass()
{
return prototype.getInstance();
}
}
This solution would require Reflection to create the prototype instance of MyClassImpl, which could be done via Spring (or some other form of dependency injection). It uses the Prototype pattern, the Factory-method pattern, and readily supports the Singleton/Pool pattern, but remember that more design patterns used is not always better. In fact, it can make the design (and code) more complex and more difficult for a beginner to understand.
For the record, the only reason I would even think about advocating this solution is because it takes the reflection hit once, up front, rather than every time createMyClass() is called, which the original poster indicated he/she would be doing frequently.