Building complex object inside or outside the class in Java? - java

I am trying to get the best practice in Java to solve the following problem :
I want to setup an complex object in one place, so that other clients can then reuse this construction. Here is an example and how I proceed :
My complex object is of type "Ontology", this object contains many parameters, once it is instantiated and filled, it is used in many objects as a kind of configuration by using its getter.
My Ontology.class
abstract class Ontology {
List<Something1> param1;
List<Something2> param2;
...
protected void addParam1(){
...
}
....
abstract protected void setup();
}
A way to hold the complex construction :
public class SpecificOntology extend Ontology{
#Override
protected void setup(){
addParam1(new Something(...));
...
}
}
A client :
protected void something(){
SpecificOntology o = new SpecificOntology();
o.setup();
install(o.getParam1(());
...
}
Another solution could be to make Ontology not abstract, make its Adder public and build the object outside of the class, but I don't know which pattern could be used for that ? I know the builder pattern and the factory pattern but I am not sure this is the right place for that. Any idea ?

If you want to build an object with many parameters, the first thing I would think of is the Builder pattern.

Related

Is using method reference bad for performance?

I need to build my own library to handle events coming from an event bus, the first solution I came up with was an abstract class made like this one:
public abstract class MyEventListener<T> extends RealEventListener{
private final Class<T> type; //the event class type
private final String stream; //the stream
public abstract onEvent(T type); //the method my subclasses have to implement
#Overrides
public void onEvent(byte[] evt){ //takes the original, clunky method and evolves it with typing
//convert and do stuff
onEvent(convertedEvent); //call method
}
}
so, the classes only do:
#Component
public class Child extends MyEventListener<AType>{
public Child(){
super(AType.class, "stream"); //registers
}
#Overrides
public void onMessage(AType evt){ //do stuff
}
I find this approach somewhat limiting and outdated (at least seeing the latest libraries). An example I can think of is that, this way, you are forced to handle separate events in separate classes.
So, I though of using annotations to have something like this:
#EventListener("stream") //1. you define the stream in this custom class annotation
public class Child { //so no need to extend
#ListenTo(type=AType.class) //2. you define the type on methods, this way a single class can handle more
public void onMessage(AType event, //any other param){
}
Now, for the magic behind, I though about using a startup annotation processing to retrieve the methods:
public void initialize(#EventListener List<Object> listeners) { //I inject all objects
listeners.stream().map(..).collect(..) //use reflection to get all methods annotated with #ListenTo and put them inside of map <String, Method>
eventBus.registerListener(new MyEventListener(target, methodMap)); //
}
Now, the listener will take somewhat the type from the original byte event and call the method:
String className = getClassFromEvent(evt);
listenerMap.get(className).invoke(target, evt);
According to you is this approach valid and, most importantly, efficient? Or, excluding the initialization phase, it could lead to performance problems at runtime? Of course I should make static checks at initialization to make sure that the annotated methods declare the event as parameter but it seems cleaner to me than the first one.

How to inherit fields properly without making them open to the package?

Say, I have a package Pack containing classes A and B. A is self-contained and no one (even in the Pack) should see A's insides, so most of the fields and methods are private.
Now I want to extend A to change one of its private methods keeping the rest - let it be class AMod. Doing it requires most of A's fields and the method to override to be protected, but protected gives access to the package.
So how do I create AMod inside Pack so that AMod has an access to A's fields and methods while no one else does? Make a nested/separate package?
UPD:
UPD2:
UPD3:
As Jacob G. suggested, my code needed redesigning, and I managed to remove the derived class from the architecture. Thanks for help!
The one answer I find missing: don't be so focused on using inheritance in order to avoid code duplication.
If you only need a subtle variation of behavior of A then you should first consider to "wrap" around A (for example via decorator) instead of extending A - the good old FCoI!
If that isn't possible: have a very close look at the common behavior of A and Amod and extract those parts in a common base class.
Finally: don't get too energetic about java access modifiers in the first place. In the end, they help you to communicate a certain thought or idea. "Evil-willing" people will always find a way to work around your intentions. What I am saying is: if you are concerned that your team members use your class in the wrong way ... that is a social problem; and you will never be able to solve that on the technical layer. You have to solve it on the social layer, too (by educating people to ensure that they understand what to do; instead of hoping that private here or protected there will prevent them from doing the wrong thing).
In other words: establish a simple policy such as "only what is marked public is meant to be public; anything else is not" might be able to table such discussions for all times. Versus spending hours and hours to find a perfect private-protected solution within source code.
Thanks for posting code.
My advice would be to first move B#stepBMod into A.java. Then, you can pass a boolean parameter to A#build; with this, you can rewrite A#build:
public Result build(boolean mod) {
stepA();
if (mod) {
stepBMod();
} else {
stepB();
}
stepC();
return result;
}
Now, B.java isn't needed anymore.
Your question is two parts. 1)Accessing fields and 2)Accessing methods.
Case1), you should make class A's fields protected. This means no one can access it by name, except derived classes.
Case2), you cannot access a protected method by name, unless in a derived class. But still you can access a protected method by name using an object of A. In order to prevent other classes making objects, your A class should be abstract.
Here is an example
public abstract class A{
protected int n;
protected void display(){
System.out.println(n);
}
}
public class B extends A{
public void demo(){
B object = new B();
object.display();
}
public void modify(){
n = 0;
}
}
Update
class A
{
public A(Args args){...}
public Result build() {
stepA();
stepB();
stepC();
return result;
}
protected void stepA() {...}
private void stepB() {...}
protected void stepC() {...}
protected T field;
}
class AMod extends A
{
public AMod(Args args){
super(args);
...
}
public Result build() {
stepA();
stepBMod();
stepC();
return result;
}
private void stepBMod() {...}
}

Partial overriding of a method: how to?

I'm implementing a service class having a method like this:
public void makeSomething() {
// some logic...
// [optional logic]
// some other logic...
}
This is a concrete class and it can be instantiated and used "as is", but I somethimes need to extend it and override the makeSomething() method adding some additional logic (in the middle). I mean: I need to use the same logic in parent method, but i need to extend logic before return.
My first idea was to add an "optional" method in the middle of the original method:
public void makeSomething() {
// some logic...
optionalOperation();
// some other logic...
}
and eventually override the optionalOperation() method in extending classes. But I don't like this: I will have an empty method doing nothing in my original class...
So, is there a better way to design my method? Is there some design pattern addressing my issue?
The design pattern is called Template method and it works exactly the way you don't like, I'm afraid.
For example, Spring's code is full of such empty protected methods waiting for you to add something custom into them.
i can think of 2 ways:
inheritance and common 'lifecycle' aka Template Method. it's very problematic to maintain when it's in the middle of your business logic
strategy pattern. try to refactor and pass strategy to the method or object owning this method. if you can use any functional language you can take it to the extreme and instead of passing strategy use a function composition: define 'makeSomething' as a function of other functions. and one of 'makeSomething' will contain also 'optionalOperation' in it's definition. but it may require really heavy refactoring
A simple solution would be this:
public class AClass {
public void makeSomething() {
someLogic();
someOtherLogic();
}
protected void someLogic() {
System.out.println("some logic");
}
protected void someOtherLogic() {
System.out.println("some other logic");
}
}
public class AnEnhancedClass extends AClass {
#Override
public void makeSomething() {
someLogic();
System.out.println("optional operation");
someOtherLogic();
}
}

Which Design Pattern can I use?

I like to realize the following scenario. (example)
I have 3 Classes:
Controller
Apple
Car
public class Apple implements IBonus {
public String name;
public String weight;
}
public class Car implements IBonus{
public String brand;
public String vmax;
public String power;
}
public class Controller {
public List<String> values;
public void doWork(IBonus bonusObject){
if(bonusObject instanceOf Car){
Car c = (Car)bonusObject;
values.add(c.brand);
values.add(c.vmax);
values.add(c.power);
}
if(bonusObject instanceOf Apple){
Apple a = (Apple)bonusObject;
values.add(a.name);
values.add(a.weight);
}
}
}
Now, I have a lot of Classes like apple and car. And there is also the possibility that some variables of each class will be changed, added or removed in the near future.
This will mean that I always have to adjust the code in the controller class.
Does anyone know a suitable pattern?
You don't need any pattern for this. Just plain old polymorphism:
public interface IBonus {
void fillStringList(List<String> values);
}
...
public void doWork(IBonus bonusObject){
bonusObject.fillStringList(values);
}
EDIT: Design pattern "Visitor".
Change your iBonus interface to add a method:
void add(List<String> values);
Have the Controller instead do
bonusObject.add(values);
This way you delegate the specific task (adding an object to 'values') to the specific implementation.
Basically whenever you find yourself writing code like the above (if instanceof or switch()) you should instead consider delegating the task to an abstract method.
You may want to consider "double dispatch" aka. "Visitor"
http://en.wikipedia.org/wiki/Visitor_pattern
The Wikipedia version is very generic, and splits out the "Visitor" logic (adding to the list) into a seperate class. In the below version the "Bonus" objects play that part, and the double dispatch structure is used instead.
In that scenario you have two interfaces: One for the bonus object, and one for the controller. The bonus object has a method called
void visit(Controller c);
The controller will then invoke the bonus object thus:
bonusObjecv.visit(this);
The purpose of "Visitor" is largely to let you vary the implementations independant of each other. It is a more generic version of the simple, polymorphic solution. Instead of using a generic class such as List you use the Controller interface. That way you make the interaction between controller and visited object explicit.
You could add a method:
public List<String> getValues();
to your IBonus interface and just use the following in doWork:
values.addAll(bonusObject.getValues());
Each IBonus type will then need to implement how to create the list.
I think Factory pattern will suit in this condition.
Factory pattern Example

Java - Is delegation the good solution in this case?

Here is my question :
I have a huge class (HugeClass) and I wanted to split it into several little classes (LittleClass1, LittleClass2, ...). I heard about delegation. It sounds good, but I think it cannot works in my case.
Indeed, my little classes need some of the attributes of HugeClass:
public class HugeClass
{
// Attributes
private Object object1;
private Object object2;
private Object object3;
...
private Object objectN;
// Delegation 1
private LittleClass1 little1 = new LittleClass1 ();
// Function delegated in the LittleClass1
public void delegated1 ()
{
little1.delegated1 ();
}
}
Here an example of a Delegation class :
public class LittleClass1
{
public LittleClass1 ()
{
}
public void delegated1 ()
{
// Here, I need object1, object3, and more to work !
}
}
The number of attributes needed by the delegated1 function can be large. So I think using the constructor of LittleClass1 is not very convenient.
And because LittleClass1 override only one method of HugeClass, I don't think that LittleClass1 should extends HugeClass.
Do you have an idea of a solution ? Using another pattern ?
Thanks !
Update
Delegated functions might need not only instance variables, but also instance functions :
public class LittleClass2
{
public LittleClass2 ()
{
}
public void delegated2 ()
{
// I need object2 and delegated1 to work !
}
}
Giving HugeClass to the constructor might solve this problem. But is this a good solution ?
Breaking up a huge class into smaller classes is generally good to improve the maintainability, testability and overall quality of the code. The smaller chunks should be easier to reason about in isolation. What you want is to look for semantically distinct features of the huge class, and split them apart, first by extracting methods, and then by extracting classes. You're not necessarily looking for a pattern, as much as looking for refactoring techniques, like the ones in the books Refactoring and Working Effectively with Legacy Code.
Now, if your little classes seem to share too many of the instance variables of the huge class, maybe you should take a step back and start with some low hanging fruits, like code that doesn't depend on too many variables; or try to find a grouping of those variables that semantically make sense to be encapsulated in a new object, what would decrease the number of these free variables and increase the quality of the design, as finding the latent concepts in the design make the code more explicit and understandable.
UPDATE: by the way, inheritance is really not a good idea. You want to decouple the concerns, and inheritance is just another more subtle way of coupling.
Looks like you just need LittleClass1 to subclass HugeClass, and its fields protected:
public abstract class HugeClass {
// Attributes - now protected instead of private
protected Object object1;
protected Object object2;
protected Object object3;
...
protected Object objectN;
-- Note: No delegation, no reference to LittleClass1 here
public abstract void delegated ()
}
public class LittleClass1 extends HugeClass {
public void delegated () {
// Here, you have access to object1, object2 etc
}
}

Categories

Resources