better modeling design java - java

I have to supply a class by another with regulatory management.
I suppose these two classes:
Class A:
public class A {
private String attributeA1;
...
private String attributeA50;
...
// getters and setters
}
Class B:
public class B {
private String attributeB1;
...
private String attributeB50;
...
// getters and setters
}
Each attribute from Class A will supply attribute from B.
Exemple:
public Class Supplying {
public B elementB;
public A elementA;
public void supplyAttributeB1( String toto){
String tata = elementA.getattributeA1();
// Example of regulatory management "Substring"
elementB.setAttributeB1(tata.substring(5));
}
public void supplyAttributeB2(String toto){
...
}
...
public void supplyAttributeB50(String toto){
...
}
}
When I see my code, it's not very pretty, I think I have a modeling problem because the class supplying will have over 150 lines of code.
Is there another way to make this concept by using interface or inheritance or a design pattern? I'm trying to learn how to code better.

If your operations fall into some broad categories, you can use the Strategy pattern:
public interface DataConverter<F,T> {
public T convert( F from );
}
public class SubstringConverter implements DataConverter<String,String> {
private final int start;
public SubstringConverter( int start ) { this.start = start; }
public String convert( String from ) {
return from.substring( start );
}
}
And in your supplying class
public class Supplying {
private static final DataConverter<String,String> b1Converter = new SubstringConverter( 5 );
// and so on ...
public void supplyAttributeB1() {
elementB.setAttributeB1( b1Converter.convert( elementA.getAttributeA1() ) );
}
}
This will make it easy to change the logic (so long as field Ax always converts into field Bx, all you need is plug in a new converter), and easy to see what's going on.
This is about as far as you can go without building a full-size data conversion framework, where you'll probably use reflection to access the fields and have external config files to drive the mapping between entities.

Related

Is there a specific way to give a certain subclass some functions of the superclass?

The Problem
I'm trying to create an application where an object class can implement some
operations from the total pool of available operations. The end goal is to not have any code duplication and to abide by the laws of OOP as much as possible.
In more detail, I'm trying to make a search engine using Lucene. Lucene
uses many indices. I've already implemented a simple structure where different index-objects inherit the methods of a parent class. The problem is that, whatever method is implemented in that parent class, it automatically becomes available for all subclasses to use. I want to give the option to the user to determine if he wants to do a phrase search, a term search or whatever else there is available for that specific index. The catch is, some indices shouldn't have the option to conduct phrase search, for example.
First Thoughts
I've thought of implementing something close to the Composite pattern,
as described by the GoF. I would implement the search operations (e.g. term search, phrase search) as primitive operations implementing some Component class and add these primitive objects later on to a Composite object. The Composite object will be implementing the same Component class as the primitives.
public abstract class Index {
public Index(String indexPath) {
// Constructor using the information provided by the subclass
}
public void phraseSearch(...) {
// Do the operation
}
public void termSearch(...) {
// Do the operation
}
public void categorySearch(...) {
// Do the operation
}
}
public class ReviewIndex extends Index {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends Index {
public TipIndex() {
super("./tip_index/");
}
}
Expected Outcome
The class ReviewIndex shouldn't be able to perform a categorySearch but be
able to execute phraseSearch and termSearch. Respectively, the TipIndex class
should be able to execute some of the parent class methods.
Final Thoughts
I know that in my solution there is no code duplication but there
are useless methods being generated each time a new index object is created.
Thank you all in advance!
P.S. If you think the Composite pattern is the way to go, in which way would you actually add the primitive objects to the composite class and in which way would you invoke them when need to?
All methods defined in a superclass are available at deriving classes but with Java 8 you might be able to get something like this by using default-methods in interfaces. So instead of one abstract class containing all possible methods you might implement four interfaces
public interface Searchable {
public String getIndexPath();
}
public interface PhraseSearchable extends Searchable {
public default void phraseSearch() {
String indexPath = getIndexPath();
// do the search
}
}
public interface TermSearchable extends Searchable {
public default void termSearch() {
String indexPath = getIndexPath();
// do the search
}
}
public interface CategorySearchable extends Searchable {
public default void categorySearch() {
String indexPath = getIndexPath();
// do the search
}
}
To avoid duplicate code you can create an abstract class
public abstract class AbstractSearchable implements Searchable {
private String indexPath;
public AbstractSearchable(String indexPath) {
this.indexPath = indexPath;
}
// other methods that might be useful
}
Your actual classes can then implement the corresponding interfaces
public class ReviewIndex extends AbstractSearchable implements CategorySearchable {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends AbstractSearchable implements PhraseSearchable, TermSearchable {
public ReviewIndex() {
super("./review_index/");
}
}
If this is possible depends heavily on the actual implementation of the search methods. Interfaces can't contain any members, etc. so these methods must be able to run for themselves (like a static method without using any static members of the class). You might to overcome this problem by adding more methods to the Searchable interface that provide the data and do the implementation in the abstract class but that might expose internal stuff to the public because all the declared methods in an interface are public.
If you don't want to use categorySearch(...) for ReviewIndex class then create one more hierarchy where you keep the categorySearch(...) method.
Example:
public abstract class Index {
public Index(String indexPath) {
// Constructor using the information provided by the subclass
}
public void phraseSearch(...) {
// Do the operation
}
}
// Give a meaningful Name
public abstract class IndexChild1 extends Index {
public void categorySearch(...) {
// Do the operation
}
}
// Give a meaningful Name
public abstract class IndexChild2 extends Index {
public void termSearch(...) {
// Do the operation
}
}
public class ReviewIndex extends IndexChild1 {
public ReviewIndex() {
super("./review_index/");
}
}
public class TipIndex extends IndexChild2 {
public TipIndex() {
super("./review_index/");
}
}
You can use Composite pattern if you need to have the same objects and use them as you wish in your ReviewIndex and TipIndex classes. you can use a list which implies aggregation and you can use one instantiation of each object(PhraseSeach, TermSearch, CategorySearch) in any order you want.
here is the code:
import java.util.ArrayList;
import java.util.List;
public class Main{
public static void main(String[] args) {
Main m = new Main();
m.run();
}
public void run() {
ReviewIndex ri = new ReviewIndex();
}
public interface ISearch {
public void search();
}
public class SearchComposite implements ISearch{
private List<ISearch> l = new ArrayList<ISearch>();
public SearchComposite(String index) {
System.out.println(index);
}
public int addSearch(ISearch search) {
l.add(search);
return this.l.size() - 1;
}
public List<ISearch> getSearch(){
return this.l;
}
public void search() {
System.out.println("search");
}
}
public class CategorySearch implements ISearch{
#Override
public void search() {
System.out.println("category search");
}
}
public class PhraseSearch implements ISearch{
#Override
public void search() {
System.out.println("phrase search");
}
}
public class TermSearch implements ISearch{
#Override
public void search() {
System.out.println("term search");
}
}
CategorySearch cs = new CategorySearch();
TermSearch ts = new TermSearch();
PhraseSearch ps = new PhraseSearch();
public class ReviewIndex {
SearchComposite sc = new SearchComposite("./review_index/");
public ReviewIndex() {
int p = sc.addSearch(ps);
int t = sc.addSearch(ts);
sc.search();
List<ISearch> s = sc.getSearch();
s.get(p).search();
s.get(t).search();
}
}
public class TipIndex {
SearchComposite sc = new SearchComposite("./tip_index/");
public TipIndex() {
int p = sc.addSearch(ps);
int t = sc.addSearch(ts);
int c = sc.addSearch(cs);
sc.search();
List<ISearch> s = sc.getSearch();
s.get(p).search();
s.get(t).search();
s.get(c).search();
}
}
}
the output of the code above is:
./review_index/
search
phrase search
term search
and we have used the same CategorySearch, TermSearch and PhraseSearch for ReviewIndex and TipIndex classes.

How to pass constants to a method?

I have this classes:
package util;
public final class Constant {
private Constant() {
throw new AssertionError();
}
public static class Product {
public static final String CODE = "Product";
public static final String A = "product_5g2g";
public static final String B = "product_a45h";
public static final String C = "product_a3ag";
//more constants..
}
public static class Employee {
public static final String CODE = "Employee";
public static final String A = "employee_1g3f";
public static final String B = "employee_h52d";
public static final String C = "employee_h5d2";
//more constants..
}
public static class Client {
public static final String CODE = "Client";
public static final String A = "client_h5ad";
public static final String B = "client_1df1";
public static final String C = "client_6g23";
//more constants..
}
}
and:
package util;
import util.Constant.*;
public class Main {
public void run() {
if (isSelected(Product.CODE)) {
if (isSelected(Product.A) || isSelected(Product.B)) {
//do something
}
compute(Product.C);
//more similar instruction that use constants from Product class
}
if (isSelected(Employee.CODE)) {
if (isSelected(Employee.A) || isSelected(Employee.B)) {
//do something
}
compute(Employee.C);
//more similar instruction that use constants from Employee class
}
if (isSelected(Client.CODE)) {
if (isSelected(Client.A) || isSelected(Client.B)) {
//do something
}
compute(Client.C);
//more similar instruction that use constants from Client class
}
}
public boolean isSelected(String s) {
return true;
}
public void compute(String s) {
}
}
As you can see, this block of code
if (isSelected(StaticClass.CODE)) {
if (isSelected(StaticClass.A) || isSelected(StaticClass.B)) {
//do something
}
compute(StaticClass.C);
//more similar instruction that use constants from Product class
}
is repetitive, but can't put it in a separate method because java don't permit a static class as a parameter public void method(StaticClass) {}.
How can I refactor the above code? My first thought was to make Singletons that extend a base class, or implement an common interface. There is a better solution?
You should look into using polymorphism here. Example: instead of doing
if (X) {
doY();
}
"good" OO looks much more like:
Y y = getMeSomeY();
y.doTheY();
Where getMeSomeY() returns you exactly that what is required (so Y could be an interface; and that method provides different implementations of that interface which all do slightly different things).
The point is: you wrote procedural code, where you ask something, to then make a decision about it. Good OO favors the opposite (called tell don't ask).
You start by ... not making everything flat strings. By doing so, you give up on the whole "static typing" thing. If your code is making decisions only on strings, why are you programming in Java? You can very well use a non-typed language than. So, at least learn about Java enums; and use those. But please understand: enums are not the real answer here. They would just help to make your code a bit better.
The real problem here is that you want to write code doing these if (x) then y all over the place.
You might have guessed by now: there is no easy answer here. What I would do: first, step back. And have a in-depth look into your design. The code you have right now indicates to me that your underlying object model is far from "helpful". And that is the whole point of OO: you create classes and objects that help you to write clean, elegant code. But when your base design isn't supporting that; then there is no point in trying to refactor the code that came out of that. Because the ugliness of your code is just a symptom; the root cause lies in your design underneath.
What you are looking for is an Enum. Redefine all your classes as Enums instead. For example, you can redfine the Product class as follows :
public enum Product {
CODE("Product"),
A("product_5g2g");
private String value;
//define others constants in a similar fasion
public Product(String value) {
this.value = value;
}
}
Enums can be passed as method parameters. In your particular example, you can do this :
public void method(Constants.Product product) {
}
That said, you should definitely look into an alternative way to achieve your objective. Take a look at Replacing conditionals with Polymorphism for starters.

Make several classes have the same attributes without inheritance

I'm facing a problem in Java.
I need to have several classes with the same attributes ( for example a Position and a boolean isWalkable ).
But I don't want these classes to inherit from a class Element because that would prevent me from using inheritance later.
I thought of an interface (so that the interface has the attributes), but apparently you can't have an interface inherit from a class.
There must be a way because otherwise I would have to copy/paste my attributes and there methods.
Thanks in advance for anyone who has an idea on how to overcome this problem.
For this, I would consider composition over inheritance.
public class Main {
public static void main(String[] args) {
AgentWrapper agentWrapper = new AgentWrapper(new Agent1(), false, 1);
System.out.println("isWalkable: " + agentWrapper.isWalkable());
System.out.println("position: " + agentWrapper.getPosition());
agentWrapper.getAgent().doSomething();
}
}
interface Agent {
void doSomething();
}
class Agent1 implements Agent {
public void doSomething() {
System.out.println("Agent1");
}
}
class Agent2 implements Agent {
public void doSomething() {
System.out.println("Agent1");
}
}
class AgentWrapper {
private final Agent agent; //Wrapped instance.
private final boolean isWalkable;
private final int position;
public AgentWrapper(Agent agent, boolean isWalkable, int position) {
this.agent = agent;
this.isWalkable = isWalkable;
this.position = position;
}
public Agent getAgent() {
return agent;
}
public boolean isWalkable() {
return isWalkable;
}
I suspect you might need an interface anyway, if you want to treat your objects generically - e.g. loop over all of them and draw each one. E.g. assuming your elements include "cats" and "houses":
interface Element{
public point getPosition();
public boolean isWalkable();
}
class Cat implements Element{
private Point position;
private String catBreed; // example of cat-specific data
public point getPosition() {return position;}
public boolean isWalkable() {return true;} // cats can walk
...
}
class House implements Element{
private Point position;
private String streetAddress; // example of house-specific data
public point getPosition() {return position;}
public boolean isWalkable() {return false;} // houses cannot walk
..
}
// Finally, using that common interface:
Element[] allGameObjects= {new Cat(...), new Cat(...), new House(...) };
for(Element e:allGameObjects)
draw(e, e.getPosition());
That was good enough for several system I wrote... but as other replies correctly mentioned, you might refactor to use composition - however it might not be a 100% clear-cut. I mean, I can understand if you feel Cat or House should be managed independently from their position... but what about isWalkable?
// Position is easy to separate:
class Cat { String catBreed; ... }
class House{ String streetAddress; ... }
class ElementWrapper implements Element{
Point position;
Object theObject; // could hold Cat or House
public Point getPosition() {return position;}
// however, isWalkable is a bit tricky... see remark below
}
But 'isWalkable' is tricky because in classic polymorphism you'd expect House/Cat to tell you whether they can walk (meaning they should implement an interface anyway). If you absolutely don't want (or cant) have it, you may compromise on polymorphism and do something in the lines of instanceof (if theObject is instanceof Cat then it can walk, if it's instanceof House it cannot walk, etc).
You can extend an abstract base class(containing nothing) or You can use the Decorator pattern as somebody suggested in the comments, for more information related to Decorator pattern you can read this link.

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
}

Tips: wrapping class in java in order to add new methods

I would like to ask you some tips about this java scenario:
I have a simple interface called Sequence that performs some basic operation. Now I would like to implement some additional methods in a separate class, called SequenceWrapper, that implements the Sequence defined above. Here is some example code that looks like my real code:
public interface Sequence {
public void methodOne();
public int methodTwo();
}
public abstract class SequenceWrapper implements Sequence {
private wrappedSequence = null;
public SequenceWrapper(Sequence sequence){
this.wrappedSequence = sequence;
}
public void methodOne(){
wrappedSequence.methodOne();
}
public int methodTwo(){
return wrappedSequence.methodTwo();
}
}
public class ConcreteWrapper extends SequenceWrapper {
public ConcreteWrapper(Sequence sequence){
super(sequence);
}
// Just an example
public int addMethodOne(){
int a = super.methodTwo();
return a + 3;
}
}
Now if I want to implements a class with another method (say 'addMethodTwo()') I can simply extends the 'ConcreteWrapper' class and add only the new method:
public class ConcreteWrapperTwo extends ConcreteWrapper {
public ConcreteWrapperTwo(Sequence sequence){
super(sequence);
}
public int addMethodTwo(){
int a = super.methodTwo();
return a + 30;
}
}
What do you think? Is this code correct or it's preferable another strategy??
Thanks in advance
First, your private wrappedSequence = null; has no type.
I suppose you meant private Sequence wrappedSequence = null;
Second, in your example you will never be able to instantiate any of the classes, since all of them receive another Sequence in the constructor and there is no way of create the first instance of Sequence.
Third, composition over inheritance is a good approach, if you really need it. Usually you wrap an object when you need to hide or protect the access to the wrapped object. In your case, within the wrapper you are exposing all of the methods of the wrapped object. You then create new methods that will affect the wrapper object, but not the wrapped one.
What you probably need is just a normal inheritance scenario:
I would like to walk you through you a breakdown for this Java scenario:
I have a simple interface called Sequence that performs some basic operation. Now I would like to implement some additional methods in a separate class, called SequenceWrapper that implements the Sequence as defined above. Here is some example code to explain what I mean:
public interface Sequence {
public void methodOne();
public int methodTwo();
}
public abstract class AbstractSequence implements Sequence {
public SequenceWrapper( ){ }
public void methodOne(){
//basic behavior here
}
public int methodTwo(){
//basic behavior here
}
}
public class ConcreteSequence extends AbstractSequence {
public ConcreteSequence ( ){
super( );
}
// Just an example
public int addMethodOne(){
int a = methodTwo();
return a + 3;
}
}
public class ConcreteSequenceTwo extends AbstractSequence {
public ConcreteSequenceTwo( ){
super( );
}
public int addMethodTwo(){
int a = methodTwo();
return a + 30;
}
}

Categories