A design pattern for constructors - java

I have been challenged by a design issue which I will try to describe below.
Suppose that a class, call it A, has a constructor with a bunch of parameters. Since it is tiring and dirty to write all those parameters in each instantiation, I have written another class, call it StyleSheetA, which encapsulates all those parameters and is the only parameter to the constructor of A. In this way, I can prepare some default StyleSheetA templates to be used later, and if it is needed, I can modify them.
And at this point, I need to extend A. Suppose B extends A. B will have its own stylesheet, namely StyleSheetB. I think it will be appropriate that StyleSheetB extends StyleSheetA, so with one stylesheet parameter, constructor of B can also construct its super class A. But I am afraid of the possibility that this design may have flaws. For example what if I decide to add a getter/setter for the stylesheet? Is there a novel way to handle all these situations? Am I in the wrong way? For those who are confused, I attach some code here:
class A
{
StyleSheetA ss;
A(StyleSheetA ss)
{
this.ss = ss;
// Do some stuff with ingredients of styleSheet
}
}
class StyleSheetA
{
int n1;
int n2;
// :
// :
int n100;
}
class B extends A
{
B(StyleSheetB ss)
{
super(ss);
// Do some stuff with ingredients of styleSheet
}
}
class StyleSheetB extends StyleSheetA
{
int n101;
int n102;
// :
// :
int n200;
}
Thank you for any help or suggestions, also any of your critics will be appreciated.
Edit: I am developing in java me so there is no generics support.

It seems to me that you are only moving the problem of having too many parameters from class A to class StyleSheetA.
To illustrate my point, think of this question: How would you instantiate StyleSheetA? Probably using a constructor that accepts all these parameters, anyway. The only benefit this design may give you is if you have a same set of parameter values encapsulated by an object of StyleSheetA which you will reuse among multiple instances of A. If so, bear in mind that although you'd have different instances of A they would share the same parameters, so it isn't a good choice.
What I could recommend you is to try to refactor your class A itself. Try to break it up into smaller classes. If nesseccary, try to create subclasses to avoid conditional branches, etc.
Now, I don't know how your class A looks like, but maybe if you do so you'll have several classes, each with its own set of parameters. And if any of the parameters is a discriminator (meaning that it determines the class "type") you will be able to get rid of it, just by using subclasses, and relying on built in type system to do it instead.

Have you considered using an IoC container, like StructureMap, to manage your constructor dependencies? That might make a lot of this stuff easier.

A thoughts on the getter and setter issue:
The constructor in 'B' implies that the additional parameters (n101+) are necessary for the operation of the class. If you were just extending the class with a full parameter list, you would have getters and setters for n101...n200 in B and n1...n100 in A. This suggests perhaps not having StylesheetB extend StylesheetA, but rather have the constructor to class B be B(StyleSheetA,StyleSheetB), this way you can have a setter in class A for it's parameters, have that inherited and also put one in B for StylesheetB.

Related

Should i create a constructor with a setter

Every Time i create a new class i wonder what is the best way to create a constructor. If i use the default constructor made in IntelliJ it would create a constructor like example A. But at school we learn to use methode B.
Is there some big difference between A and B.
Is there some preferred way or is just a programmers choice ?
Example A:
public Model(int modelNumber) {
this.modelNumber = modelNumber;
}
Example B
public Model(int modelNumber) {
setModelNumber(modelNumber);
}
public void setModelNumber(int modelNumber) {
this.modelNumber = modelNumber;
}
Unless your class is marked as final, example B in its current form is definitely wrong.
The principle you need to follow is that you mustn't call overrideable methods from your constructor. If you don't obey that rule, you can't maintain class invariants: you can't guarantee that a subclass doesn't change what setModelNumber() does and you can end up with a modelNumber field that hasn't been initialised to the expected value.
Failing to follow this principle could carry other, less obvious, but no less damaging consequences too.
And for that reason it's usually preferable that you set the fields directly from the constructor. Not only that, in the case of final fields, that is your only option.
Example A is more preferred, The moment you create your object you need to call the constructor to initialize values of your class members, setters and getters are used for other functions in your code to make use of the same members! It becomes extremely important to consider Example A. You can't do the calling setter if you want to inherit this class. You cannot make your class non inheritable.
So the answer is NO! Don't use Example B!Cheers!
I definitely agree with the idea of
you mustn't call overrideable methods from your constructor"
as biziclop user said, so try to avoid the B example! In addition, B example is more expensive than the A. Think about the processor. Instead of going directly to the class attribute modelNumber it has to go to setModelNumber method first. Once there, it has to setup the modelNumber with the specified one. In the end, both examples do the same, but A is more direct and efficient.

Find info about class in java, software design?

I have a bunch of classes extending an abstract Base class.
Each subclass takes an array as in the constructor, (different length depending on class).
These classes could be written by other people.
What is the best way to figure out the length of the array the class needs?
I could:
(A) Require that each derived class have a static method, returning the length.
However, the base class cannot enforce this, since abstract static methods does not work in java.
(B) Each derived class have a constructor with no arguments, and I construct
such classes just to be able to call the countParameters() method, that
I can enforce from the Base class. This feels "cludgy", since I am not interested in creating such object, but only need some info about it.
The reason is that I am creating a GUI, that gives the user the ability to create
instances of Derived classes, but each Derived class takes different number of parameters.
That is, I need to know how to draw the GUI before I can create the classes.
EDIT:
I could just require that each Derived class have a private
constructor, with no arguments, and using reflection I can call the countParameters() method.
EDIT2: Actually, what I am interested in, is what the names of the parameters are.
That is, if the class Derived have the constructor
public Derived(double name1,double name2,...)
I need a way to generate the String[] array
{name1,name2,...}
I guess this would be impossible to do without creating an instance of the class,
but for the user to be able to create such class, he/she needs the parameter names!
Moment 22.
It sounds like you need the Factory Pattern.
In general, it's a bad idea for a base class to know the set of it's descendant's. So you define another class whose job it is to know that.
If you have something like a Shape, with ThisShape and ThatShape as derived classes, then a ShapeCreator will handle the job of creating the specific set of shapes your program supports, giving each one the arguments it needs.
It's not quite clear what you're trying to achieve, but I wonder: Do the subclasses really have to take a single parameter with an array, as opposed to a list of parameters?
Constructor<?> ctor = Test.class.getConstructors()[0];
int parameterCount = ctor.getParameterTypes().length;
ctor.newInstance(new Object[parameterCount]);
how about this code:
public absract Base {
public abstract int size();
public Base(Object[] objs) {
if (objs.length != size()) {
throw new IllegalArgumentException();
}
//rest of your code.
}
each child class needs to implement size method.
hope its help.
I'd go with method A. You can't get the compiler to enforce the existence of such a method, but you can certainly enforce it in your program - no method, no work!
Seriously, this whole scheme is a bit brittle and I can't think of a way to make it significantly better. An incorrect implementation of those subclasses will bomb out, that's life.
A possible remedy would be for you to provide a set of interfaces for those subclasses, such as
SubClassTaking2Args
SubClassTaking3Args
...
and requiring your sub's to implement one of those as a marker interface. But that's just more bureaucracy with little more effect.

Adding functions to Java class libraries

I'm using a Java class library that is in many ways incomplete: there are many classes that I feel ought to have additional member functions built in. However, I am unsure of the best practice of adding these member functions.
Lets call the insufficient base class A.
class A
{
public A(/*long arbitrary arguments*/)
{
//...
}
public A(/*long even more arbitrary arguments*/)
{
//...
}
public int func()
{
return 1;
}
}
Ideally, I would like to add a function to A. However, I can't do that. My choice is between:
class B extends A
{
//Implement ALL of A's constructors here
public int reallyUsefulFunction()
{
return func()+1;
}
}
and
class AddedFuncs
{
public static int reallyUsefulFunction(A a)
{
return a.func()+1;
}
}
The way I see it, they both have advantages and disadvantages. The first choice gives a cleaner syntax than the second, and is more logical, but has problems: Let's say I have a third class, C, within the class library.
class C
{
public A func()
{
return new A(/*...*/);
}
}
As I see it, there is no easy way of doing this:
C c;
int useful = c.func().reallyUsefulFunction();
as the type returned by C.func() is an A, not a B, and you can't down-cast.
So what is the best way of adding a member function to a read-only library class?
Natural and frequent dilemma. Read about the composition vs inheritance alternative. Your second alternative is basically a composition, if we think that the object A is passed in the constructor instead of passing it in each method - that is, we would be using composition to implement a wrapper or decorator pattern.
The issue for class C returning a new instance of class A has no trivial solution, as you guessed, as long as class C decides to take responsability of creating the new instance. This is why one should pause and think before typing a "new" statement inside a class, if there is the possibility that this class will be subclassed. In yout example, it would be nice if you could tell class C what concrete class to return ... but how would it know to create it? Well we could pass him an object who knows how to instantiate an object of class A (or a subclass)... I guess you are enough motivated to read about Factories now, and design patterns in general.
There is no unique best answer, but if want a quick one: I'd make a wrapper, B class does not extend A but has a constructor with A as parameter, it delegates its methods (except the own) to the inside object.
When you need to call the method in class C (I'm assuming you cant touch class C), you could write: B b = new B(c.func())
Why not use Composition instead of Inheritance?
class ABetterA {
private A a;
public ABetterA() {
}
// write wrapper methods calling class' A methods and maybe doing something more
}
This way, you could also mimic multiple inheritance...
You have a third option. You could use Scala (a Java compatible language) and its traits, which are mixins by another name.
Another option similar to Brian's sugestion is to use Aspect Oriented Programming (AOP) tool, such as ApectJ, which let you "inject" additional functionality into existing classes, even binary ones. You either preprocess the library jar to get a new one with enhanced classes ("static weaving") or you can do all of this at runtime when the library classes are loaded (so called "load-time weaving"). You can check this AspectJ example.
Even though AOP is normally used to modify existing methods (before, after or around "advices" = code pieces) you can also introduce new members and methods - check AspectJ's Inter-type declarations.
Of course there is the question whether AspectJ is supported at your limited platform.

Constructor overloading in Java - best practice

There are a few topics similar to this, but I couldn't find one with a sufficient answer.
I would like to know what is the best practice for constructor overloading in Java. I already have my own thoughts on the subject, but I'd like to hear more advice.
I'm referring to both constructor overloading in a simple class and constructor overloading while inheriting an already overloaded class (meaning the base class has overloaded constructors).
Thanks :)
While there are no "official guidelines" I follow the principle of KISS and DRY. Make the overloaded constructors as simple as possible, and the simplest way is that they only call this(...). That way you only need to check and handle the parameters once and only once.
public class Simple {
public Simple() {
this(null);
}
public Simple(Resource r) {
this(r, null);
}
public Simple(Resource r1, Resource r2) {
// Guard statements, initialize resources or throw exceptions if
// the resources are wrong
if (r1 == null) {
r1 = new Resource();
}
if (r2 == null) {
r2 = new Resource();
}
// do whatever with resources
}
}
From a unit testing standpoint, it'll become easy to test the class since you can put in the resources into it. If the class has many resources (or collaborators as some OO-geeks call it), consider one of these two things:
Make a parameter class
public class SimpleParams {
Resource r1;
Resource r2;
// Imagine there are setters and getters here but I'm too lazy
// to write it out. you can make it the parameter class
// "immutable" if you don't have setters and only set the
// resources through the SimpleParams constructor
}
The constructor in Simple only either needs to split the SimpleParams parameter:
public Simple(SimpleParams params) {
this(params.getR1(), params.getR2());
}
…or make SimpleParams an attribute:
public Simple(Resource r1, Resource r2) {
this(new SimpleParams(r1, r2));
}
public Simple(SimpleParams params) {
this.params = params;
}
Make a factory class
Make a factory class that initializes the resources for you, which is favorable if initializing the resources is a bit difficult:
public interface ResourceFactory {
public Resource createR1();
public Resource createR2();
}
The constructor is then done in the same manner as with the parameter class:
public Simple(ResourceFactory factory) {
this(factory.createR1(), factory.createR2());
}
Make a combination of both
Yeah... you can mix and match both ways depending on what is easier for you at the time. Parameter classes and simple factory classes are pretty much the same thing considering the Simple class that they're used the same way.
I think the best practice is to have single primary constructor to which the overloaded constructors refer to by calling this() with the relevant parameter defaults. The reason for this is that it makes it much clearer what is the constructed state of the object is - really you can think of the primary constructor as the only real constructor, the others just delegate to it
One example of this might be JTable - the primary constructor takes a TableModel (plus column and selection models) and the other constructors call this primary constructor.
For subclasses where the superclass already has overloaded constructors, I would tend to assume that it is reasonable to treat any of the parent class's constructors as primary and think it is perfectly legitimate not to have a single primary constructor. For example,when extending Exception, I often provide 3 constructors, one taking just a String message, one taking a Throwable cause and the other taking both. Each of these constructors calls super directly.
If you have a very complex class with a lot of options of which only some combinations are valid, consider using a Builder. Works very well both codewise but also logically.
The Builder is a nested class with methods only designed to set fields, and then the ComplexClass constructor only takes such a Builder as an argument.
Edit: The ComplexClass constructor can ensure that the state in the Builder is valid. This is very hard to do if you just use setters on ComplexClass.
It really depends on the kind of classes as not all classes are created equal.
As general guideline I would suggest 2 options:
For value & immutable classes (Exception, Integer, DTOs and such) use single primary constructor as suggested in above answer
For everything else (session beans, services, mutable objects, JPA & JAXB entities and so on) use default constructor only with sensible defaults on all the properties so it can be used without additional configuration
Constructor overloading is like method overloading. Constructors can be overloaded to create objects in different ways.
The compiler differentiates constructors based on how many arguments are present in the constructor and other parameters like the order in which the arguments are passed.
For further details about java constructor, please visit https://tecloger.com/constructor-in-java/

Getting data from a subclass without instantiation

I have an abstract superclass and various subclasses. Each subclass contains a value that I would like to use statically but it is not possible to create an abstract static method. I want to get a value from them dynamically without having to create instances. What do I do?
Another question would be: How would I loop through subclasses? Is it it even possible?
One attempt involved mapping class names (Subclass.class) to the value and trying to use the newInstance on them so I could use a method to get the value but this doesn't work.
Where am I going wrong in my approach?
Why not go about it the other way? Put the data someplace statically accessible and have the subclasses get it from there?
Of course, the feasibility of this depends on the nature of the data but when you find yourself hitting this sort of barrier it often helps to step back and reexamine your assumptions.
-- MarkusQ
You can reference static members/methods via reflection, but there is not automatic way to find all subclasses of a class.
Consider providing the subclasses/instance factories/metadata classes via some other mechanism, such as ServiceLoader services or some other plugin framework.
Maybe you are looking for enums?
public enum Planet
{
MERCURY (2.4397e6),
VENUS (6.0518e6),
EARTH (6.37814e6);
private final double radius;
Planet(double radius)
{
this.radius = radius;
}
public double radius()
{
return radius;
}
}
You don't have to create enum instances yourself. Enums can have values, e.g. radius() in the example. You can add behaviour to them so they can act like normal classes, by defining abstract methods on them, e.g.
public enum Planet
{
...
abstract double weightOnSurface(double weight);
...
}
You can loop through enums, like this:
for (Planet p : Planet.values())
{
System.out.println(p.radius());
}
So they seem to meet all your criteria.
Creating a second class for each of your subclasses which represents the type of that subclass might work.
For example, create a factory class for each subclass (a class that is responsible for creating instances of that subclass). There only needs to be one instance of each factory class.
Each factory class can then be responsible for knowing the subclass-specific data you describe. You then just need to loop over a fixed set of factory classes.
If you have a fixed set of subclasses then you can put the data in the superclass. If you subclasses can be added, then there is no way to list them all. You might get subclasses let the superclass know of their existence from the static initialiser (or use an agent!).
Generally superclasses should not be aware of their subclasses. However you might want to think (or better refactor) your superclass into a supertype and some other class responsible for your subclasses.
You will need to to scan package(s) and clasess to find ones that extend your superclass - unfortunately, this cannot be done with the Reflection API, but must be done through URLs (file system classes, jar files etc). Annotation use is probably better in this case, and lots of open source products use this method (Hibernate etc).
Then you can have a static method in each (either consistent naming or annotated) which you should be able to invoke with as method.invoke(MyObject.class, arguments)
The other option is to put a registry map in the abstract class - if you need to mandate it, the abstract constructor takes the static value (or just stores the subclass if calculations are needed). If you're controlling all subclasses, just make sure you have a static block in each one to add it to the registry.
Mapping subclasses... you can do it via reflection (but it won't be fun).
newInstance() (likely) won't work unless:
the class is public
the constructor is public
the constructor takes no arguments
The last one is mandatory, the other two depend on what package you are doing things from (I think, been a while since I cared). Using the Constructor class is better.
Can you give a short code example of what it is you are thinking of doing? Based on that I (and others) might be able to give you better answers. If you do need to do the mapping subclass thing I can dig up some code that does it...

Categories