I was wondering lately, which one of the three methods of passing parameters to the method - presented below - are the best for you, your CPU, memory and why. I am considering methods which allow me to pass more arguments in future, without changing the method signature.
If you know something better, I am here to listen and learn.
Pass by methods
Params.java
public interface Params {
int getParamOne();
int getParamTwo();
}
Calling
obj.foo(new Params() {
#Override
public int getParamOne() {
return 1;
}
#Override
public int getParamOne() {
return 2;
}
});
Receiving
public void foo(Params p) {
int p1 = p.getParamOne();
int p2 = p.getParamTwo();
}
Pass by class fields
Params.java
public class Params {
private int paramOne;
private int paramTwo;
// Getters and setters here
}
Calling and receiving
No magic here, just create a new Params object, use setters, pass it to the method and use getters.
Pass by Properties class
Calling
properties.put("paramOne", 1);
properties.put("paramTwo", 2);
obj.foo(properties);
Receiving
public void foo(Properties properties) {
int a = (int) properties.get("paramOne");
int b = (int) properties.get("paramTwo");
}
I was pleased to show an real-life example of code, which actually needs passing varying types and number of properties. I'm using the third method - passing by the properties:
public interface DataProvider {
public String getContent(Properties properties);
}
public class HttpProvider implements DataProvider {
#Override
public String getContent(Properties properties) {
InputStream in = new URL(properties.get("URL")).openStream();
String content = IOUtils.toString(in);
IOUtils.closeQuietly(in);
return content;
}
public class FtpProvider implements DataProvider {
#Override
public String getContent(Properties properties) {
FTPClient ftpClient = new FTPClient();
ftpClient.connect(properties.get("server"), properties.get("port"));
ftpClient.login(properties.get("user"), properties.get("pass"));
// Get file stream and save the content to a variable here
return content;
}
}
One interface for a different methods of obtaining a file. I am not persisting that this is good or not, it's just an example of code I've stumbled upon in my current project in work and I was wondering if could it be done better.
The usage of a "Params" class is better than properties, in performance. The java compiler can handle such short lived classes quite well.
One sees properties on some constructors / factory methods, like for XML and such.
One sees a parameter containing class in larger systems, to keep the API restricted to one parameter, and not use overloaded methods.
I would do:
public class Params {
public final int a;
public final int b;
public Params(int a, int b) {
this.a = a;
this.b = b;
}
}
And in the class immediately use params.a.
For the rest there is also the Builder Pattern, but that would be more a substitute for a complex constructor.
Signatures in interfaces should not ever change!!! If you contemplate to change APIs in the future (i.e. change, add or remove a parameter), an acceptable way may be by incapsulating your parameters in objects in order to do not break signatures.
Related
I'm beginner in Java and I need help. I have several classes.
public class A{
private String name = "A";
public String getClassName(){
return "A";
}
public void editClassName(String name){
this.name = name;
}
}
public class B{
private String name = "B";
private int counter = 0;
public String showClassName(){
return "B";
}
public int getCount(){
return counter;
}
}
Such classes could be more. I also need to have some class witch can return an instance of asked class.
public class ClassSelector{
public static ??? getClassByName(String nameOfClass){
if(nameOfClass == "A"){ return new A();}
if(nameOfClass == "B"){ return new B();}
}
}
And here is a code that I want to use to get access to appropriate class:
ClassSelector.getClassByName("A").getClassName();
ClassSelector.getClassByName("B").showClassName();
I need to have an access to the instance of the class, and each instance can show it's unit methods that class has.
In this situation I don't get which return type I should use in the 'getClassByName' method.
I will very appreciate for help.
I would very much like to offer an alternative architecture if possible! It's not much different to what you have.
Firstly, we'll define some interface.
public interface Named {
String getName();
}
Now, this means you can have lots of concrete classes but provided they implement this interface, you'll know (and the Java compiler will know) that they have the getName method available to you.
Next, let's update your class to implement this interface.
public class A implements Named {
public String getName() {
return "A";
}
}
You could do this for classes B, C... and so on.
Now your method return type can be set to Named, that is:
public class ClassSelector{
public static Named getClassByName(String nameOfClass){
if(nameOfClass.equals("A")){ return new A();}
if(nameOfClass.equals("B")){ return new B();}
}
}
And you can access the response like so:
Named response = ClassSelector.getClassByName("A").getName();
As Eran suggested, it can be only of type Object, because they don't have a common superclass other than Object. If you don't want to work with Object class, you can create a body-less interface and implement it in both(or multiple classes) and that can be your return type.
After the call of the method, you can find the specific type of the returned object with instanceof;
What you are trying to do is called the Factory Pattern.
Assuming you are crating Widgets I suggest;
Introduce a Widget interface and have A and B implement Widget as per Christopher’s answer
Rename ClassSelector to WidgetFactory
Rename the method getClassByName to create, make it non-static and return Widget instances
This is more aligned with common Java name conventions and thus makes your code readily understandable by most developers.
If you want to keep your factory static it is of course possible but it may make your code less testable as it cannot be switched out for another factory in your tests. This is problematic if A and B are heavy weight objects that carries a lot of external dependencies that you may want to exclude.
If testability is a concern you may even consider making the factory implement a WidgetFactory interface...
First of all, please note that for string comparison you have not to use "==" (the problem is in nameOfClass == "A" and so on, I say it only for completeness).
I want suggest a solution based on reflection, that maybe could be more concise:
public interface IClass {
}
public class A implements IClass {
private String name = "A";
}
public class B implements IClass {
private String name = "B";
}
public class ClassSelector {
public static void main(String[] args) {
IClass obj = null;
try {
Class c = Class.forName("A");
obj = (IClass) c.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("Create object of type " + obj.getClass());
}
}
Thanks to all guys, who have answered my. Forgive me, when I create the first post, I made one mistake, which leads to misunderstanding what I mean. Now the code in the first post is better to show what I'm looking for.
I am using DI to pass around my dependencies. But in some scenarios we need to create objects dynamically and do need to provide parameters during initialization. Code sample -a tries to explain the scenario.
In order to initialize such type of objects and hide new operator, I created simple factories. Code sample -b.
Code sample -a
int are used for simplicity they will/can actually be some real objects
public class Sample {
private final int c;
public Sample(int c){
this.c = c;
}
public void doSomething(SomeCommand command, Request request, Context context){
DynamicDependency dynamicDependency = new DynamicDependency(command.getA(), command.getB(), c);
dynamicDependency.doSomeWork(request, context);
}
}
class DynamicDependency{
private final int a;
private final int b;
private final int c;
public DynamicDependency(int a, int b, int c){
this.a = a;
this.b = b;
this.c = c;
}
public void doSomeWork(Request request, Context context){
/*
Do work
*/
}
}
class SomeCommand {
private int a;
private int b;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
Code sample -b
public interface IParameterizedObjectFactory<T> {
T getInstance(Object... arguments) throws ClassCastException;
}
public class DynamicDependency implements IParameterizedObjectFactory<DynamicDependency> {
#Override
public DynamicDependencyFactory getInstance(Object... arguments) throws ClassCastException {
Validate.notNull(arguments);
if(arguments.length > 0){
final int a = (Integer) arguments[0];
final int b = (Integer) arguments[1];
final int c = (Integer) arguments[2];
return new DynamicDependency(a, b,c);
}
return null;
}
}
This does the job as I can now inject factory and then use it to get the new object as:
DynamicDependency dynamicDependency = dynamicDependencyFactory.getInstance(a,b,c);
Question(s):
Though, it does the job but we need to pass around list of Object[s] and and we loose strong typing. Casting also will eat up some execution time. How can it be improved?
Another approach could be to not to use the interface at all and use concrete classes which have getInstance method with appropriate parameter list. Sounds reasonable to me.
public class DynamicDependencyFactory {
public DynamicDependency getInstance(int a, int b, int c) {
return new DynamicDependency(a, b,c);
}
}
What else can be done to hide new? Or should I use second approach to create concrete factories?
Note: I am trying to stay away from reflection
The second approach you suggested is much better than the first. You still have the option to extract an interface from that factory if required:
public interface IDynamicDependencyFactory {
DynamicDependency getInstance(int a, int b, int c);
}
Note the lack of generic type parameters. Your first suggestion of the following interface:
public interface IParameterizedObjectFactory<T> {
T getInstance(Object... arguments) throws ClassCastException;
}
seems completely unnecessary according to your example, and, as you have noted, the Object[] as the arguments makes it a very unpleasant and non-type safe API to work with.
If you really need to pass different argument types to the methods on the factory, then define an overload for each valid signature instead of just accepting an Object[]:
public interface IDynamicDependencyFactory {
DynamicDependency getInstance(int a, int b, int c);
DynamicDependency getInstance(double a, int b, BigDecimal c);
}
Better yet, if you can refactor your code so that it does not require such a factory then that could be beneficial (unless you do not have access to the Request and Context objects at the same time as the a, b, and c int values). For example, you can pull up the constructor arguments to be method parameters and treat your DynamicDependency more like a service (or singleton):
class DynamicDependencyService {
public void doSomeWork(Request request, Context context, int a, int b, int c){
//Do work
}
}
This way, an instance of DynamicDependencyService can be passed to your Sample object via the constructor.
I decided to go with a mixed approach, using factories where I do not have control on the runtime object being created and passing runtime data via methods where the control is with me.
Steven shared couple of good articles in the comments, posting here.
Factories are a code smell
runtime values should not be injected into a component's constructor
Fortunately I was already avoiding the constructor injection in case of runtime values. The problem was with the legacy code and the code which is not owned by our team. For now, for the code which is not owned by us we have to use constructor even though it will smell a bit :)
public interface IHashStorage<T> {
public static final float INITIAL_LOAD_FACTOR = 0.7f;
public static final int INITIAL_CAPACITY = 149;
}
I have the code above which needs to be translated in c#. The only solution that seems to be proper is to make it an abstract class.From what I found it's safer to use readonly than const:
public abstract class IHashStorage<T>
{
private readonly float INITIAL_LOAD_FACTOR = (float)0.7;
private readonly int INITIAL_CAPACITY = 149;
}
The project in Java is using the Decorator pattern and Proxy, the transformation from java to c# can possibly require to use more abstract classes(currently in java there are only interfaces used)?I know theoretically the difference between them but practically in c# I used abstract classes more.I'm not that familiar with java and I would like to know your advice about how to find the best solution to finish this task, I mean the main points to keep in mind when converting the code.
I would define an interface with a get property.
then, make my base class implement it and set the default values
and then, extend the base class for every java class that implements the java interface.
something along these lines:
public interface IHashStorage<T>
{
float InitialLoadFactor { get; }
int InitialCapacity { get; }
}
public class HashStorageBase<T> : IHashStorage<T>
{
private readonly float _initialLoadFactor = 0.7f;
private readonly int _initialCapacity = 149;
public float InitialLoadFactor
{
get { return _initialLoadFactor; }
}
public int InitialCapacity
{
get { return _initialCapacity; }
}
}
public class HashStorage1<T> : HashStorageBase<T>
{
...
}
As I imply in my comment, there is no way to attach fields (or any other implementation details) to an interface in C#. You have two options besides making this an abstract class:
Make the fields into (probably read-only) properties on the interface, which will force all implementations to specify them.
Make the fields into custom attributes defined on the interface and/or the implementions.
One of the legal modifiers you can use with method local inner classes is abstract.
For example:
public class Outer {
public void method(){
abstract class Inner{
}
}
}
Is there any situation where you would actually use this?
You have to know this for the SCJP exam.
The are some invalid assumptions in the original question. That something is legal/valid Java doesn't mean that it is something that you need to use, or need to know.
I can't recall that the SCJP contains odd corner case questions.
I tried to come up with a case where I would have used an abstract class declared in a method, but everything looks very odd, and reeks of bad design.
Here's however a code example that I came up with (still bad code design IMHO)
public class BatchExecutor {
public static enum ResultNotification {
JMS,
MAIL
};
public Runnable createRunnable(ResultNotification type) {
abstract class Prototype implements Runnable {
public void run() {
performBusinessLogic();
publishResult();
}
abstract void publishResult();
}
switch (type) {
case JMS: {
return new Prototype() {
void publishResult() {
//Post result to JMS
}
};
}
case MAIL: {
return new Prototype() {
void publishResult() {
//Post result to MAIL
}
};
}
}
return null;
}
private void performBusinessLogic() {
//Some business logic
}
}
I can think only in this case
class Outer {
public void method() {
abstract class A {
void bar(){}
abstract void foo();
}
class B extends A {
#Override
void foo() {
}
}
final class C extends A {
#Override
void foo() {
}
}
A a1 = new B();
A a2 = new C();
}
}
But I can't imagine real usage
IMHO, this feature has NO real use. There's a couple of possible abuses, but there are many other ways to write bad code, you needn't learn this one. :D
Whenever you try to make use of an abstract method-local class, you need to define at least two concrete method-inner classes. This means you end up with a method containing at least three classes, the method gets quite long and that's quite a bad style.
You have to know this for the SCJP exam.
I really hope not. Method-local inner classes are already useless enough to be considered a corner case (you should understand them but probably never use them).
IMHO, a person asking this in an exam misunderstood Java badly. There can't be accessibility modifiers on a local class since (lacking method literals) the class can't be accessed from the outside anyway. There can be abstract and final modifiers, since there's no reason to forbid them. There are good reasons to allow them: orthogonality and the Principle of least astonishment.
Is there any situation where you would actually use this?
Let S1 denote all situations in which you need an abstract class.
Let S2 denote all situations in which you need a local class.
The answer to your question can be found by examining S1 ∩ S2
Related questions:
What benefit do method-local inner classes provide in Java?
Use of Java [Interfaces / Abstract classes]
Clarification: My point is that the two features (abstract classes and local classes) are two completely orthogonal features of the language. Understanding when each feature is useful is the key to understanding when they are both useful at the same time.
You can get the use here http://java-questions.com/InnerClass_interview_questions.html
which says
The inner class declared inside the method is called method local inner class. Method local inner class can only be declared as final or abstract. Method local class can only access global variables or method local variables if declared as final
ie You can declare the static variables in the inner call and use them in the methods.
EDIT: Why abstract:
Because if you dont want to create the objects of the inner class. If you create the object in the method then it will be stored in the heap and it is not freed even if the method execution completes as there might be an external reference for this object when it is returned from the method.
So it depends on whether you want to create an instance or not. If you want to create then use final modifier.
the only real use I can imagine is for nodes in a data structure
that way you can differentiate methods from sentinel nodes and normal data nodes which can be really handy in recursive algorithms and you don't have to null check each time
No, there is no good use for abstract classes (or classes in general) inside methods.
It would only make sense if only that particular method would need that particular class and would also implement it. Actually having that situation maybe happens once in trillions of methods you write.
Check out the section titled "Hierarchies of Inner Classes" on this page.
The gist is that you can treat the inner class as just another abstract member that needs to be overridden/implemented. I don't necessarily agree with it (I would probably just define the inner class separately), but I've seen things like this in the wild.
Here's their example code:
public abstract class BasicMonitorScreen {
private Dimension resolution;
public BasicMonitorScreen(final Dimension resolution) {
this.resolution = resolution;
}
public Dimension getResolution( ) {
return this.resolution;
}
protected abstract class PixelPoint {
private int x;
private int y;
public PixelPoint(final int x, final int y) {
this.x = x;
this.y = y;
}
public int getX( ) {
return x;
}
public int getY( ) {
return y;
}
}
}
public class ColorMonitorScreen extends BasicMonitorScreen {
public ColorMonitorScreen(final Dimension resolution) {
super(resolution);
}
protected class ColorPixelPoint extends PixelPoint {
private Color color;
public ColorPixelPoint(final int x, final int y, final Color color) {
super(x, y);
this.color = color;
}
public Color getColor( ) {
return this.color;
}
}
}
I think it can be useful to reduce the scope of methods in certain conditions.
For exemple, I use it in unit tests. Sometimes you need an utility method to reduce the verbosity of a test. But this utility method may be related to the current test dataset, and can't be reused outside of this test.
#Test
public void facetting_is_impacted_by_filtering() {
// given
String userId = "cd01d6b08bc29b012789ff0d05f8e8f1";
DocumentSolrClient client = solrClientsHolder.getDocumentClient(userId);
//
final SolrDocument doc1 = createDocument(userId);
doc1.setAuthorName("AuthorName1");
doc1.setType("Type1");
doc1.setUserTags(Arrays.asList("UserTag1", "UserTag1bis","UserTag1bisbis"));
doc1.setSenderTags(Arrays.asList("SenderTag1", "SenderTag1bis"));
doc1.setCreationDate( new Date(EnumDateRange.CURRENT_DAY.getBegin().getTime()+1000) );
doc1.setLocation(DocumentLocation.INBOX);
client.index(doc1);
//
final SolrDocument doc2 = createDocument(userId);
doc2.setAuthorName("AuthorName2");
doc2.setType("Type2");
doc2.setUserTags(Arrays.asList("UserTag2"));
doc2.setSenderTags(Arrays.asList("SenderTag2"));
doc2.setCreationDate( new Date(1000) ); // cree il y a tres longtemps
doc2.setLocation(DocumentLocation.SAFE);
client.index(doc2);
//
final List<DateRange> facettedRanges = Arrays.<DateRange>asList(
EnumDateRange.CURRENT_DAY,
EnumDateRange.CURRENT_YEAR,
EnumDateRange.BEFORE_CURRENT_YEAR
);
class TestUtils {
ApiSearchRequest baseFacettingRequest(String userId) {
ApiSearchRequest req = new ApiSearchRequest(userId);
req.setDocumentTypeFacets(true);
req.setSenderNameFacets(true);
req.setSenderTagsFacets(true);
req.setUserTagsFacets(true);
req.addDateCreationFacets(facettedRanges);
return req;
}
void assertDoc1FacettingResult(ApiSearchResponse res) {
assertThat(res.getDocuments().size()).isEqualTo(1);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(2);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(3);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1),facettedRanges) );
}
void assertDoc2FacettingResult(ApiSearchResponse res) {
assertThat(res.getDocuments().size()).isEqualTo(1);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(1);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(1);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc2),facettedRanges) );
}
}
TestUtils utils = new TestUtils();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
ApiSearchRequest req = utils.baseFacettingRequest(userId);
ApiSearchResponse res = documentSearchService.search(req);
// then
assertThat(res.getDocuments().size()).isEqualTo(2);
assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(2);
assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(2);
assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(3);
assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(4);
assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1,doc2),facettedRanges) );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addLocation(DocumentLocation.SAFE);
res = documentSearchService.search(req);
// then
utils.assertDoc2FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addUserTag("UserTag1");
res = documentSearchService.search(req);
// then
utils.assertDoc1FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.addSenderTag("SenderTag2");
res = documentSearchService.search(req);
// then
utils.assertDoc2FacettingResult(res);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// when
req = utils.baseFacettingRequest(userId);
req.setDocumentType("Type1");
res = documentSearchService.search(req);
// then
utils.assertDoc1FacettingResult(res);
}
In this real-life exemple, I could have done a regular inner class, but someone could have been tempted to reuse it in other tests, while it was not designed to.
By the way, you will notice the ability to "capture" the dataset build in the test directly inside the utility class. Using a regular inner class, it couldn't work without creating the test specific dataset outside the test too... so you end up with a lot of things shared with other tests, while they are used (should be used) by only one.
In the end, I don't think a feature permitting to reduce the visibility is useless.
You can build a perfectly working application without using encapsulation at all, and can argue the same thing, saying the private modifier is useless...
But yes, the private modifier is certainly more useful than method local innerclasses ;)
package dto;
public class Outer {
public void method(int x, int y){
abstract class Inner{
abstract void performAction(int x,int y);
}
class InnnerA extends Inner{
#Override
void performAction(int x,int y) {
int z =x+y;
System.out.println("addition :" + z);
}
}
class InnnerB extends Inner{
#Override
void performAction(int x,int y) {
System.out.println("multiply :"+x*y);
}
}
Inner inner1 = new InnnerA();
inner1.performAction(x,y);
Inner inner2 = new InnnerB();
inner2.performAction(x,y);
}
public static void main(String args[]){
Outer outer = new Outer();
outer.method(10,20);
}
}
You can use it like this.
I have a public class, which needs 7 parameters to be passed down. At the moment, I am able to make 3 of them being passed to constructor and another 4 to a public method in the class . Like this:
Public Class AClass{
private XClass axClass;
private String par4;
private String par5;
private String par6;
private String par7;
public AClass(String par1, String par2, String par3){
aXClass = new XClass(par1,par2,par3);
}
public execute(String par4,String par5, String par6, String par7){
//this is needed because they are used in other private methods in this class
this.par4 = par4;
this.par5 = par5;
this.par6 = par6;
this.par7 = par7;
//call other private methods within this class.
//about 7 lines here
}
}
My question is, is this the right way to ask client of the class to passing in paramters?
There shouldn't be anything stopping you from passing 7 parameters to a constructor, if that's what you want. I don't know if there's a maximum number of parameters that can be passed to a method in Java, but it's certainly higher than 7 if there is a max.
When you create a class and its public methods, you're creating an interface on how to use and access that class. So technically what you've done so far is correct. Is it the "right way" to ask the client of a class to pass in arguments? That's up to you, the designer of the interface.
My first instinct when I saw 7 parameters being passed was to silently ask "Is there some relationship between some or all of these parameters that might mean they'd go together well in a class of their own?" That might be something you address as you look at your code. But that's a question of design, not one of correctness.
I'd go for the Builder Pattern instead of many constructor parameters as suggested by
Effective Java Item 2: Consider a builder when faced with many constructor parameters
Here's a simple class to illustrate:
public class Dummy {
private final String foo;
private final String bar;
private final boolean baz;
private final int phleem;
protected Dummy(final Builder builder) {
this.foo = builder.foo;
this.bar = builder.bar;
this.baz = builder.baz;
this.phleem = builder.phleem;
}
public String getBar() {
return this.bar;
}
public String getFoo() {
return this.foo;
}
public int getPhleem() {
return this.phleem;
}
public boolean isBaz() {
return this.baz;
}
public static class Builder {
private String foo;
private String bar;
private boolean baz;
private int phleem;
public Dummy build() {
return new Dummy(this);
}
public Builder withBar(final String bar) {
this.bar = bar;
return this;
}
public Builder withBaz(final boolean baz) {
this.baz = baz;
return this;
}
public Builder withFoo(final String foo) {
this.foo = foo;
return this;
}
public Builder withPhleem(final int phleem) {
this.phleem = phleem;
return this;
}
}
}
You would instantiate it like this:
Dummy dummy = new Dummy.Builder()
.withFoo("abc")
.withBar("def")
.withBaz(true)
.withPhleem(123)
.build();
The nice part: you get all the benefits of constructor parameters (e.g. immutability if you want it), but you get readable code too.
Can't you just make a class/hashmap that stores these parameters and pass this to the function?
public excute(Storageclass storageClass){
//this is needed because they are used in other private methods in this class
this.par4 = storageClass.getPar4();
this.par5 = storageClass.getPar5();
this.par6 = storageClass.getPar6();
this.par7 = storageClass.getPar7();
//or
this.storageClass = storageClass;
}
I don't really see the problem with that.
In any case you could create a "Request" object or something like this:
class SomeClass {
private String a;
private String b;
....
public SomeClass( Request r ) {
this.a = r.get("a");
this.b = r.get("b");
...
}
public void execute( Request other ) {
this.d = other.get("d");
this.e = other.get("d");
...
}
}
See also: http://c2.com/cgi/wiki?TooManyParameters
Without knowing the use of the child class, I can say that there is nothing inherently wrong with what you have done.
Note though that you have to declare
private XClass axClass;
in the variables of your AClass.
However, you say 'I am able to make....' Does this mean there is some problem with declaring this another way?
I don't care for it much, because an object should be 100% ready to be used after its constructor is called. It's not as written in your example.
If the parameters passed into the execute method can simply be consumed, and that's the method of interest for clients, I see no reason for them to be data members in the class.
Without knowing more about your ultimate aims it's hard to tell. But I would re-think this implementation.
If you're planning on introducing an AClass.someMethod() that needs to know par4-7 without requiring you to have called AClass.excute(), then clearly you should be passing the parameters in the constructor.
On the other hand: if you can construct an instance of this object with only par1-3 and do something meaningful with it besides call excute() then it makes sense to allow the object to be constructed with fewer than the full seven parameters.
Yet my own aesthetic is to try and limit the number of "modes" that an object can be in which make certain methods work and others fail. So ideally, a fully-constructed object is ready to run any method the programmer might call. I'd worry about the design issue more than be too concerned about the sheer number of parameters to the constructor.
But as others have pointed out, sometimes there is a natural grouping of these parameters which can deserve objects of their own. For instance: in many APIs instead of passing (x, y, width, height) all over the place they use rectangle objects.
As others already wrote, it is technically correct to pass 7 parameters, although not very 'user-friendly', if you can say so.
Since you didn't write much about this class, I can suggest one small thing: in constructor you're just creating XClass object, so it would be sane to create this object before and pass it as a single parameter.
Something like this:
...
XClass aXClass = new XClass(par1, par2, par3);
AClass aClass = new AClass(aXClass);
...
And this is the constructor:
public AClass(XClass aXClass) {
this.aXClass = aXClass;
}