Class that does things to another class - java

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.

Related

Java inheritance: multiple extends needed

I design my game application and face some troubles in OOP design.
I want to know some patterns which can help me, because java have not any multiple extends option. I will describe my problem below, and also explain why multiple interface doesn't help me at all. Lets go.
What we want is "class is set of features". By feature I mean construction like:
field a;
field b;
field c;
method m1(){
// use, and change fields a,b,c;
}
method m2(){
// use, and change fields a,b,c;
}
//etc
So, basically the feature is a set of methods and corresponding fields. So, it's very close to the java interface.
When I talk that class implemets "feature1" I mean that this class contains ALL "feature needed" fields, and have realisation of all feature related methods.
When class implements two features the tricky part begins. There is a change, that two different features contains similar fields (names of this fields are equal). Let the case of different types for such fields will be out of scope. What I want - is "feature naming tolerance" - so that if methodA() from feature A change the field "common_field", the methodB from feature B, that also use "common_field" as field will see this changes.
So, I want to create a set of features (basically interfaces) and their implementations. After this I want to create classes which will extends multiple features, without any copy-paste and other crap.
But I can't write this code in Java:
public static interface Feature1 {
public void method1();
}
public static interface Feature2 {
public void method2();
}
public static class Feature1Impl implements Feature1 {
int feature1Field;
int commonField;
#Override
public void method1() {
feature1Field += commonField;
commonField++;
}
}
public static class Feature2Impl implements Feature2 {
int feature2Field;
int commonField;
#Override
public void method2() {
commonField++;
}
}
public static class MyFeaturedClass extends Feature1Impl, Feature2Impl implements Feature1, Features2 {
}
So, as you can see the problem are really complex.
Below I'll describe why some standart approaches doesn't work here.
1) Use something like this:
public static class MyFeaturesClass implements Feature1,Feature2{
Feature1 feature1;
Feature2 feature2;
#Override
public void method2() {
feature2.method2();
}
#Override
public void method1() {
feature1.method1();
}
}
Ok, this is really nice approach - but it does not provide "feature field name tolerance" - so the call of method2 will not change the field "commonField" in object corresponding the feature1.
2) Use another design. For what sake you need such approach?
Ok. In my game there is a "unit" concept. A unit is MOVABLE and ALIVE object.
Movable objects has position, and move() method. Alive objects has hp and takeDamage() and die() methods.
There is only MOVABLE objects in my game, but this objects isn't alive.
Also, there is ALIVE objects in my game, but this objects isn't movable (buildings for example).
And when I realize the movable and alive as classes, that implements interfaces, I really don't know from what I should extends my Unit class. In both cases I will use copy-paste for this.
The example above is really simple, actually I need a lot of different features for different game mechanics. And I will have a lot of different objects with different properties.
What I actually tried is:
Map<Field,Object> fields;
So any object in my game has such Map, and to any object can be applied any method. The realization of method is just take needed fields from this map, do its job and change some of them. The problem of this approach is performance. First of all - I don't want to use Double and Interger classes for double and int fields, and second - I want to have a direct accsess to the fields of my objects (not through the map object).
Any suggestions?
PS. What I want as a result:
class A implements Feature1, Feature2, Feature3, Feature4, Feature5 {
// all features has corresponding FeatureNImpl implementations;
// features 1-2-3 has "shared" fields, feature 3-4 has, features 5-1 has.
// really fast implementation with "shared field tolerance" needed.
}
One possibility is to add another layer of interfaces. XXXProviderInterface could be defined for all possible common fields, that define a getter and setter for them.
A feature implementation class would require the needed providers in the constructor. All access to common fields are done through these references.
A concrete game object class implementation would implement the needed provider interfaces and feature interfaces. Through aggregation, it would add the feature implementations (with passing this as provider), and delegate the feature calls to them.
E.g.
public interface Feature1 {
void methodF1();
}
public interface Feature2 {
void methodF2();
}
public interface FieldAProvider {
int getA();
void setA(int a);
}
public class Feature1Impl implements Feature1 {
private FieldAProvider _a;
Feature1Impl(FieldAProvider a) {
_a = a;
}
void methodF1() {
_a.setA(_a.getA() * 2);
}
}
// Similar for Feature2Impl
public class GameObject implements Feature1, Feature2, FieldAProvider
{
int _fieldA;
Feature1 _f1;
Feature2 _f2;
GameObject() {
_f1 = new Feature1Impl(this);
_f2 = new Feature2Impl(this);
}
int getA() {
return _fieldA;
}
void setA(int a) {
_fieldA = a;
}
void methodF1() {
_f1.methodF1();
}
void methodF2() {
_f2.methodF2();
}
}
However, I don't think this is an optimal solution

Have a class be subclass for several super classes

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;
}
}

querying database in constructor (java)?

Is it a good practice to execute query in constructor?
class Foo {
public Foo() {
populateData();
}
private void populateData() {
// query database here...
}
}
Constructor only purpose is to create an instance of a class.
The issue with querying a database is the operation can fail.
At that point if you don't handle exception properly then your code is candidate for bugs.
You should think of constructor a way to prepare the object for use which should be quick.
If you want your code to be both legible and extensible, I can advise to consider the Single_responsibility_principle. According to it - every context (class, function, variable, etc.) should have a single responsibility, and that responsibility should be entirely encapsulated by the context. All its services should be narrowly aligned with that responsibility.
So bottom line is your method to be put to work like this:
public static class DbAccessor
{
public static void setPopulatedData() {
// query database here...
}
}
You could use lazy values. Google Guava provides some utilities to do that.
e.g.
class Foo {
private final Spplier<Data> data = Suppliers.memoize(new Supplier<Data>() {
public Data get() {
// query database here...
return data;
};
});
public Foo() {
}
}

Java: Two objects that use each other

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.

Accessing Field Variable from Generic Object

I have two classes, ClassOne and ClassTwo, that update a public field data i.e.,
public class ClassOne {
public byte[] data = new byte[10];
// Thread that updates data
}
and
public class ClassTwo {
public byte[] data = new byte[10];
// Thread that updates data
}
Only one class and its associated thread is running at any given time, i.e., the app detects the source of the data at run time and uses either ClassOne or ClassTwo. I want to parse the data in a separate class called ParseMyData, but a little confused as to the best way to set this up so ParseMyData can access data from either ClassOne or ClassTwo.
I'm currently trying to do it using generics, something like:
public class ParseMyData<T> {
T classOneOrClassTwo;
ParseMyData(T t) {
classOneOrClassTwo = t;
}
public void parseIt() {
// Need to access data from either ClassOne or ClassTwo here, something like:
classOneOrClassTwo.data; // this obviously doesn't work
}
So my question is how do I access the field data from within the class ParseMyData? Do I have to use reflection? Is reflection the only and best method to use?
New to generics and reflection, so thoughts and pointers greatly appreciated.
Create an interface DataProvider with a method getData() which returns your data field.
Then in your class ParseMyData<T> you will write instead ParseMyData<T extends DataProvider>.
public class ParseMyData<T extends DataProvider> {
T classOneOrClassTwo;
ParseMyData(T t) {
classOneOrClassTwo = t;
}
public void parseIt() {
classOneOrClassTwo.getData();
}
Alternatively you might also use your version, but do an instanceof check first and then cast to either ClassOne or ClassTwo. But I'd recommend you to go with the first option.

Categories