Java combine parents of two large inheritance chains - java

I have two parent classes in a huge project, let's say ClassA and ClassB. Each class has many subclasses, which in turn have many subclasses, which in turn have many subclasses, etc.
My task is to "marry" these two "families" so that both inherit from a SINGLE parent. I need to essentially make ClassA and ClassB one class (parent) to both of their combined subclasses (children).
ClassA and ClassB both currently implement Serializable.
I am currently trying to make both inheritance chains inherit from ClassA, and then copy all functions and data members from ClassB into ClassA. This is tedious, and I think a terrible solution.
What would be the CORRECT way to solve this problem?
EDIT - some clarification
ClassA and ClassB essentially do the same thing (many calls to many Stored procs, through a series of many classes and method calls of course).
ClassA, however, makes the calls to half of the Stored Procs via a new service based (Jersey) architecture we implemented. I am essentially implementing the new service oriented functionality into "FamilyB" in the same way we it has already been done in "FamilyA". The problem is that each of these families are huge - many classes and long inheritance chains, making small changes has a butterfly effect on the inheritance chains.
If clarification is needed, please let me know.

The first answer that comes to mind is "In general, no".
In order for this to be reasonable, A and B should be special cases of some other thing -- although that is feasible, it would seem unlikely.
Besides that, I don't see any reason to combine any code (and a lot of reasons not to). Is there some reason you cannot simply have both of them extend X, and leave all their code where it is?
I don't think I have enough information for a clear picture yet, but will go with what I have so far.
If you implement a Class X that both Class A and Class B extend, that changes nothing about any subclasses or any use of either class or any subclass. That is certainly where I'd start.
public Class X implements Serializable {}
public Class A extends X implements Serializable
{
// retain all current code to start
}
public Class B extends X implements Serializable
{
// and here be all current code also
}
You say you are currently thinking of merging Class B into Class A; this sounds problematic; A and B share 'about half' of their code and both have a large inheritance tree below them - something that instantiates a Class A subclass could have its behavior changed by having A get some new functionality.
So instead I would move things slowly from A to X and from B to X. I would try to move things only if they had commonality between the A and B trees.
For instance, let's say you have method abc() in A and def() in B with the same functionality. You could move this functionality to X and call it anything you want - I would probably try to give it the name I thought best described its function, whether that came from A, B, or I made up a new one. Then abc() and def() could invoke this new function, and the code for these methods could be removed from both of them.
public class X implements Serializable
{
public void abcdef()
{
// common functionality, merged from A and B
}
}
public class A extends X implements Serializable
{
public function abc() { abcdef(); }
}
public class B extends X implements Serializable
{
public function edf() { abcdef(); }
}
One good thing about proceeding this way is that it is clear at each step what has been done. You could mark it well with comments and have it reviewed, and/or put it through tests to insure that functionality of both the refactored methods was complete and correct; this could be done after one, two, or more methods were refactored, depending on whether you have good setups for review and/or testing.
The only case where this might break is if, for some reason, you want the callers of methods in the two inheritance trees to change, but I don't have any reason (yet) to think that is necessary. Hopefully all the methods have at least reasonable names describing what they do and passing the parameters that need passing, and the refactoring at the top only affects the implementations, not the calls. It looks like a big enough job anyway, I'm hoping you don't have to change the calls as well as the functions.

My instinct is to create a new class that has objects of ClassA and ClassB as members, then use that as the base class for the things that you essentially want to derive from both ClassA and ClassB. For example:
class ClassAB
{
private ClassA a;
private ClassB b;
public void doSomething()
{
a.doSomething();
}
public void doSomethingElse()
{
b.doSomethingElse();
}
...
}
Sure, it's tedious, but it seems a lot easier and a lot less likely to lead to bugs than trying to rework ClassA and ClassB to make this possible. Does that work in this case?

Why don't you create a new class that ClassA and ClassB both extend and then start merging shared functionality up there.
Be sure that it actually makes sense to merge the code from ClassA and ClassB though.

Related

How to prohibit a subclass from having a method?

In my Java project, I have the method addType1AndType2() which has windows where you expand lists and select objects from the list. It was very complicated and time consuming to create, as things must be scrolled and xpaths keep changing. There are two lists in this which are actual names but, due to company proprietary info, I will just call them Tyep1 and Type2.
Now I have an UpdateType1 class which uses all the complicated methodology in the AddType1AndType2 but has nothing related to Type2 in it. I could copy the AddType1AndType2 and cut everything I do not need, but that would be replicating and changes would have to be duplicated in both classes. This defeats the purpose of inheritance and reusability.
I can make a class UpdateType1 extends AddType1AndType2{} which I have done. But there are still methods like selectType2Value() which are inherited but not possible in the subclass.
If I do an #Override and declare the class as private in the sub class, I get an error that I cannot reduce the visibility in a subclass.
Any idea what I can do? Right now I am just putting a throw new AssertError("Do not use") but that seems kind of lame. Is there a better thing to do that would even give a compile-time error rather than an assert at run time, or is this the best way?
The thing is: your model is wrong.
Inheritance is more than just putting "A extends B" in your source code. A extends B means: A "is a" B.
Whenever you use a B object, you should be able to put an A object instead (called Liskov substitution principle).
Long story short: if B has methods that A should not have ... then you should not have A extends B.
So the real answer is: you should step back and carefully decide which methods you really want to share. You put those on your base class. Anything else has to go. You might probably define additional interfaces, and more base classes, like
class EnhancedBase extends Base implements AdditionalStuff {
Edit: given your comment; the best way would be:
Create interfaces that denote the various groups of methods that should go together
Instead of extending that base class, use composition: create a new class A that uses some B object in order to implement one/more of those new interfaces.
And remember this as an good example why LSP really makes sense ;-)
Create the interfaces
public interface IAddType1 {... /* methods signtatures to add Type1 */}
public interface IAddType2 {... /* methods signtatures to add Type2 */}
public interface IUpdateType1 {... /* methods signtatures to update Type1 */}
then your current code at AddType1AndType2 will become just a base helper class:
public abstract class BaseOperationsType1AndType2{
//code originally at AddType1AndType2: methods that add Type1 and Type2
}
then your new AddType1AndType2 class will be:
public class AddType1AndType2
extends BaseOperationsType1AndType2,
implements IAddType1 , IAddType2 {
//nothing special.
}
and your new UpdateType1can be defined as
public class UpdateType1
extends BaseOperationsType1AndType2
implements IUpdateType1 {
//
}
Voila.
You can use 'final' keyword to prohibit extending a method in a subclass.
A method with a 'final' modifier cannot be overriden in a subclass.

Understanding Java Interfaces Principles

I am reading a Java book and stuck again this time thinking about what this whole paragraph actually means:
Interfaces are designed to support dynamic method resolution at run time. Normally, in order for a method to be called from one class to another, both classes need to be present at compile time so the Java compiler can check to ensure that the method signatures are compatible. This requirement by itself makes for a static and nonextensible classing environment. Inevitably in a system like this, functionality gets pushed up higher and higher in the class hierarchy so that the mechanisms will be available to more and more subclasses. Interfaces are designed to avoid this problem. They disconnect the definition of a method or set of methods from the inheritance hierarchy. Since interfaces are in a different hierarchy from classes, it is possible for classes that are unrelated in terms of the class hierarchy to implement the same interface. This is where the real power of interfaces is realized.
First question: what does the author mean by saying from one class to another? Does he mean that those classes are related in terms of the hierarchy? I mean, assigning subclass object reference to its superclass type variable and then calling a method?
Second question: what does the author again mean by saying This requirement by itself makes for a static and nonextensible classing environment? I don't understand the makes for meaning (english is not my main language) and why the environment is called static and nonextensible.
Third question: what does he mean by saying functionality gets pushed up higher and higher? Why does it get pushed up higher and higher? What functionality? Also, mechanisms will be available to more and more subclasses. What mechanisms? Methods?
Fourth question: Interfaces are designed to avoid this problem. What problem???
I know the answers must be obvious but I don't know them. Maybe mainly because I don't undestand some magic english phrases. Please help me to understand what is this whole paragraph telling.
Between any two classes. If your code contains a call to String.substring() for example, the String class and its substring() method must be available at compile time.
As said, "makes for" means the same as "creates". The environment is non-extensible because everything you may want to use must be available at compile time. (This isn't 100% true though. Abstract classes and methods provide extension points even when no interfaces are present, but they aren't very flexible as we're going to see.)
Imagine that you have two classes: Foo and Bar. Both classes extend the class Thingy. But then you want to add a new functionality, let's say you want to display both in HTML on a web page. So you add a method to both that does that.
The basic problem
abstract class Thingy { ... }
class Foo extends Thingy {
...
public String toHTMLString() {
...
}
}
class Bar extends Thingy {
...
public String toHTMLString() {
...
}
}
This is great but how do you call this method?
public String createWebPage( Thingy th ) {
...
if (th instanceof Foo)
return ((Foo)th).toHTMLString();
if (th instanceof Bar)
return ((Bar)th).toHTMLString();
...
}
Clearly this way isn't flexible at all. So what can you do? Well, you can push toHTMLString() up into their common ancestor, Thingy. (And this is what the book is talking about.)
A naive attempt to resolve it
abstract class Thingy {
...
public abstract String toHTMLString();
}
class Foo extends Thingy {
...
public String toHTMLString() {
...
}
}
class Bar extends Thingy {
...
public String toHTMLString() {
...
}
}
And then you can call it like this:
public String createWebPage( Thingy th ) {
...
return th.toHTMLString();
}
Success! Except now you've forced every class extending Thingy to implement a toHTMLString() method, even if it doesn't make sense for some of them. Even worse, what if the two objects do not extend anything explicitly, they're completely unrelated? You'd have to push the method up all the way into their common ancestor, which is java.lang.Object. And you can't do that.
Solution with interfaces
So what can we do with interfaces?
abstract class Thingy { ... }
interface HTMLPrintable {
public String toHTMLString();
}
class Foo extends Thingy implements HTMLPrintable {
...
public String toHTMLString() {
...
}
}
class Bar extends Thingy implements HTMLPrintable {
...
public String toHTMLString() {
...
}
}
//We've added another class that isn't related to all of the above but is still HTMLPrintable,
//with interfaces we can do this.
class NotEvenAThingy implements HTMLPrintable {
public String toHTMLString() {
...
}
}
And the calling code will be simply
public String createWebPage( HTMLPrintable th ) {
...
return th.toHTMLString(); // "implements HTMLPrintable" guarantees that this method exists
}
What are interfaces then?
There are many metaphors used to understand interfaces, the most popular is probably the idea of a contract. What it says to the caller is this: "If you need X done, we'll get it done. Don't worry about how, that's not your problem." (Although the word "contract" is often used in a more general sense, so be careful.)
Or in another way: if you want to buy a newspaper, you don't care if it's sold in a supermarket, a newsagents or a small stall in the street, you just want to buy a newspaper. So NewspaperVendor in this case is an interface with one method: sellNewsPaper(). And if someone later decides to sell newspaper online or door-to-door, all they need to do is implement the interface and people will buy from them.
But my favourite example is the little sticker in shop windows that says "we accept X,Y and Z credit cards". That's the purest real-world example of an interface. The shops could sell anything (they may not even be shops, some might be restaurants), the card readers they use are different too. But you don't care about all of that, you look at the sign and you know you can pay with your card there.
The Key to paragraph is "classes need to be present at compile time" in line 2. Classes are more concrete. While interfaces are abstract.
As classes are concrete so Designer and programmer needs to know all about class structure and how the methods are implemented. Where as interfaces are more abstract. (They contain abstract methods only). So programmer needs to know only what methods an interface has to have and signature of those methods. He does not need to know detail how these are implemented.
Thus using interfaces is easier and better while making subclasses. You only need to know method signatures of interface.
Using concrete class we have to implement functionality of a method high in class hierarchy while using interface avoids this problem. (There is a related concept of polymorphism that you would probably learn later)

java - connecting interface to class member

Say I have an interface A and a class B that implements it.
Now, I also have some class C which extends class D (which means that it can't also extends B) but I also need there the functionality of interface A.
The solution I know is to have a member of A instantiated by B in C (which will implement A) and when implementing the functions of A call the matching function from the member of A.
Is there any way to create some connection between the functions of A and the member inside C? (so that java will know that every time it needs to call a function from A it will directly go and and run the matching function from the A member without me needing to write the code for it for every function of A)
A big thank you is waiting to each one of the helpers...
No. As already stated delegation must be implemented manually.
Having said that, you have a few options to simplify this: If you're working with Eclipse, select Source|Generate Delegate Methods... and select your member variable. Eclipse will then generate all the delegate methods for you. I don't know about other IDEs, but I would be surprised, if NetBeans et al. would not have a similar feature.
Another option, if you actually want to decorate existing collection classes, consider Google Guava's Google Guava's Collection Helpers.
Last, but not least, you could consider restructing your code and decorate your classes using Advices. Advices stem from Aspect Oriented Programming (AOP) and typically use a proxying mechanism to enrich original target classes. This is a rather advanced technique, but if you are determined to go down this road, have a look at Spring's AOP support.
So to sum up, here is your class hierarchies:
package common;
public interface A
{
void doStuff();
}
package commom.impl;
public class B implements A
{
void doStuff() {}
}
package real.service;
public class D
{
void doSomeRealStuff() {}
}
package real.service;
public class C extends D
{
void doSomeRealStuffForGood() {}
}
Assuming that each class is declared in its own source file.
Just to recall from the OP, I assume you need B stuff in C and not really A stuff. Because A is nothing but a contract and you need then the real implemting class to be fetched inside your C class in order to call the declared methods on.
In such a case, you may need to use the Inversion of Responsability approach, so that you declare an instacne of type B inside your C clas then you layer each method from B with a one having the same signature and that do nothing but delegate the real call to the instance member:
package real.service;
import common.A;
import common.impl.B;
public class C extends D
{
private A delegate;
public C ()
{
delegate = new B();
}
void doStuff() {
delegate.doStuff(); // Call the real delegate method when doStuff is called on an isntance of C.
}
void doSomeRealStuffForGood() {}
}
Note that this is a legal OO concept, since you are following an HAS-a even though some could consider it a high coupling.
Otherwise if you are not tied to the B class, and you may drop the declare methods in there for some others, you can declare an inner class that implements the A interface the way you need.
Edit:
Java does not support multiple inheritance, though you have provided a common contract in your A interface, so if you need all those methods (behavior) to be availble in your C class, it would be better to implement it directely and override all the interface methods.

Decorator Design Pattern in java

I'm designing of a project I have to do. For that, I have thought to use decorator design pattern. However, I have to adjust my design to the existing implementation of the project. Then, I can't keep completely the decorator design pattern.
The project has an abstract base class (called A) and a set of sub-class (called A1, A2, A3, A4, etc.). I can't modify the code of these classes.
Then, I have to add extra funcionality to these classes. For that, I create an abstract class (called B) that use to class A (Decorator). I also create concrete decorators that use to classes A1,A2,A3,A4,...
NOTE: As you see, I don't use any interface because the class A doesn't use any interface and I can't modify this code.
But I see some issues in this design:
1) Classes B1,B2,B3,B4,... have to add all methods of classes A1,A2,A3,A4,... for calling to methods of classes A1,A2,A3,A4... For example, in class B1:
class B1 {
public A1 objectA1;
B1() {
objectA1 = new A1();
}
public void add(int value) {
objectA1.add(value);
// extra funcionality
}
}
It can be a problem because if other developers modify the code of classes A,A1,A2,A3,A4,... they also need to modify the code of B,B1,B2,B3,B4,...
I WANT TO PREVENT THAT.
2) Moreover, classes A,A1,A2,A3,A4 have protected methods that only can be accessed from the own class or sub-classes. As I need to access to these methods, I can't use the decorator design pattern.
SECOND ALTERNATIVE
I could extend the classes A1,A2,A3,A4 with B1,B2,B3,B4. For example:
class B1 extends A1 {
B1() {
objectA1 = new A1();
}
public void add(int value) {
super.add(value);
// extra funcionality
}
}
Of this way, I solve the second problem and avoid to override all methods of A1, overriding only necessary methods. Even so, each time a sub-class of A is created, it's necessary to create the corresponding class B.
I WANT TO PREVENT THAT because it only is necessary that class B (B1,B2,...) override a method of class A (A1,A2,...).
THIRD ALTERNATIVE
Then, I thought that I could consider to class B (B1,B2,...) as a wrapper of class A (A1,A2,...). Of this way, a instance of B will be created as next:
new BMaker.get(A1, params_of_constructor_A1)
new BMaker.get(A2, params_of_constructor_A2)
new BMaker.get(A3, params_of_constructor_A3)
new BMaker.get(A4, params_of_constructor_A4) or
...
new BMaker.get(AN, params_of_constructor_AN)
where BMaker.get is a static method.
public static <T extends A> A get (T objectA, params ) {
// return anonymous class (*1)
}
My question is if it's possible to implement an anonymous class that inherit of A1, A2, ...
Each call to BMaker.get() should be created a different anonymous class deppending on if the first parameter of BMaker.get() is A1,A2,A3,...
Really, I don't know if it's possible to do this or is there another better way.
Any help would be appreciated!
Answer to the first issue:
Either put an interface I on A so your decorators/delegates can implement same interface, or
Create an interface I (equivalent to A's api) and a wrapper class AW which wraps A and implements I by passing all calls straight onto it.
Convert your client code to use I rather than A, and you can then happily proceed to build decorators/ or delegates using the new interface having "wrapped up" the old crunk in AW.
The one notable issue that arises is that some styles of code using A (IdentityHashMaps, persistence) may want a reference to the "underlying" A. If that comes up, you can put a method in the interface getUnderlyingA(). Try and avoid using that too much, since it obviously bypasses all decoration.
Second issue: decorating subtypes.
The question here is whether the subtypes need to be exposed as different decorator types -- or whether one uniform decorator can be exposed, that (maybe, if necessary) is internally aware of the type-system of the A subtypes that it can wrap.
If the subtypes are well-known & stable, you can implement a "handle style" api in the interface. For example, for file-system entities, you would present a handle of a single type but offer isFile(), isDirectory(), isDevice(), isDrive(), isRaw() etc methods for interrogating the type. A listFiles() method could be available to use the directory subtype.
My question is why you need external access (from the decorator) to protected methods? If you do, those methods should be public and the original design is broken/insufficiently extensible.
Maybe you can create a static helper class in the same package (if not changing the A class itself) that will give you proper access to this legacy crunk from your decorator.
There's a certain point here, where doing your job properly does sometimes involve working with & potentially upgrading legacy code. If there isn't an efficient & maintainable design alternative, that shouldn't be a total sticking point. Doubling up the type-system (creating two parallel heirarchies) is definitely not what you should be doing.
If there isn't a good way to do this, you should work on something else (a different feature/requirement) rather than making the codebase even worse.

Distinguishing between delegation, composition and aggregation (Java OO Design)

I am facing a continuing problem distinguishing delegation, composition and aggregation from each other, and identifying the cases where it's the best to use one over the other.
I have consulted a Java OO Analysis and Design book, but my confusion still remains. The main explanation is this:
Delegation: When my object uses another object's functionality as is without changing it.
Composition: My object consists of other objects which in turn cannot exist after my object is destroyed-garbage collected.
Aggregation: My object consists of other objects which can live even after my object is destroyed.
Is it possible to have a few simple examples demonstrating each case, and the reasoning behind them? How else can these examples be demonstrated other than my object simply having a reference to another object(s)?
Delegation
public class A {
private B b = new B();
public void methodA() {
b.methodB();
}
}
When clients of A call methodA, class A delegates the call to B's methodB.
Rationale. Class A exposes behaviours that belong elsewhere. This can happen in single-inheritance languages where class A inherits from one class, but its clients need behaviours that are implemented in a different class. Further study.
Hybrid Delegation
public class A {
private B b = new B();
public void methodA() {
b.methodB( this );
}
}
The difference between delegation that involves simple forwarding and delegation that acts as a substitute for inheritance is that the callee must accept a parameter of the caller, exemplified as:
b.methodB( this );
Rationale. Allows class B instances to use functionality available from class A, just as class B would if it inherited from class A--but without inheritance. Further study.
Composition
public class A {
private B b = new B();
public A() {
}
}
Once no more references to a particular instance of class A exist, its instance of class B is destroyed.
Rationale. Allows classes to define behaviours and attributes in a modular fashion. Further study.
Aggregation
public class A {
private B b;
public A( B b ) {
this.b = b;
}
}
public class C {
private B b = new B();
public C() {
A a = new A( this.b );
}
}
Once there are no more references to a particular instance of class A, its instance of class B will not be destroyed. In this example, both A and C must be garbage collected before B will be destroyed.
Rationale. Allows instances to reuse objects. Further study.
Demonstration Without References
The names given to these simple patterns are defined by their referential relationships.
Your object would reference another object(s) in all three cases. The difference lies in behavior and / or lifecycle of referenced objects. Some examples:
Composition: House contains one or more rooms. Room's lifetime is controlled by House as Room will not exist without House.
Aggregation: Toy house built from blocks. You can disassemble it but blocks will remain.
Delegation: Your boss asked you to get him a coffee, you've had an intern do it for you instead. Delegation is not a type of association (like composition / aggregation are). The latter two have been discussed on Stack Overflow many times
In the comment you ask how the implementation would differ in each case, observing that in all cases we invoke methods on the releated objects. It's true that in each case we would have code such as
myRoom.doWork();
myBlock.doWork();
myMinion.doWork();
but the differences lie in the life-cycle and cardinality of the related objects.
For the Component, the Rooms come into existence when the House is created. So we might create them in the constructor of the House.
In the case of Association (I'll use Tyre and Car) Cars might add Tyres in their constructor, but later you may want to remove and change tyres. So you also have methods such as
removeTyre(FrontLeft)
addNewTyre(aTyre, BackRight)
And it's quite likely that the aTyre object came from a Factory - we didn't new it in any of the Car's methods.
In the case of Delegation, you might not even have a member variable to hold the delegate
resourcingPool().getIntern().getCoffee(SkinnyLatte, workstation 7);
the relationship between the objects lasts only as long as the intern is fetching the coffee. Then it returns to the resource pool.
Your book explains quite good so let me elaborate and provide you some examples.
delegation: When my object uses another object's functionality as is without changing it.
Sometime a class may logically need to be big. But big class is not a good coding pratice. Also sometime, some functionalities of a class may be implementable in more than one way and you may want to change that some time.
class FeatureHolder {
void feature() {
// Big implementation of the feature that you dont want to put in the class Big
}
}
class Big {
private FeatureHolder FH = new FeatureHolder();
void feature() {
// Delegate to FeatureHolder.
FH.feature();
}
//.. Other features
}
From the above example, Big.feature() call feature of FH as is without changing it. This way, the class Big does not need to contain the implementation of the feature (separation of labour). Also, feature() can implement differently by other class like "NewFeatureHolder" and Big may choose to use the new feature holder instead.
composition: My object consists of other objects which in turn cannot exist after my object is destryed-garbage collected.
aggregation: My object consists of other objects which can live even after my object is destroyed.
Technially, Composition is "part of" and Aggregation is "refer to" relationship. Your arms are part of you. If you no longer live, your arm will die too. Your cloth is not part of you but you have them; as you can guest, your cloth does not go with you.
In programming, some objects are part of another object and they have no logical meaning without it. For example, a button is composed into a window frame. If a frame is closed, the button has no reason to be around anymore (Composition). A button may have reference to a database (like to refreash data); when the button is eliminated, the database may still be around (Aggregation).
Sorry for my English, Hope this helps
1) Delegation: Man-driver-car example. A Man bought a car. But that man does not know to drive the car. So he will appoint a driver who knows driving a car. So the Man class wants to perform a transportation using car. But it does not have the interacting- functionality/compatibility with car. So he uses a class which has compatibility with car that is driver which is compatible with man class. Assuming that driver can understand what man says
2) Composition: Car simulation is a routine example. To make a car move, wheel rotates. Car class using wheel class rotate functinality as part of its move function, where as wheel is part of car.
3) Aggregation: Car and its colour. Car class object ferrari will have a colour class object red. But colour class object red can be there as individual class, when user search happens with a specification of red colour.
In a very simple sentence I can say:
Delegation is: delegate behaviour to other class when you do not want to change it. by change I mean during run time. for example you delegate driver to car class that driver wont change while driving.
Composition is: when you want to use behaviour of family of classes (one or more classes, that implements an interface) that you might change during run time. but you should consider these classes can not exist with out main classes, such as rooms of a hotel. If you remove hotel all rooms of hotel will not exist.
Aggregation is: same as composition but classes can exist without main class.

Categories

Resources