Accessing child variables from super workaround - java

I have the following classes.
public abstract class Thing {
private String appearance;
public void setAppearance(String appearance) {
this.appearance = appearance;
}
}
public abstract class MovableThing extends Thing {
// ASCII representation of MovableThing moving right.
private static String FACE_RIGHT;
// ASCII representation of MovableThing moving left.
private static String FACE_LEFT;
private boolean goingRight;
public MovableThing() {
setAppearance(FACE_RIGHT);
goingRight = true;
// Some other things
public void turnAround() {
goingRight = !goingRight;
if (goingRight) {
setAppearance(FACE_RIGHT);
} else {
setAppearance(FACE_LEFT);
}
}
public class Bird extends MovableThing() {
private static String FACE_RIGHT = "/'/>";
private static String FACE_LEFT = "<\\'\\";
public Bird() {
super();
// Some other things
}
}
I know that this is currently incorrect because in MovableThing, FACE_RIGHT doesn't get assigned anything so when I call super() in Bird, the appearance just gets set to null. How can I work around this? I have multiple animals with different left/right ASCII representations but I'm not sure how to do all of this in an OOP kind of way.
Edit: Meant to say Bird() instead of Chicken().

Here is what I would do with your code to model your scenario:
public abstract class Thing {
private String appearance;
// Require subclasses of Thing to have a defined "going left" and "going right"
// method.
public abstract void setGoingLeft();
public abstract void setGoingRight();
protected final void setAppearance(String appearance) {
this.appearance = appearance;
}
}
public abstract class MovableThing extends Thing {
private boolean goingRight;
public MovableThing() {
setGoingRight();
// Some other things
}
// Require subclasses to define a method that gives me a String showing which
// way they're facing, when I tell them what way they're facing. This allows
// subclasses (like Bird) to each return their own appearances depending on the
// way they are facing.
protected abstract String getAppearance(boolean right);
// Override the "going left" and "going right" methods (and make them final so
// subclasses can't change them). These also modify the "goingRight" field of a
// MovableThing correctly.
#Override
public final void setGoingLeft() {
goingRight = false;
getAppearance(false);
}
#Override
public final void setGoingRight() {
goingRight = true;
getAppearance(true);
}
public void turnAround() {
// If they're going right, turning them around will make them go left and vice
// versa.
if (goingRight)
setGoingLeft();
else
setGoingRight();
}
}
public class Bird extends MovableThing {
private static final String FACE_RIGHT = "/'/>";
private static final String FACE_LEFT = "<\\'\\";
// This method is called by the super class.
#Override
protected String getAppearance(boolean right) {
// If the super class asks for a Bird's appearance when facing right, return
// "FACE_RIGHT". Otherwise, return "FACE_LEFT". (Other animals can return
// different things depending on the way they're facing.)
return right ? FACE_RIGHT : FACE_LEFT;
}
}

Related

Question on diamond operator for design pattern strategy

Small question regarding the diamond operator and design pattern strategy for Java, please.
I would like to implement a very specific requirement:
there are some objects to store (in my example called MyThingToStore)
and the requirement is to store them with different kinds of data structures, for comparison.
Therefore, I went to try with a strategy pattern, where each of the strategies is a different way to store, I think this pattern is quite lovely.
The code is as follows:
public class MyThingToStore {
private final String name;
public MyThingToStore(String name) {
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyThingToStore that = (MyThingToStore) o;
return Objects.equals(name, that.name);
}
#Override
public int hashCode() {
return Objects.hash(name);
}
#Override
public String toString() {
return "MyThingToStore{" +
"name='" + name + '\'' +
'}';
}
}
public class MyStorage {
private final StorageStrategy storageStrategy;
public MyStorage(StorageStrategy storageStrategy) {
this.storageStrategy = storageStrategy;
}
public void addToStore(MyThingToStore myThingToStore) {
storageStrategy.addToStore(myThingToStore);
}
public int getSize() {
return storageStrategy.getSize();
}
}
public interface StorageStrategy {
void addToStore(MyThingToStore myThingToStore);
int getSize();
}
public class StorageUsingArrayListStrategy implements StorageStrategy {
private final List<MyThingToStore> storeUsingArrayList = new ArrayList<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingArrayList.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingArrayList.size();
}
}
public class StorageUsingHashSetStrategy implements StorageStrategy{
private final Set<MyThingToStore> storeUsingHashSet = new HashSet<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingHashSet.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingHashSet.size();
}
}
public class Main {
public static void main(String[] args) {
final StorageStrategy storageStrategy = new StorageUsingArrayListStrategy();
final MyStorage myStorage = new MyStorage(storageStrategy);
myStorage.addToStore(new MyThingToStore("firstItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
System.out.println(myStorage.getSize()); //changing strategy will return a different size, working!
}
}
And this is working fine, very happy, especially tackled the requirement "easy to change the data structure to do the actual store".
(By the way, side question, if there is an even better way to do this, please let me know!)
Now, looking online at different implementations of strategy patterns, I see this diamond operator which I am having a hard time understanding:
MyThingToStore stays the same.
public class MyStorage {
private final StorageStrategy<MyThingToStore> storageStrategy; //note the diamond here
public MyStorage(StorageStrategy<MyThingToStore> storageStrategy) {
this.storageStrategy = storageStrategy;
}
public void addToStore(MyThingToStore myThingToStore) {
storageStrategy.addToStore(myThingToStore);
}
public int getSize() {
return storageStrategy.getSize();
}
#Override
public String toString() {
return "MyStorage{" +
"storageStrategy=" + storageStrategy +
'}';
}
}
public interface StorageStrategy<MyThingToStore> {
//note the diamond, and it will be colored differently in IDEs
void addToStore(MyThingToStore myThingToStore);
int getSize();
}
public class StorageUsingArrayListStrategy implements StorageStrategy<MyThingToStore> {
private final List<MyThingToStore> storeUsingArrayList = new ArrayList<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingArrayList.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingArrayList.size();
}
}
public class StorageUsingHashSetStrategy implements StorageStrategy<MyThingToStore> {
private final Set<MyThingToStore> storeUsingHashSet = new HashSet<>();
#Override
public void addToStore(MyThingToStore myThingToStore) {
storeUsingHashSet.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingHashSet.size();
}
}
public class Main {
public static void main(String[] args) {
final StorageStrategy<MyThingToStore> storageStrategy = new StorageUsingArrayListStrategy();
final MyStorage myStorage = new MyStorage(storageStrategy);
myStorage.addToStore(new MyThingToStore("firstItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
myStorage.addToStore(new MyThingToStore("duplicatedSecondItem"));
System.out.println(myStorage.getSize()); //changing strategy will return a different size, working!
}
}
And both versions will yield the same good result, also be able to answer requirements.
My question is: what are the differences between the version without a diamond operator, and the version with the diamond operator, please?
Which of the two ways are "better" and why?
While this question might appear to be "too vague", I believe there is a reason for a better choice.
I think the confusion comes from how you named type parameter for StorageStrategy in your 2nd example.
Let's name it T for type instead. T in this case is just a placeholder to express what type of objects your StorageStrategy can work with.
public interface StorageStrategy<T> {
void addToStore(T myThingToStore);
int getSize();
}
E.g.
StorageStrategy<MyThingToStore> strategy1 = // Initialization
StorageStrategy<String> strategy2 = // Initialization
strategy1.addToStore(new MyThingToStore("Apple"));
// This works fine, because strategy2 accepts "String" instead of "MyThingToStore"
strategy2.addToStore("Apple");
// Last line doesn't work, because strategy1 can only handle objects of type "MyThingToStore"
strategy1.addToStore("Apple");
To make it work properly, you need to change your different StorageStrategy implementations to also include the type parameter.
public class StorageUsingHashSetStrategy<T> implements StorageStrategy<T> {
private final Set<T> storeUsingHashSet = new HashSet<>();
#Override
public void addToStore(T myThingToStore) {
storeUsingHashSet.add(myThingToStore);
}
#Override
public int getSize() {
return storeUsingHashSet.size();
}
}
And lastly you also want to have a type paremeter for MyStorage
public class MyStorage<T> {
private final StorageStrategy<T> storageStrategy;
public MyStorage(StorageStrategy<T> storageStrategy) {
this.storageStrategy = storageStrategy;
}
public void addToStore(T myThingToStore) {
storageStrategy.addToStore(myThingToStore);
}
public int getSize() {
return storageStrategy.getSize();
}
}
Now you can create a MyStorage and can use it to store essentially any object into it and not just MyThingToStore. Whether that is something you want or not is up to you.
In the second code sample in the declaration of the interface StorageStrategy<MyThingToStore>, MyThingToStore is a Type Variable.
I.e. it's not the actual type, only a placeholder for a type, like T. The common convention is to use single-letter generic type variables (T, U, R, etc.), otherwise it might look confusing like in this case.
Note that in the class declarations, like:
public class StorageUsingArrayListStrategy
implements StorageStrategy<MyThingToStore>
MyThingToStore is no longer a type variable, but the name of the class MyThingToStore because in this case parameterized interface is implemented by a non-parameterized class (i.e. the actual type known to the compile is expected to be provided).

How to access a parent class variable via a child class

I am trying to re-build an OOP approach to mobile verification at the developers discretion. The concept I come up with is to allow for interfaces to manipulate the class. If the class implements the interface, then the verify method will be executed.
The problem I am facing, because I am only used to programming in less strongly-typed languages (PHP) is how to get a protected variable from a class extending the current class.
_areaCodes.stream().forEach(o -> {
try {
int prefix = Integer.parseInt(this._mobileNumber.charAt(0), this._mobileNumber.charAt(1));
} catch (Exception e) {}
});
This line of code is now giving me an error
_mobileNumber cannot be resolved or is not a field
Here is my full code and here is an example I wrote of the same concept in PHP which I am trying to implement in Java.
import java.util.ArrayList;
interface Verification
{
public void initVerification();
}
class AreaCode
{
private int _code;
private String _country;
public AreaCode(int code, String country)
{
this._code = code;
this._country = country;
}
public int getAreaCode() { return this._code; }
public String getAreaCountry() { return this._country; }
}
class VerificationHandler
{
private ArrayList<AreaCode> _areaCodes = new ArrayList<AreaCode>() {{
this.add(new AreaCode(44, "UNITED KINGDOM"));
this.add(new AreaCode(91, "INDIA"));
}};
public void initVerification()
{
if(this instanceof Verification) {
this.verify();
}
}
protected void verify()
{
_areaCodes.stream().forEach(o -> {
try {
int prefix = Integer.parseInt(this._mobileNumber.charAt(0), this._mobileNumber.charAt(1));
} catch (Exception e) {}
});
}
}
class Main extends VerificationHandler implements Verification {
protected String _mobileNumber = "+447435217761";
}
public class Hack1337 { public static void main(String[] args) { new Main(); } }
How can I retrieve a variable in a class extending another, ie:
class A { public String getB() { return this.b; } }
class B extends A { protected String b = 'A should get this'; }
B b = new B().getB();
Only instances of class B, or sub-classes of B can access the b instance variable directly (unless you cast A to B within the body of the A class, which is bad practice).
You can give class A read-only access to that value by overriding getB():
class B extends A
{
protected String b = 'A should get this';
#Override
public String getB() {
return this.b;
}
}
and you may also want to make the getB() method abstract in class A (which means making class A abstract):
abstract class A
{
public abstract String getB();
}
This would only make sense if different sub-classes of A are expected to return different things in getB(). Otherwise, you may as well move the b variable to the base class A.

can you call different methods with one changing variable in java?

ex:
public class Game{
String level;
public void update(){
update+"level"(); //calls diff. method depending on variable
}
public static void setLevel(String lv){
level = lv;
}
private updateLevelOne(){
.....
}
private updateLevelTwo(){
.....
}
}
public class Level{......
Game.setLevel(One);
}
I know the top statement wont work. But I was wondering if its possible to make a call in such way that I wouldn't have to use a if/switch statement and go directly to the method.
Either use a switch statement or objects:
Switch statement:
public class Game {
private int level;
public void update() {
switch(level) {
case 1:
updateLevelOne();
break;
case 2:
updateLevelTwo();
break;
}
}
public static void setLevel(int lv) {
level = lv;
}
private updateLevelOne() {
.....
}
private updateLevelTwo() {
.....
}
}
Alternatively, make your levels objects:
public class Game {
private Level[] levels;
private int currentLevel;
public Game() {
levels = new Level[2]
levels[0] = new Level();
levels[1] = new Level();
currentLevel = 0;
}
public void update() {
levels[currentLevel].update();
}
public static void setLevel(int newLevel) {
currentLevel = newLevel;
}
}
public class Level {
public Level() {
}
public void update() {
}
}
Objects are preferred but you can go either way. You could also go with the reflection package, but that's a worse idea that will be harder to understand.
No, it's not possible to create method names dynamically like this.
You should look up the Strategy pattern. This means you set some Level interface as a field in your class.
All your different levels should implement this interface, and each should implement some update method. At runtime, you can set this field with the exact implementation that you need at that time and you can call update() on it. This will delegate to the required implementation.

Builder Pattern and Inheritance

I have an object hierarchy that increases in complexity as the inheritance tree deepens. None of these are abstract, hence, all of their instances serve a, more or less sophisticated, purpose.
As the number of parameters is quite high, I would want to use the Builder Pattern to set properties rather than code several constructors. As I need to cater to all permutations, leaf classes in my inheritance tree would have telescoping constructors.
I have browsed for an answer here when I hit some problems during my design. First of, let me give you a simple, shallow example to illustrate the problem.
public class Rabbit
{
public String sex;
public String name;
public Rabbit(Builder builder)
{
sex = builder.sex;
name = builder.name;
}
public static class Builder
{
protected String sex;
protected String name;
public Builder() { }
public Builder sex(String sex)
{
this.sex = sex;
return this;
}
public Builder name(String name)
{
this.name = name;
return this;
}
public Rabbit build()
{
return new Rabbit(this);
}
}
}
public class Lop extends Rabbit
{
public float earLength;
public String furColour;
public Lop(LopBuilder builder)
{
super(builder);
this.earLength = builder.earLength;
this.furColour = builder.furColour;
}
public static class LopBuilder extends Rabbit.Builder
{
protected float earLength;
protected String furColour;
public LopBuilder() { }
public Builder earLength(float length)
{
this.earLength = length;
return this;
}
public Builder furColour(String colour)
{
this.furColour = colour;
return this;
}
public Lop build()
{
return new Lop(this);
}
}
}
Now that we have some code to go on, imaging I want to build a Lop:
Lop lop = new Lop.LopBuilder().furColour("Gray").name("Rabbit").earLength(4.6f);
This call will not compile as the last chained call cannot be resolved, Builder not defining the method earLength. So this way requires that all calls be chained in a specific order which is very impractical, especially with a deep hierarchy tree.
Now, during my search for an answer, I came across Subclassing a Java Builder class which suggests using the Curiously Recursive Generic Pattern. However, as my hierarchy does not contain an abstract class, this solution will not work for me. But the approach relies on abstraction and polymorphism to function which is why I don't believe I can adapt it to my needs.
An approach I have currently settled with is to override all methods of the superclass Builder in the hierarchy and simply do the following:
public ConcreteBuilder someOverridenMethod(Object someParameter)
{
super(someParameter);
return this;
}
With this approach I can assure I am being returned an instance I can issue chain calls on. While this is not as worse as the Telescoping Anti-pattern, it is a close second and I consider it a bit "hacky".
Is there another solution to my problem that I am not aware of? Preferably a solution consistent with the design pattern. Thank you!
This is certainly possible with the recursive bound, but the subtype builders need to also be generic, and you need a few interim abstract classes. It's a little bit cumbersome, but it's still easier than the non-generic version.
/**
* Extend this for Mammal subtype builders.
*/
abstract class GenericMammalBuilder<B extends GenericMammalBuilder<B>> {
String sex;
String name;
B sex(String sex) {
this.sex = sex;
return self();
}
B name(String name) {
this.name = name;
return self();
}
abstract Mammal build();
#SuppressWarnings("unchecked")
final B self() {
return (B) this;
}
}
/**
* Use this to actually build new Mammal instances.
*/
final class MammalBuilder extends GenericMammalBuilder<MammalBuilder> {
#Override
Mammal build() {
return new Mammal(this);
}
}
/**
* Extend this for Rabbit subtype builders, e.g. LopBuilder.
*/
abstract class GenericRabbitBuilder<B extends GenericRabbitBuilder<B>>
extends GenericMammalBuilder<B> {
Color furColor;
B furColor(Color furColor) {
this.furColor = furColor;
return self();
}
#Override
abstract Rabbit build();
}
/**
* Use this to actually build new Rabbit instances.
*/
final class RabbitBuilder extends GenericRabbitBuilder<RabbitBuilder> {
#Override
Rabbit build() {
return new Rabbit(this);
}
}
There's a way to avoid having the "concrete" leaf classes, where if we had this:
class MammalBuilder<B extends MammalBuilder<B>> {
...
}
class RabbitBuilder<B extends RabbitBuilder<B>>
extends MammalBuilder<B> {
...
}
Then you need to create new instances with a diamond, and use wildcards in the reference type:
static RabbitBuilder<?> builder() {
return new RabbitBuilder<>();
}
That works because the bound on the type variable ensures that all the methods of e.g. RabbitBuilder have a return type with RabbitBuilder, even when the type argument is just a wildcard.
I'm not much of a fan of that, though, because you need to use wildcards everywhere, and you can only create a new instance using the diamond or a raw type. I suppose you end up with a little awkwardness either way.
And by the way, about this:
#SuppressWarnings("unchecked")
final B self() {
return (B) this;
}
There's a way to avoid that unchecked cast, which is to make the method abstract:
abstract B self();
And then override it in the leaf subclass:
#Override
RabbitBuilder self() { return this; }
The issue with doing it that way is that although it's more type-safe, the subclass can return something other than this. Basically, either way, the subclass has the opportunity to do something wrong, so I don't really see much of a reason to prefer one of those approaches over the other.
Confronted with the same issue, I used the solution proposed by emcmanus at: https://community.oracle.com/blogs/emcmanus/2010/10/24/using-builder-pattern-subclasses
I'm just recopying his/her preferred solution here. Let say we have two classes, Shape and Rectangle. Rectangle inherits from Shape.
public class Shape {
private final double opacity;
public double getOpacity() {
return opacity;
}
protected static abstract class Init<T extends Init<T>> {
private double opacity;
protected abstract T self();
public T opacity(double opacity) {
this.opacity = opacity;
return self();
}
public Shape build() {
return new Shape(this);
}
}
public static class Builder extends Init<Builder> {
#Override
protected Builder self() {
return this;
}
}
protected Shape(Init<?> init) {
this.opacity = init.opacity;
}
}
There is the Init inner class, which is abstract, and the Builder inner class, that is an actual implementation. Will be useful when implementing the Rectangle:
public class Rectangle extends Shape {
private final double height;
public double getHeight() {
return height;
}
protected static abstract class Init<T extends Init<T>> extends Shape.Init<T> {
private double height;
public T height(double height) {
this.height = height;
return self();
}
public Rectangle build() {
return new Rectangle(this);
}
}
public static class Builder extends Init<Builder> {
#Override
protected Builder self() {
return this;
}
}
protected Rectangle(Init<?> init) {
super(init);
this.height = init.height;
}
}
To instantiate the Rectangle:
new Rectangle.Builder().opacity(1.0D).height(1.0D).build();
Again, an abstract Init class, inheriting from Shape.Init, and a Build that is the actual implementation. Each Builder class implement the self method, which is responsible to return a correctly cast version of itself.
Shape.Init <-- Shape.Builder
^
|
|
Rectangle.Init <-- Rectangle.Builder
If anyone still bumped into the same problem, I suggest the following solution, that conforms "Prefer composition over inheritance" design pattern.
Parent class
The main element of it is the interface that parent class Builder must implement:
public interface RabbitBuilder<T> {
public T sex(String sex);
public T name(String name);
}
Here is the changed parent class with the change:
public class Rabbit {
public String sex;
public String name;
public Rabbit(Builder builder) {
sex = builder.sex;
name = builder.name;
}
public static class Builder implements RabbitBuilder<Builder> {
protected String sex;
protected String name;
public Builder() {}
public Rabbit build() {
return new Rabbit(this);
}
#Override
public Builder sex(String sex) {
this.sex = sex;
return this;
}
#Override
public Builder name(String name) {
this.name = name;
return this;
}
}
}
The child class
The child class Builder must implement the same interface (with different generic type):
public static class LopBuilder implements RabbitBuilder<LopBuilder>
Inside the child class Builder the field referencing parentBuilder:
private Rabbit.Builder baseBuilder;
this ensures that parent Builder methods are called in the child, however, their implementation is different:
#Override
public LopBuilder sex(String sex) {
baseBuilder.sex(sex);
return this;
}
#Override
public LopBuilder name(String name) {
baseBuilder.name(name);
return this;
}
public Rabbit build() {
return new Lop(this);
}
The constructor of Builder:
public LopBuilder() {
baseBuilder = new Rabbit.Builder();
}
The constructor of builded child class:
public Lop(LopBuilder builder) {
super(builder.baseBuilder);
}
I have adopted the following guidelines when creating object hierarchies with builders:
Make the constructor of the class at least protected and use it as copy constructor, thus pass it an instance of the class itself.
Make the fields non-final private and use getters to access them.
Add package private setters for the builders, which is also nice for object serialization frameworks.
Make a generic builder for each class that will have a subclass builder. This builder will already contain the setter methods for the current class, but we create also a second non generic builder for the class that contains the constructor and build method.
The builders will not have any fields. Instead the generic builder that is on top of the hierarchy will contain a generic field for the concrete object to be build.
The Rabbit will look like this:
public class Rabbit {
// private non-final fields
private String sex;
private String name;
// copy constructor
Rabbit(Rabbit rabbit) {
sex = rabbit.sex;
name = rabbit.name;
}
// no-arg constructor for serialization and builder
Rabbit() {}
// getter methods
public final String getSex() {
return sex;
}
public final String getName() {
return name;
}
// package private setter methods, good for serialization frameworks
final void setSex(String sex) {
this.sex = sex;
}
final void setName(String name) {
this.name = name;
}
// create a generic builder for builders that have subclass builders
abstract static class RBuilder<R extends Rabbit, B extends RBuilder<R, B>> {
// the builder creates the rabbit
final R rabbit;
// here we pass the concrete subclass that will be constructed
RBuilder(R rabbit) {
this.rabbit = rabbit;
}
public final B sex(String sex) {
rabbit.setSex(sex);
return self();
}
public final B name(String name) {
rabbit.setName(name);
return self();
}
#SuppressWarnings("unchecked")
final B self() {
return (B) this;
}
}
// the builder that creates the rabbits
public static final class Builder extends RBuilder<Rabbit, Builder> {
// creates a new rabbit builder
public Builder() {
super(new Rabbit());
}
// we could provide a public copy constructor to support modifying rabbits
public Builder(Rabbit rabbit) {
super(new Rabbit(rabbit));
}
// create the final rabbit
public Rabbit build() {
// maybe make a validate method call before?
return new Rabbit(rabbit);
}
}
}
and our Lop:
public final class Lop extends Rabbit {
// private non-final fields
private float earLength;
private String furColour;
// copy constructor
private Lop(Lop lop) {
super(lop);
this.earLength = lop.earLength;
this.furColour = lop.furColour;
}
// no-arg constructor for serialization and builder
Lop() {}
// getter methods
public final float getEarLength() {
return earLength;
}
public final String getFurColour() {
return furColour;
}
// package private setter methods, good for serialization frameworks
final void setEarLength(float earLength) {
this.earLength = earLength;
}
final void setFurColour(String furColour) {
this.furColour = furColour;
}
// the builder that creates lops
public static final class Builder extends RBuilder<Lop, Builder> {
public Builder() {
super(new Lop());
}
// we could provide a public copy constructor to support modifying lops
public Builder(Lop lop) {
super(new Lop(lop));
}
public final Builder earLength(float length) {
rabbit.setEarLength(length);
return self(); // this works also here
}
public final Builder furColour(String colour) {
rabbit.setFurColour(colour);
return self();
}
public Lop build() {
return new Lop(rabbit);
}
}
}
Pros:
The builders will exactly mirror the object hierarchy of your classes with a single derivative for each generic builder to build the objects of the current class. No need to create artificial parents.
The class does not have a dependency to its builder. All it needs is an instance of itself to copy the fields, which might be useful for alternative factories.
The classes work very well with serialization frameworks like JSON or Hibernate, since they most often need getters and setters to be present. E.g. Jackson works fine with package private setters.
No need to duplicate fields in the builder. The builder contains the object to be constructed.
No need to override setter methods in the subtype builders since the direct parent class is generic.
Build-in support for copy constructors to allow creating a modified version of an instance, making the objects 'kind of immutable'.
Cons:
Requires at least one additional generic builder.
Fields are not final, thus it's not safe to make them public.
The class itself needs additional setter methods to be called from the builders.
Let's create some rabbits..
#Test
void test() {
// creating a rabbit
Rabbit rabbit = new Rabbit.Builder() //
.sex("M")
.name("Rogger")
.build();
assertEquals("M", rabbit.getSex());
// create a lop
Lop lop = new Lop.Builder() //
.furColour("Gray")
.name("Rabbit")
.earLength(4.6f)
.build();
// modify only the name of the lop
lop = new Lop.Builder(lop) //
.name("Lop")
.build();
assertEquals("Gray", lop.getFurColour());
assertEquals("Lop", lop.getName());
}
This form seems to nearly work. It is not very tidy but it looks like it avoids your issues:
class Rabbit<B extends Rabbit.Builder<B>> {
String name;
public Rabbit(Builder<B> builder) {
this.name = builder.colour;
}
public static class Builder<B extends Rabbit.Builder<B>> {
protected String colour;
public B colour(String colour) {
this.colour = colour;
return (B)this;
}
public Rabbit<B> build () {
return new Rabbit<>(this);
}
}
}
class Lop<B extends Lop.Builder<B>> extends Rabbit<B> {
float earLength;
public Lop(Builder<B> builder) {
super(builder);
this.earLength = builder.earLength;
}
public static class Builder<B extends Lop.Builder<B>> extends Rabbit.Builder<B> {
protected float earLength;
public B earLength(float earLength) {
this.earLength = earLength;
return (B)this;
}
#Override
public Lop<B> build () {
return new Lop<>(this);
}
}
}
public class Test {
public void test() {
Rabbit rabbit = new Rabbit.Builder<>().colour("White").build();
Lop lop1 = new Lop.Builder<>().earLength(1.4F).colour("Brown").build();
Lop lop2 = new Lop.Builder<>().colour("Brown").earLength(1.4F).build();
//Lop.Builder<Lop, Lop.Builder> builder = new Lop.Builder<>();
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
Although I have successfully built Rabbit and Lop (in both forms) I cannot at this stage work out how to actually instantiate one of the Builder objects with it's full type.
The essence of this method relies on the cast to (B) in the Builder methods. This allow you to define the type of object and the type of the Builder and retain that within the object while it is constructed.
If anyone could work out the correct syntax for this (which is wrong) I would appreciate it.
Lop.Builder<Lop.Builder> builder = new Lop.Builder<>();
I did some experimenting and I found this to work quite nicely for me.
Note that I prefer to create the actual instance at the start and the call all the setters on that instance. This is just a preference.
The main differences with the accepted answer is that
I pass a parameter that indicated the return type
There is no need for an Abstract... and a final builder.
I create a 'newBuilder' convenience method.
The code:
public class MySuper {
private int superProperty;
public MySuper() { }
public void setSuperProperty(int superProperty) {
this.superProperty = superProperty;
}
public static SuperBuilder<? extends MySuper, ? extends SuperBuilder> newBuilder() {
return new SuperBuilder<>(new MySuper());
}
public static class SuperBuilder<R extends MySuper, B extends SuperBuilder<R, B>> {
private final R mySuper;
public SuperBuilder(R mySuper) {
this.mySuper = mySuper;
}
public B withSuper(int value) {
mySuper.setSuperProperty(value);
return (B) this;
}
public R build() {
return mySuper;
}
}
}
and then a subclass look like this:
public class MySub extends MySuper {
int subProperty;
public MySub() {
}
public void setSubProperty(int subProperty) {
this.subProperty = subProperty;
}
public static SubBuilder<? extends MySub, ? extends SubBuilder> newBuilder() {
return new SubBuilder(new MySub());
}
public static class SubBuilder<R extends MySub, B extends SubBuilder<R, B>>
extends SuperBuilder<R, B> {
private final R mySub;
public SubBuilder(R mySub) {
super(mySub);
this.mySub = mySub;
}
public B withSub(int value) {
mySub.setSubProperty(value);
return (B) this;
}
}
}
and a subsub class
public class MySubSub extends MySub {
private int subSubProperty;
public MySubSub() {
}
public void setSubSubProperty(int subProperty) {
this.subSubProperty = subProperty;
}
public static SubSubBuilder<? extends MySubSub, ? extends SubSubBuilder> newBuilder() {
return new SubSubBuilder<>(new MySubSub());
}
public static class SubSubBuilder<R extends MySubSub, B extends SubSubBuilder<R, B>>
extends SubBuilder<R, B> {
private final R mySubSub;
public SubSubBuilder(R mySub) {
super(mySub);
this.mySubSub = mySub;
}
public B withSubSub(int value) {
mySubSub.setSubSubProperty(value);
return (B)this;
}
}
}
To verify it fully works I used this test:
MySubSub subSub = MySubSub
.newBuilder()
.withSuper (1)
.withSub (2)
.withSubSub(3)
.withSub (2)
.withSuper (1)
.withSubSub(3)
.withSuper (1)
.withSub (2)
.build();
The following IEEE conference contribution Refined Fluent Builder in Java gives a comprehensive solution to the problem.
It dissects the original question into two sub-problems of inheritance deficiency and quasi invariance and shows how a solution to these two sub-problems opens for inheritance support with code reuse in the classical builder pattern in Java.
As you cannot use generics, now probably the main task is to somehow loosen typing.
I don't know how you process those properties afterwards, but what if you used a HashMap for storing them as key-value pairs? So there will be just one set(key, value) wrapper method in the builder (or builder might not be necessary any more).
The downside would be additional type castings while processing the stored data.
If this case is too loose, then you could keep the existing properties, but have a general set method, which uses reflection and searches for setter method on the basis of 'key' name. Although I think reflection would be an overkill.

using object functions in java

I'm trying to implement function objects in Java. I have a Unit class, with a default addition function that should be used in most initializations of a Unit object. However, for some issues, I need a different addition function. The code will look something like this:
public class Unit() {
public Unit(unitType) {
if (unitType == "specialType") {
additionFunc = defaultFunc } else {
additionFunc = specialFunc }
}
}
public int swim() {
return additionFunc()
}
// definiion of regularFunc
// definition of specialFunc
}
Then, from the main file:
Unit fish = new Unit(regularTyoe);
Unit fatFish = new Unit(specialType);
fish.swim(); //regular function is called
fatFish.swim(); //special function is called
That's it.. does anyone know how this can be done?
You need to look up inheritance and method overriding. It would probably help to read up on proper Object Oriented Programming as well.
The proper way to do this is:
class Fish {
public void swim() {
// normal swim
}
}
class FatFish extends Fish {
#Override
public void swim() {
// special swim
}
}
Fish fish = new Fish()
Fish fatFish = new FatFish()
fish.swim() // normal swim
fatFish.swim() // slow swim
Make a new FatFish class which extends Unit and overrides swim().
Unit fish = new Unit();
Unit fatFish = new FatFish();
fish.swim(); //regular function is called
fatFish.swim(); //special function is called
There are many solutions for your problem, one of them is using inheritance, that you could have a default implementation of Unit, and extend it overriding the desired method with a new one.
Basically would be something like:
public class FatFish {
#Override
public void swim() {
// new behavior
}
}
Another approach would be to implement Strategy Design Pattern, which allows you to select algorithms on runtime. Therefore you could do something like:
public interface SwimStrategy {
void execute();
}
public class FatFishSwimStrategy implements SwimStrategy {
#Override
public void execute() {
// fat fish swim impl
}
}
public class FishSwimStrategy implements SwimStrategy {
#Override
public void execute() {
// normal fish swim impl
}
}
public class Fish {
private final SwimStrategy swimStrategy;
public Fish(SwimStrategy swimStrategy) {
this.swimStrategy = swimStrategy;
}
public void swim() {
swimStrategy.execute();
}
}
In order to instantiate an object you could do:
new Fish(new FatFishSwimStrategy());
or for the normal behavior:
new Fish(new FishSwimStrategy());
I think it can do by extends and factory method:
public class Unit {
public static Unit createUnit(UnitType type) {
if (UnitType.Special == type) {
return new Unit(type) {
#Override
public int swim() {
System.out.println("special swim");
return 0;
}
};
}
return new Unit(UnitType.Default);
}
private UnitType type;
private Unit(UnitType type) {
this.type = type;
System.out.println("create unit for " + type);
}
public int swim() {
System.out.println("default swim");
return 0;
}
public static void main(String[] args) {
Unit fish = Unit.createUnit(UnitType.Default);
Unit fatFish = Unit.createUnit(UnitType.Special);
fish.swim();
fatFish.swim();
}
}
This is a simple type enum:
public enum UnitType {
Default, Special
}
There are two ways to accomplish this polymorphic behavior in Java. The first is to use a inheritance and a hierarchical set of classes. For example, you could have an abstract base class which defines an abstract method called "swim". Then each concrete fish class would extend this base class and implement the swim method. Later when you have a set of fish objects, you can upcast them to the base class and invoke the swim method on each.
The second way is to use interfaces. You define an interface (e.g. ISwim) which declares the public method swim. Each fish class (whether part of a class hierarchy or no) would implement the ISwim interface, meaning they would define a swim method. Then if you have a set of fish class objects of different types, you can cast each to the ISwim interface and invoke the swim method on each object.
Java does not have function pointers, so the approach you are considering is inappropriate for the language. Even in languages with function pointers, the above two approaches would be most appropriate in my opinion.
One way to do this is with an enum for the types of Unit and with Unit subclasses:
public class Unit {
public enum UnitType {
REGULAR {
public Unit makeUnit() {
return new RegularUnit();
}
},
SPECIAL {
public Unit makeUnit() {
return new SpecialUnit();
}
};
abstract public Unit makeUnit();
}
protected Unit() {}
public abstract int swim();
private static class RegularUnit extends Unit {
RegularUnit() {}
public int swim() {
return 0;
}
}
private static class SpecialUnit extends Unit {
SpecialUnit() {}
public int swim() {
return 1;
}
}
}
Unit fish = UnitType.REGULAR.makeUnit();
Unit fatFish = UnitType.SPECIAL.makeUnit();
Another way is with Callable objects:
public class Unit {
public enum UnitType { REGULAR, SPECIAL }
private Callable<Integer> additionFunc;
public Unit(UnitType type) {
switch (type) {
case REGULAR:
additionFunc = new Callable<Integer>() {
public Integer call() {
return 0;
}
};
break;
case SPECIAL:
additionFunc = new Callable<Integer>() {
public Integer call() {
return 1;
}
};
break;
}
}
public int swim() {
return additionFunc();
}
}
Using a simple if statement:
private String unitType;
public Unit(unitType) {
this.unitType = unitType;
}
public int swim() {
if (unitType.equals("specialType") {
return specialFunc();
}
else {
return regularFunc();
}
}
Or using polymorphism and a factory method :
public abstract class Unit() {
protected Unit() {
}
protected abstract int addition();
public int swim() {
return addition();
}
public static Unit forType(String unitType) {
if (unitType.equals("specialType") {
return new SpecialUnit();
}
else {
return new RegularUnit();
}
}
private static class SpecialUnit extends Unit {
#Override
protected addition() {
// special addition
}
}
private static class RegularUnit extends Unit {
#Override
protected addition() {
// regular addition
}
}
}
Or using an Adder functional interface, defining an addition() method, and two concrete implementations of this interface:
private Adder adder;
public Unit(unitType) {
if (unitType.equals("specialType") {
this.adder = new SpecialAdder();
}
else {
this.adder = new RegularAdder();
}
}
public int swim() {
return adder.addition();
}
This last one is the closest to waht you asked in your question. function objects don't exist per se, but can be replaced by interfaces.

Categories

Resources