There's a problem I can't solve. I have simple part of code here:
public class Item{
Block blockDrop;
public void setBlockDrop(Block block) {
this.blockDrop = block;
}
}
public class Block{
Item itemDrop;
public void setItemDrop(Item item) {
this.itemDrop = item;
}
}
public class ItemDirt extends Item {
public ItemDirt() {
setBlockDrop(Registry.blockDirt);
}
}
public class BlockDirt extends Block {
public BlockDirt() {
setItemDrop(Registry.itemDirt);
}
}
public class Registry {
public static ItemDirt itemDirt = new ItemDirt();
public static BlockDirt blockDirt = new BlockDirt();
}
When I run this, blockDirt WILL drop itemDirt, but itemDirt WON'T drop blockDirt. Is there any way I can solve this? I could instead add to Registry constructor:
itemDirt.setBlockDrop(blockDirt);
blockDirt.setItemDrop(itemDirt);
but that defeats whole simplicity of my objects.
The problem is that when ItemDirt is constructed and assigned to Registry.itemDirt, its constructor already uses Registry.blockDirt, although it has not been initialized and is still null at that point of time.
This is a typcial problem that happens when objects try to prematurely grab alien objects at construction time. Usually, a constructor should never 'reach' outside and grab other objects that may or may not exist at that point of time.
There seems to be no pretty way to break your vicious circle without some visible alterations to your code, but maybe something like this will be less ugly:
public class Registry() {
public static ItemDirt itemDirt;
public static BlockDirt blockDirt;
static {
itemDirt = new ItemDirt();
blockDirt = new BlockDirt();
itemDirt.setBlockDrop(blockDirt);
}
}
Or some lazy initializations in your set methods. Your call.
It looks like you're trying to implement something similar to the Mediator Pattern, but the real way to do this is not in the constructor, because you cannot be assured of the order of construction.
Instead, when you implement a business method, you call a Mediator, which then handles the inter-class communication. Please read up on the Mediator Pattern before you go further, as it will provide some insight on how to do this better.
Related
I'm wondering what is the best/correct way to access methods from other classes in java.
I'll show how I'm doing it right now.
Sometimes like this:
public class DriverManager {
private final SeleniumDriverManager seleniumDriverManager;
public DriverManager() {
this.seleniumDriverManager = new SeleniumDriverManager();
}
public void startDriver() {
seleniumDriverManager.startWebDriver();
}
public void quitDriver() {
seleniumDriverManager.quitWebDriver();
}
}
and sometime like this
public class DriverManager {
private final SeleniumDriverManager seleniumDriverManager = new SeleniumDriverManager()
public void startDriver() {
seleniumDriverManager.startWebDriver();
}
public void quitDriver() {
seleniumDriverManager.quitWebDriver();
}
}
It's working in both cases, but is there any difference? Should I follow 1st or 2nd approach
There is no difference.
In the first one, seleniumDriverManager is initialized directly in the constructor via this.seleniumDriverManager = new SeleniumDriverManager();.
In the second one, seleniumDriverManager is initialized when the (generated) default no-arg constructor is called (similar to what happens in the first case).
Nevertheless, the best approach could be different:
public class DriverManager {
private final SeleniumDriverManager seleniumDriverManager;
public DriverManager(SeleniumDriverManager seleniumDriverManager) {
this.seleniumDriverManager = seleniumDriverManager;
}
public void startDriver() {
seleniumDriverManager.startWebDriver();
}
public void quitDriver() {
seleniumDriverManager.quitWebDriver();
}
}
In this case, you actually request the seleniumDriverManager to be passed in the constructor as an argument. This is one of the bases of Dependency Injection which relies on this approach of "asking" instead of (silently) providing. Dependency injection is actually the foundation of Frameworks such as Spring and has a huge amount of advantages. Still, this really depends on our use case, but keep this option in mind ;)
I facing a real hard problem in my code snippet.
I want to learn how to use Interface in Java the correct way.
So for this I have my Application-Class...
package inversionUsage;
public class Application {
public static void main(String [] args) {
String standard = "Standard version!";
if (FeatureDecisions.checkEnabledFeatures("new-feature1")) {
System.out.println("Implement new feature...");
}else {
System.out.println(standard);
}
}
}
Then I made a Interface...
package inversionUsage;
public interface AppConfiguration {
boolean isEnabled(String searchFeature);
}
I want to use the Interface in another class:
package inversionUsage;
import java.util.Arrays;
public class FeatureDecisions implements AppConfiguration{
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public static boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
if (Arrays.asList(_implNewFeature).contains(searchFeature)) {
return true;
}else {
return false;
}
}
private String [] fetchFeatureTogglesFromSomehere() {
// TODO get the CONFIG from somewhere
enabledFeatures = new String [2];
enabledFeatures[0] = "new-feature1";
enabledFeatures[1] = "new-feature2";
return enabledFeatures;
}
}
So the workflow is:
1. I start the Application
2. Main method checks the enabled features via FeatureDecisions.java
3. In Feature Decisions i implemented the Interface
I getting the error:
Cannot make a static reference to the non-static method isEnabled(String) from the type FeatureDecisions
May Someone can help me out?
The only way to use an instance method is to have an instance on which to call it. Your checkEnabledFeatures is static, so it doesn't receive an instance you can use (as this). To use an instance method, it would need to create an instance. But obviously that's not what you want here.
Java's interface construct is for defining the interface that instances implement. Java doesn't have the concept of a "static interface" that a class must implement. On the rare occasions when that's needed, it's usually implemented using reflection (perhaps with a class-level annotation to indicate that the class has the necessary feature).
You would have to instantiate the FeatureDecisions class.
public static boolean checkEnabledFeatures(String searchFeature) {
return new FeatureDecisions().isEnabled(searchFeature);
}
or make all members static.
Additional info: There are frameworks like togglz that do this for you.
There's no way to do that. The closest can get is to use the singleton pattern (though lots of people - myself included - would discourage it).
public enum FeatureDecisions implements AppConfiguration
{
INSTANCE;
public String [] enabledFeatures;
public String [] _implNewFeature = fetchFeatureTogglesFromSomehere();
public boolean checkEnabledFeatures(String searchFeature) {
return isEnabled(searchFeature);
}
#Override
public boolean isEnabled(String searchFeature) {
//...
}
}
Your call would then change from:
FeatureDecisions.checkEnabledFeatures(...)
to
FeatureDecisions.INSTANCE.checkEnabledFeatures(...)
It's also worth noting that checkEnabledFeatures doesn't actually do anything besides defer to isEnabled. You could scrap the former and just call the latter directly.
I am trying to figure out if generics would be a better way to do what I'm trying to accomplish below (or some other way) instead of using reflection (which I currently have working just fine, but don't like it...).
I have a class library I'm using that is roughly like the following:
abstract class base<T>{
public boolean method1 (String who) {
System.out.println(who+":s");
return true;
}
public T method2 (String who) {
System.out.println(who+":d");
// The following gives me an unchecked cast warning. I can't figure out
// the proper way to fix that either, but it works, so I've moved on...
// In the main program, it's this: obj = (T) in.readObject();
// basically deserializing the object from disk.
return (T) new Object();
}
public abstract void load();
}
class Api1 extends base{
#Override
public void load(){
System.out.println("api1:load()");
}
}
class Api2 extends base{
#Override
public void load(){
System.out.println("api2:load()");
}
}
I am trying to wrap the above class library using the code below... This is what I cannot figure out how to do. The objects that are passed to init() have the same methods (method1(), method2() and load()). I don't want to write init() for each class type, instead, I just want to write it once, then have the compiler handle the details.
UPDATE: There are currently 6 classes that are derived from Base (with a few more likely). In the wrapper, I'm just trying to simplify access to the underlying APIs by handling various housekeeping chores automatically. In the init() method, I need to be able to call the methods of those underlying objects (based on Api1, Api2, ...), without using reflection, or without writing duplicate code for each class, or getting a bunch of unchecked warnings and/or casting...
class ApiWrapper<T>{
// would like to return the type passed in if that's doable
// e.g. public T init(T t)
public void init(T t){
System.out.println("inside init: "+t.getClass().toString());
//t.method1(t.getClass().toString());
//t.method2(t.getClass().toString());
//t.load();
}
}
class api1Wrap extends ApiWrapper {
Api1 api = new Api1();
public api1Wrap(){
init(api);
}
}
class api2Wrap extends ApiWrapper {
Api2 api = new Api2();
public api2Wrap(){
init(api);
}
}
public class GenericApiWrapper {
private final api1Wrap api1;
private final api2Wrap api2;
public GenericApiWrapper() {
this.api1 = new api1Wrap();
this.api2 = new api2Wrap();
}
}
From a main() somewhere ...
GenericApiWrapper gaw = new GenericApiWrapper();
It feels to me like generics are the right approach for this type of thing, but I've been trying all sorts of combinations, and reviewing various articles and examples, but I just can't seem to figure out the proper approach. If this has already been asked and answered, please point me to it. I can't seem to find it, probably because I'm not sure how to describe what I'm trying to do. :) I've been looking at the Java Generics FAQ as well, but I haven't found what I'm looking for... Thanks in advance!
In generics you should specify the type you want to use, in this case you replace the T with for example Api1 otherwise the compiler uses Object:
class api1Wrap extends ApiWrapper<Api1> {
Api1 api = new Api1();
public api1Wrap(){
init(api);
}
}
Also you could improve your code by simple implementing one single class and creating several instances with different types, this is the idea behind generics.
UPDATE:
If you also specify that T extends base, then the compiler is able to find the methods.
Take a look at this:
class ApiWrapper<K, T extends base<K>>{
private T t;
public ApiWrapper(T t){
this.t = t;
}
public void wrap(){
init(t)
}
private void init(T t){
t.method1("hello");
K k = t.method2("world");
}
}
ApiWrapper<Object, Api1> apiWrapper1 = new ApiWrapper<>(new Api1());
I have a class that is essentially a wrapper for a large data object on a database. Looks like this:
public class ServerWrapper {
private DataObject object;
public ServerWrapper(DataObject object) {
this.object = object;
}
public void doAThing1() {
getSomeStuff();
// do stuff that modifies this object
}
public void doAThing2() {
getSomeStuff();
// do other stuff that modifies this object
}
private List<> getSomeStuff();
}
This is the problem: there are many, many "doAThing" methods. And some of them are quite large. Also, a lot of them use other private methods also in ServerWrapper. Ideally, I'd like to break off these public methods into their own classes, like ThingDoer1, ThingDoer2, but I don't know the best way to do this.
Something like this:
public class ThingDoer1{
public void doAThing1(ServerWrapper wrapper) {
wrapper.getSomeStuff();
// do the thing to wrapper
}
seems very smelly; it's tightly coupled to ServerWrapper (ServerWrapper calls it and it calls ServerWrapper), plus it needs to either do stuff with the object it's given (which is bad), or make a copy, do the stuff, then return the copy.
Really, I think what I'm looking for is a set of partial classes, just to make this monster of a class more manageable; but I'm using Java, which doesn't support that.
Is there some standard practice for breaking down a large class like this? Thanks in advance!
EDIT:
The point of the wrapper is to add server-side functionality to a database object. For example, this object needs to be "expired". What this requires is getting all the associations to the database table, then doing several validations on the object and those associations, then setting a bunch of fields in the object and its associations, then calling a database update on the object and all those associations. Having all that code inside the ServerWrapper makes sense to me, but there are several fairly complex operations like that the need to happen, so the class itself is getting rather large.
But it doesn't need to be tightly coupled with ServerWrapper:
public class ThingDoer1() {
public void doAThing1(List<> theList) {
// do the thing to object
}
Then in ServerWrapper:
public void doAThing1() {
new ThingDoer1().doAThing1(getSomeStuff());
}
I'd go further maybe:
public class ThingDoer1() {
private final List<> theList;
public ThingDoer1(List<> theList) {
this.theList = theList;
}
public void doAThing() {
// do the thing to object
}
}
In ServerWrapper:
public void doAThing1() {
new ThingDoer1(getSomeStuff()).doAThing();
}
Which is more of a Replace Method with Method Object refactor.
There are several (5+) classes, in code I cannot change, that I need to extend by a few fields. Is there any way to do this without writing (and editing every time I need to change something) the almost exactly same code 5 times? So is there any more elegant way than this:
class Subclass1 extends Superclass1 {
private String newField;
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
class Subclass2 extends Superclass2 {
private String newField;
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
//...
I do NOT want multiple inheritance, I want 5 seperate subclasses - just without the duplicate code, because the subclasses all add exactly the same.
The only alternative I can think of is copying the original classes and having the copy extend a Superclass which is probably even worse.
No, you can't do this in Java. You can in certain other JVM-based languages, such as Scala (traits). However, if you must use plain Java, you might consider the following:
Determine the (hopefully single) purpose of the fields you are adding, and the behavior that you want.
Create a new class encompassing all of the fields and the new methods. For example:
public class ExtraFields // Don't use this name!
{
private String myExtraField1;
private String myExtraField2;
// etc.
public void doSomethingWithExtraFields() {
// etc.
}
}
Then, you could take one of the following approaches:
Subclass each of the five classes, and add one field, which is an instance of the class you created above, and delegate behavior accordingly. You will have to use this approach if you must have the extra fields in places where you must pass in one of your five classes. For example:
public class Subclass1 extends Superclass1
{
private ExtraFields extraFields;
public MySubclass()
{
super();
extraFields = new ExtraFields();
}
public void doSomethingWithExtraFields()
{
extraFields.doSomethingWithExtraFields();
}
}
Create a new wrapper class that contains an instance of both your new class created above, and one of those five subclasses. You can make this typesafe using generics. For example:
public class Wrapper<T> // Don't use this name either...
{
private ExtraFields extraFields;
private T myClass;
public Wrapper(T myClass) {
this.myClass = myClass;
this.extraFields = new ExtraFields();
}
}
In this second approach, you don't strictly need the ExtraFields class. But it's still often a good idea to do this so as to encapsulate related functionality.
Hope that helps!
Since you can't change the base classes, it's impossible to eliminate the redundancy. Eric Galluzzo's idea to store the extra fields in a separate class is the best one so far, but I don't know if that's practical in your case. If it isn't, create an interface that defines the extra fields. You'll still have to do a lot of repetitive typing, but at least you'll know immediately when you've made a mistake.
You could use a generic wrapper class, as long as it wouldn't be too tedious to change the rest of the code that works with it.
class Wrapper<E> {
private E obj;
private String newField;
public Wrapper (E obj) {
this.obj = obj;
}
public E get() {
return obj;
}
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}