Avoid casting and instanceOf - java

I got an interface
public interface Details {
// nothing needed until now
}
which is used in a class like the following:
public class Value {
// many fields
private Details details;
public Value(SomeType type) {
switch (type) {
case TYPE_1:
case TYPE_2:
this.details = new DetailsA();
break;
case TYPE_3:
this.details = new DetailsB();
break;
default:
throw new NotImplementedException("not yet implemented");
}
}
public Details getDetails() {
return this.details;
}
}
The interface has two implementations
public class DetailsA implements Details {
private BigDecimal betragA;
public DetailsA() {
}
public BigDecimal getBetragA() {
return this.betragA;
}
public void setBetragA(BigDecimal betragA) {
this.betragA = betragA;
}
}
public class DeailsB implements Details {
private BigDecimal betragB;
private boolean booleanB;
public BetragB() {
}
public BigDecimal getBetragB() {
return this.betragB;
}
public void setBetragB(BigDecimal betragB) {
this.betragB = betragB;
}
public boolean isBooleanB() {
return this.booleanB;
}
public void setBooleanB(boolean booleanB) {
this.booleanB = booleanB;
}
// some more fields
}
I got a model class in which I want to use those details, depending on the instance.
public class Model extends AbstractModel {
private Details details;
public void init(StoerungValue stoerung) {
setDetails(stoerung.getSchaden().getDetails());
}
private void setDetails(Details details) {
this.details = details;
}
// ...
In there I have some operations like the following
// ...
public void setBooleanB(boolean booleanB) {
if (details instanceof DetailB) {
((DetailB) details).setBooleanB(booleanB);
}
}
// ...
How can I avoid this casting and instanceOf stuff? Is any of the design patterns applicable here?

I think the problem you have here is a collection of design smells. You've painted yourself into a corner, and there may not be an easy way out. I don't know if this solution will work for you or not, but you can at least consider this.
The first design smell is that you have created an inheritance relationship where none actually exists. In short, the hierarchy rooted at Details violates the Liskov Substitution Principle. When a class claims (as Model does) to support the Details interface, it's making the claim that any implementation of Details will do. The program's correctness and behavior shouldn't change whether it's given a DetailsA, a DetailsB, or some FooDetails class that hasn't even been invented yet.
The reality is that DetailsA and DetailsB are not actually related. You can see this because Details has no methods, and thus may as well be Object which any two classes already inherit from.
The second design smell is "Feature Envy." It seems that many methods of Model are just pass-through calls to its underlying details property. You could consider, rather than having setBooleanB on Model to just provide a getDetails method, and then let the caller work directly on the Details object. This won't remove the instanceof checks or casting, but it will move them out of this class.
The third thing here is related two the first two. Model depends not on Details as its property types would tell you, but rather on (at least) DetailsB. If that's the case, then its property type should say so. Now, it's possible that sometimes you need a Model with a DetailsA and sometimes you need a Model with a DetailsB, but it can't be both at the same time. In that case, you can work around the issue with generics.
First, make the Model class generic, with a type parameter that tells what its underlying Details must actually be.
public abstract class Model<T extends Details> {
private T details;
public void init(T dets) {
setDetails(dets);
}
public void setDetails(T dets) {
this.details = dets;
}
public T getDetails() {
return this.details;
}
}
Then, create two subclasses that are bound to different Details types, and can thus promise to do the right thing without requiring casting or instanceof calls.
public class ModelA extends Model<DetailsA> {
public BigDecimal getBetragA() {
return this.getDetails().getBetragA();
}
}
public class ModelB extends Model<DetailsB> {
public boolean getBooleanB() {
return this.getDetails().isBooleanB();
}
public void setBooleanB(boolean boolB) {
this.getDetails().setBooleanB(boolB);
}
}
I'm not sure if that'll fix your problem or not, but it's something to consider.

Related

Is there someway to restrict the access to a member of an object only to the object that owns it by composition?

I really feel like there must be a way around this.
Imagine I have a large number of objects as components of an owner class. I want to offer easy access to the clients of this owner class to its members, so I make all those objects public. Each of those objects also have all their members public. But one member of the components should not be accessible to the clients of their owner, only by their owner itself:
public class ComponentObject
{
public int int_field;
public float float_field;
public Object object_field;
public Object public_method1()
{
//something;
}
public Object public_method2()
{
//something;
}
public Object restricted_to_owner_only()
{
//something;
}
}
//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
public ComponentObject component1;
public ComponentObject component2;
public ComponentObject component3;
//... lots of others
public ComponentObject component300;
}
Is there a way to achieve this? Note that any class from any package can own a ComponentObject, so using package level visibility at restricted_to_owner_only doesn't seem to be an option. ComponentObject is like a utility class, reusable in other applications.
Maybe there's an annotation that enforces that at compile time in some nice lib out there?
EDIT: I forgot to mention that ComponentObject is a parameterized type in real life, and each field in Owner is parameterized differently. I tried to abstract off the details so we could focus on the design problem itself, but I abstracted too much. I will post bellow something more similar to the real problem:
public class ComponentObject<T>
{
public int int_field;
public float float_field;
public T object_field;
//any method could return T or take T as an argument.
public T public_method1()
{
//something;
}
public Object public_method2()
{
//something;
}
public Object restricted_to_owner_only()
{
//something;
}
}
//all clients of Owner should be able to access all the members of its components, except
//restricted_to_owner_only, which only Owner should be able to access
public class Owner
{
public ComponentObject<String> component1;
public ComponentObject<File> component2;
public ComponentObject<Consumer<Boolean>> component3;
//... lots of others
public ComponentObject<Integer> component300;
}
EDIT 2 (Possibly a solution): Guys, inspired by Romeo and Juliet's love, I wrote this solution, can you spot any faults with it? Or would it work as I intended?
//add this class
public class OwnershipToken
{
private static int id_gen = 0;
public final int id = id_gen++;
#Override
public boolean equals(Object obj)
{
return (obj instanceof OwnershipToken) && ((OwnershipToken)obj).id == id;
}
#Override
public int hashCode()
{
return id;
}
}
//Then change this in ComponentObject<T>:
public class ComponentObject<T>
{
//add this field:
private final OwnershipToken ownershipToken;
//add this constructor
public ComponentObject(OwnershipToken onwershipToken)
{
this.ownershipToken = ownershipToken;
}
//change restricted_to_owner_only signature:
public Object restricted_to_owner_only(OwnershipToken ownershipToken)
{
//add this condition
if(this.ownershipToken.equals(ownershipToken)
//something;
}
}
//finally, Owner gains a field:
public class Owner
{
private final OwnershipToken ownershipToken = new OwnershipToken();
//... etc, remainder of the class
}
would this work as intended?
I understand what you want and that is impossible i think.
But, there is still one way to do it!
Make an id in the owner class:
private int id = new Random().nextInt(10000);
In ComponentObject:
private id;
public ComponentObject(int id){
this.id = id;
}
public Object restricted(int id){
if(this.id != id)
return null;
else
return object;
}
In owner:
private ComponentObject<String> string;
public Owner() {
string = new ComponentObject<>(id);
string.restricted(id);
//if the id is right it will return the restricted object, if not i will
//return null
}

What kind of relationship does an interface have with it implementing class?

A subclass has a relationship that is described as IS-A with it base class, but a base class does not share this kind of relationship with it subclass. I was wandering what kind of relationship an interface have with it implementing class since an object of that class can be passed to interface object and the interface object can only access methods defined it concrete Interface.
public class main {
public static void main(String[]args){
Nigeria ng = new Nigeria(){};
//Interface object can accept Nigerias object which is not posible in Inheritance
Continent continent = ng;
//prints Country is in Africa
continent.Africa();
//continent.language(); will not compile language is not in the interface
//Print Democratic thought this should print Undefined since it is inialied with default.
continent.Goverment();
}
}
interface Continent{
public void Africa();
default void Goverment(){
System.out.println("Undefined");
}
}
class Nigeria implements Continent{
#Override
public void Africa(){
System.out.println("Country is in Africa");
}
public void language(){
System.out.println("Official Language is English");
}
public void Goverment(){
System.out.println("Democratic");
}
}
If you are looking for English-language analogues, an Interface is not an "Is a..." nor "Has a..." relationship, but more an "Is...".
An Interface is not about the class that uses it.
It's about the consumer that asks for it.
If you wanted to see it as anything, you could see it as an adjective.
"He is Responsible".
Well, what does he do?
He finishes tasks; he takes ownership of his mistakes; he makes them right.
Is he a pilot, is he a surgeon, is he a doctor?
Is he a child, a father, a greatGrandfather?
Do you care?
I need a responsible person, to help me do this job.
Does ResponsiblePerson inherit from PoliceOfficer? Does Lawyer inherit from ResponsiblePerson, because I'm sure there can be irresponsible lawyers.
class Lawyer extends Person { }
class ResponsibleLawyer extends Lawyer implements ResponsibleEntity { }
class NeedyPerson extends Person {
public void acceptHelp (ResponsibleEntity somebody) {
try {
somebody.attemptTask( someTask );
} catch (TaskCompletionError err) {
somebody.takeOwnership(err);
somebody.fixMistake(err);
}
}
}
Can corporations be Responsible too?
Perhaps we don't see it too often, but it's theoretically possible:
class LawFirm extends CorporateEntity { }
class BetterLawFirm extends LawFirm implements ResponsibleEntity { }
Can somebody be a responsible corporate body? Well, so long as that corporate body does all of the same things that the responsible person would otherwise do, sure.
In another example, you might have a Switchable interface.
Looking at that name, you could surmise that the thing you're being given has a switch which can be poked.
So what methods might it have?
on( )
off( )
toggle( )
isOn( )
sounds like a useful set to have.
What benefit is there to having an interface like this?
Well, now I know that I can deal with a switch, and its lineage doesn't matter.
If all I want is a class which takes a switch and does something with it, why do I need to create dozens of classes, just to accept my dozens of things with switches?
Or override methods into the dirt to do the same.
class SwitchThrower {
public void throwSwitch (CoffeeMaker coffeeMaker) { coffeeMaker.on(); }
public void throwSwitch (LightSwitch lightSwitch) { lightSwitch.on(); }
public void throwSwitch (GhostTrap ghostTrap) { ghostTrap.on(); }
public void throwSwitch (TheHeat theHeat) { theHeat.on(); }
public void throwSwitch (CarIgnition ignition) { ignition.on(); }
}
...
why not just:
class SwitchThrower {
public void throwSwitch (Switchable switch) { switch.on(); }
}
class LightSwitch implements Switchable {
private boolean currentlyOn;
public LightSwitch (boolean initiallyOn) {
currentlyOn = initiallyOn;
}
public LightSwitch () {
currentlyOn = false;
}
public boolean on () {
currentlyOn = true;
return currentlyOn;
}
public boolean off () {
currentlyOn = false;
return currentlyOn;
}
public boolean toggle (boolean forceOn) {
boolean state;
if (forceOn == true) {
state = on();
} else {
state = off();
}
return state;
}
public boolean toggle () {
boolean state;
if (isOn() == true) {
state = off();
} else {
state = on();
}
return state;
}
public boolean isOn () {
return currentlyOn;
}
}
...et cetera
As you can see, aside from describing a basic feature-set of the implementer, interfaces are not about the class at all, but rather the consumer.
An even more awesome implementation of this, in different languages, is _Traits_.
Traits are typically like Interfaces, but they have default behaviour associated with them.
Looking at my Switchable and my LightSwitch, you could imagine that practically all classes with this switch would have the same methods, with the same method behaviour...
...so why would I rewrite all of those methods over again, if I'm already going through the trouble of defining the signature in the interface?
Why couldn't I just add default behaviour in there, and have it apply to the implementer, unless a method is overridden?
Well, that's what Traits / Mix-Ins allow.
The relationship is only the "contract" that the class is getting to implement the methods the interface is offering.
That is how java can separate WHAT objects can do (Interface) and HOW the inherited class will do it.

Public static final variable with getter

at work we do a peer review of code and I found something I don't like and I want to ask about best practice for this particular problem.
We have an interface:
public interface Item {
public String getType();
//some other methods
}
and an implementing class:
public class EmailItem implements Item {
public static final String TYPE = "email";
#Override
public String getType() {
return TYPE;
}
}
and some code that uses the classes:
for (Item item : items) {
if (EmailItem.TYPE.equals(item.getType())) {
isProcessed = Processor.process(item);
} else {
LOGGER.error("Unknown failover type received to process. Type: {}", item.getType());
}
}
At this point we have only one implementing class so checking the type is not necessary but we will add some other implementations and then it would make sense (though switch will be used).
The main issue is that EmailItem has variable TYPE set as public and this variable has also a getter.
Both class and instance of that class should have access to this variable, but having it public static final and accessing it with instance directly doesn't seem right/best practice (although it is technically possible) and when it would be private (as it should) then it won't be accessible from other classes (where for cycle is and static would not make sense at that point).
Through discussion we come up with solution with usage of instanceOf(...) or instance.getClass().getName() and EmailItem.class.getName() but none of them seem elegant to me :).
So finally, my question is what is the most elegant solution for described problem?
Heh, this is my first question here and I hope it makes sense to you ;).
Thinking about it from an OO point of view I'd consider the following approach:
public interface Item {
public boolean process();
//some other methods
}
public class EmailItem implements Item {
#Override
public boolean process() {
// email specific implementation
}
}
public class AnotherItem implements Item {
#Override
public boolean process() {
// another implementation
}
}
for (Item item : items) {
isProcessed = item.process();
}
The way you did it is fine, if you want to do it that way:
The static final variable TYPE lets you treat it as a type constant,
The implementation on the instance lets you check the constant against the return value on the interface.
However, when you find yourself dispatching on a type represented by String or some other value, you are usually going down a wrong path of switch statements in object-oriented code. If you have a choice of action at this point, consider an alternative technique of double dispatch, such as implementing the Visitor Pattern:
interface ItemVisitor {
void visitEmail(EmailItem item);
void visitSms(SmsItem item);
}
interface Item {
void accept(ItemVisitor v);
}
class EmailItem implements Item {
public void accept(ItemVisitor v) { v.visitEmail(this); }
}
class SmsItem implements Item {
public void accept(ItemVisitor v) { v.visitSms(this); }
}
Now you can do this:
class Example implements ItemVisitor {
public void visitEmail(EmailItem item) {
// Do something with an e-mail
}
public void visitSms(SmsItem item) {
// Do something with an SMS
}
public static void main(String[] args) {
Example e = new Example();
for (Item item : ItemSource.getManyItems()) {
item.accept(e);
}
}
}
If all "types" for your Item are known at compile time, you could use an enum like this:
public interface Item {
enum ItemType { MAIL, OTHER; }
public ItemType getType();
//some other methods
}

Techniques to expose multiple Interfaces (via static creation methods)

I am currently working on a project where I am attempting to hide as much detail about a hierarchy I have created as possible. I want to do this to minimize the amount of information the user needs to know about objects (and to control what they can do to the state of the object). In addition, I'm using the pattern to limit what kinds of objects the application can make, and limit it to creation from the factory.
The main issue I am having, however, is that there are a few different kinds of interfaces I would like to expose. Each interface is has additional functionality that I don't believe should be shared, and I would like to keep these interfaces separated. Finally, I don't know what new interfaces may come in the future, but I'd like to try and be ready for them.
Weapon:
public interface Weapon extends GameObject {
Number attack();
boolean addWeaponAttribute(WeaponAttribute attribute);
}
Firearm:
public interface Firearm extends Weapon {
void reload(Number rounds);
}
My question is what would be the best way to have the factory produce objects with different interfaces? Here's what I am thinking "the best would be":
The most clear to the user (it's obvious what they're asking for and what they're getting back)
The best for future expansion (I am uncertain what new interfaces I will be adding to this system).
Here's what I have been thinking so far:
Create properly named methods for each interface
public static Firearm getFirearm(String firearmName) {
...
}
public static Weapon getWeapon(String weaponName) {
...
}
Do the above, but produce the factories in separately named classes
public class WeaponFactory {
public static Weapon getWeapon(String weaponName) {
...
}
}
public class FirearmFactory {
public static Firearm getFirearm(String firearmName) {
...
}
}
Something completely different
I'm open to suggestions, and changes. This is a flexible project, so I can change as much as I want to (in terms of this portion of the project) to make a better result.
Also - As a side note, I was uncertain if this question was too open-ended or not for SO. If I made a mistake posting here, let me know and I'll move my question elsewhere.
What I can suggest is to make the interfaces as concise as possible and move other unrelated methods elsewhere. you might consider doing this for example:
public interface Weapon extends GameObject {
Number attack();
}
public interface Modifiable extends GameObject {
boolean addWeaponAttribute(WeaponAttribute attribute);
}
public class ActualWeapon implements Weapon, Modifiable {
...
}
Then you can create different factories to generate your concrete objects, as you already mentioned:
public class WeaponFactory {
public static Weapon getWeapon(String weaponName) {
...
}
}
or
public class GenericFactory<T extends GameObject> {
public T createGameObject(Object... properties) {
...
}
}
public class WeaponFactory extends GenericFactory<ActualWeapon> {
public ActualWeapon createGameObject(Object... properties) {
...
}
}
I think you can't add static methods to interfaces. I wouldn't recommend it if you even could.
maybe just use the factory method design pattern like
interface GameObject {}
class WeaponAttribute {}
interface Weapon extends GameObject {
Number attack();
boolean addWeaponAttribute(WeaponAttribute attribute);
}
interface Firearm extends Weapon {
void reload(Number rounds);
}
class WeaponBaseClass implements Weapon {
WeaponBaseClass(WeaponName weaponName) {
this.weaponName=weaponName;
}
#Override public Number attack() {
return null;
}
#Override public boolean addWeaponAttribute(WeaponAttribute attribute) {
return false;
}
public String toString() {
return weaponName.toString();
}
final WeaponName weaponName;
}
class FirearmBaseClass extends WeaponBaseClass implements Firearm {
public FirearmBaseClass(WeaponName weaponName) {
super(weaponName);
}
#Override public void reload(Number rounds) {}
}
enum WeaponName {
knife, sword, colt45, glock19, glock19WithLaser;
}
class WeaponCreator {
Weapon create(WeaponName weaponName) {
switch (weaponName) {
case knife:
case sword:
return new WeaponBaseClass(weaponName);
case colt45:
case glock19:
return new FirearmBaseClass(weaponName);
default:
return new WeaponBaseClass(weaponName);
}
}
}
class FancyWeaponCreator extends WeaponCreator {
Weapon create(WeaponName weaponName) {
Weapon weapon = null;
switch (weaponName) {
case glock19WithLaser:
weapon = super.create(WeaponName.glock19);
// whatever it needs
return weapon;
default:
return new WeaponBaseClass(weaponName);
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println(new WeaponCreator().create(WeaponName.knife));
System.out.println(new WeaponCreator().create(WeaponName.colt45));
System.out.println(new FancyWeaponCreator().create(WeaponName.glock19WithLaser));
}
}
What about a factory of factories? Each factory would implement ifactory. Ifacorty would require a method Instantiate(string type) and return your subclassed weapon instance.
Using generics, you might only need one factory method like:
public <T> T getObject(java.lang.Class<T> responseType, String name)
Then the user would call:
Weapon weapon = factory.getObject(Weapon.class, "my weapon");

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