I have following class inheritances (A is my parent class):
In some cases, X and Y need some extra fields and methods. So what I basically need is this:
I don't want to extend X and Y to give their child classes exact the same fields and methods due to duplicate code.
How to handle this? Is the only solution a delegate?
Update: Real-world example:
I'm importing data from different file types:
Package my_application.core:
public class ImportFile { // the "A"
protected final Path path;
}
public class CsvImportFile extends ImportFile { // the "X"
private final String delimiter;
}
public class FixedLengthImportFile extends ImportFile { // the "Y"
// nothing new
}
public class XmlImportFile extends ImportFile {
private final String root;
}
Sometimes the first lines of a file contain heads/titles instead of data. So here an example extension which allows to set a start line for csv and fixed-length files:
Package my_application.extension.line_start:
public class ExtensionLineStartImportFile { // the "B"
protected final int lineStart;
// some methods
}
So if the user chooses to use the extension line_start, CsvImportFile and FixedLengthImportFile should get the properties of ExtensionLineStartImportFile.
Side node: Since I have multiple extensions which do different things and these extensions should be easy to add to/remove from the application, I don't want to merge them all into the "core".
Factory pattern - this is quite an architectural issue and this pattern should be the answer for Your problem
You cannot have "conditional inheritance" in Java. Either you extend a class, either you don't. Changing the legacy chain implies recompiling the application.
If a C extends B extends A but B is not on the classpath, the class loading of C will fail.
The only solution I see here is to integrate this logic into your code (or have as many implementations as there are possible combinations).
So, yes, delegates would be a way (probably the only one to have logic on your classpath only when you need it). Having multiple ugly ifs in your code is another.
Related
Nowadays we are on writing some core application that is all other application will be relying on. Without further due let me explain the logic with some codes,
We used to have a single java file that was 1000+ lines long and each application was having it as class inside, so when there was a change, each application had to edit the java file inside of it or simply fix one and copy to all. This is hard to implement as much as it is hard to maintain. Then we end-up with creating this as a separate application that is divided to smaller part, which is easy to maintain and also a core maybe a dependency to other application so we fix in one place and all other code applications are fixed too.
I've been thinking for a some great structure for this for a while want to use a builder patter for this as below
TheCore theCore = new TheCore().Builder()
.setSomething("params")
.setSomethingElse(true)
.build();
The problem arises now. Like so, I initialized the object but now I'm having access to that objects public class only. This application actually will have many small classes that has public functions that I don't want them to be static methods that can be called everytime. Instead I want those methods to be called only if TheCore class is initilized like;
// doSomething() will be from another class
theCore.doSomething()
There are some ideas I produced like
someOtherClass.doSomething(theCore)
which is injecting the main object as a parameter but still someOtherClass needs to be initialized or even a static method which doesn't make me feel comfortable and right way to that.
Actually I do not care if initializing TheCore would bring me a super object that includes all other classes inside initialized and ready to be accessed after I initialized TheCore. All I want in this structure to have a maintainable separate app and methods avaiable if only the main object which is TheCore is this circumstances is initialized.
What is to right way to achive it? I see that Java does not allow extending multiple classes even it if does, I'm not sure it that is right way...
Thanks.
After spending significant amount of time of thought I ended up that
// doSomething() will be from another class
theCore.doSomething()
is not suitable since many java classes could possibly have identical method names. So...
// doSomething() will be from another class
theCore.someOtherClass.doSomething()
would be a better approach.
To make it easier to understand I'll have to follow a complex path to explain it which is starting from the package classes first.
Think that I have a package named Tools and a class inside SomeFancyTool
main
└─java
└─com
└─<domainName>
├─Tools
| └─SomeFancyTool.java
└─TheCore.java
Now this SomeFancyTool.java must have a default access level which is actually package level access, because I don't want this classes to be accessed directly;
SomeFancyTool.java
package com.<domainName>.Tools
class SomeFancyTool{
public String someStringMethod(){
return "Some string!";
}
public int someIntMethod(){
return 123;
}
public boolean someBooleanMethod(){
return true;
}
}
So now we have the SomeFancyTool.java class but TheCore.java cannot access it since it is accesible through its Tools package only. At this point I think of an Initializer class that is gonna be in the same package, initialize these private classes and return them with a function when called. So initiliazer class would look like this;
ToolsInitializer.java
package com.<domainName>.Tools
public class ToolsInitializer{
private SomeFancyTool someFancyTool = new SomeFancyTool();
public SomeFancyTool getSomeFancyTool(){
return someFancyTool;
}
}
Since ToolsInitializer.java can initialize all functional private classes inside in Tools package and also can return them as objects to outside of the package scope, still we are not able to use these methods as we cannot import com.<domainName>.SomeFancyTool from TheCore.java because it is package wide accessible. I think here we can benefit from implementation of the java interface. A class that is not functional alone, so no problem even if it is accessed since it's methods will be nothing but declarations.
At this point I'll rename SomeFancyTool.java to SomeFancyToolImplementation.java which it will be implementing the interface and call SomeFancyTool.java to the interface itself.
SomeFancyTool.java (now as an interface)
package com.<domainName>.Tools
public interface SomeFancyTool{
public String someStringMethod();
public int someIntMethod();
public boolean someBooleanMethod();
}
and lets rename prior SomeFancyTool.java and implement the interface
SomeFancyToolImplementation.java (renamed)
package com.<domainName>.Tools
class SomeFancyToolImplementation implements SomeFancyTool{
#override
public String someStringMethod(){
return "Some string!";
}
#override
public int someIntMethod(){
return 123;
}
#override
public boolean someBooleanMethod(){
return true;
}
}
Now our structure has become like this with the final edits;
main
└─java
└─com
└─<domainName>
├─Tools
| ├─SomeFancyTool.java
| ├─SomeFancyToolImplementation.java
| └─ToolsInitializer.java
└─TheCore.java
Finally we can use our TheCore.java class to call all initializer classes with their methods to receive all these private classes inside as an object. This will allow external apps to call and initialize TheCore first to be able to access other methods.
TheCore.java
public class TheCore{
private SomeFancyToolImplementation someFancyTool;
public static class Builder{
private SomeFancyToolImplementation someFancyTool;
public Builder(){
ToolsInitializer toolsInitializer = new ToolsInitializer();
someFancyTool = toolsInitializer.getSomeFancyTool();
}
public Builder setSomeValues(){
//some values that is needed.
return this;
}
public Builder setSomeMoreValues(){
//some values that is needed.
return this;
}
public TheCore build(){
TheCore theCore = new TheCore();
theCore.someFancyTool = someFancyTool;
return theCore;
}
}
}
All Done and it is ready to use. Now the functional package classes and its methods that it relying on if TheCore is initialized or not, cannot be accessed with out TheCore. And simple usage of this Library from a 3rd Party app would simply be;
3rd Party App
TheCore theCore = new TheCore.Builder()
.setSomeValues("Some Values")
.setMoreSomeValues("Some More Values")
.build();
theCore.someFancyTool.someStringMethod();
Note: Note that a the ToolsInitializer.java is still accessible and could be used the get private method without first calling TheCore but we can always set a checker inside getSomeFancyTool() method to throw error if some prerequisites are not satisfied.
I do not still know if this is a functional structural pattern to use or its just some hard thoughts of mine. And don't know if some pattern is already exist that I just could not see yet but this is the solution I end up with.
I have class named: ComplexValidator that extends absract class Validator which have two methods:
Validate(Part part);
getAnswer():
I also have validators, lets name them A, B, C and D.
So
AValidator extends Validator
BValidator extends Validator
CValidator extends Validator
DValidator extends Validator
I am not in front of my code right not so I will use pseudo-code.
CValidator takes different parameter than rest of it, A B and D uses part to get filename etc, but CValidator uses numberOfFiles (which are increased in loop (for part p: multipart) so after every time loop is repeated numberoffiles is increased so I can compare it with maxNumberOfFiles field).
Sadly I didnt know how to make abstract class that will take any parameter to method so all methods must take Part part. Cvalidator doesnt use it and I had to make field numberOfFiles static so I can get access to it.
Is there any way to make those validators takes no parameters but no using static?
Is there any way to make abstract class the way that child classes will be able to change arguments it take?
And if it takes other arguments HOW can I loop it all when I have:
List <Validator> validators = new ArrayList<>();
in my ComplexValidator.
and then I add all child validators to it and loop over them like that:
for (Validator v: validators){
validate(part);
}
The types of the parameters of an overriden method must be the same as the original method.
To face your problem I would create a custom class that wraps all the different parameters that you might want to pass to the validate function.
Something like that
class Wrapper{
Part param1;
File param2;
File param3;
}
class Validator{
void validate (Wrapper wrapper);
}
class ValidatorA extends Validate{
void validate (Wrapper wrapper){
//use wrapper.part...
}
}
class ValidatorC extends Validate{
void validate (Wrapper wrapper){
//use wrapper.file...
}
}
You may want to use java reflection. With a Class you can either getMethods and loop throught the methods and getParameterTypes of each method or if you know in advance the types of the method you wish you can getMethod (without s) and provide an array of type.
In your case I would go to the first method and depending on the presence of the second parameter (number of files), invoke the method the good way (with all the parameters needed).
Background: I'm using Google Guice and so it's easier to pass through the configuration class but I think this is not the best way.
I have a configuration class which stores some paths:
class Configuration{
String getHomePath();
String getUserPath();
}
Also I have a class "a" which needs the "homepath" and a class "b" which needs the "userpath".
Is it better to pass the configuration class through the constructor of class a and b or only pass through the specific path?
If you're really using Guice correctly all your configuration like this should appear in modules' configure method. So:
Remove the configuration class.
Create annotation classes, probably called HomePath and UserPath.
Where class a uses getHomePath() replace that with a String field member named homePath.
Where class b uses getUserPath() replace that with a String field member named userPath.
Modify the class a and b constructors to be #Inject annotated (should already be) and take in a String parameter, respectively annotated with #HomePath and #UserPath and assign the String field member that injected value.
Create bindings in your module's configure method use .annotatedWith() which define correct values; if they're only available at run time, bind a provider.
E.G.
class a {
private String homePath;
#Inject
public a(#HomePath String homePath) {
this.homePath = homePath;
}
public String tellMeAboutHome() {
return "We live in a nice home called " + homePath;
}
}
class customModule extends AbstractModule {
public static final String userPath = "/home/rafael";
public void configure() {
bind(String.class).annotatedWith(HomePath.class).to("/home/");
bind(String.class).annotatedWith(UserPath.class).to(userPath);
}
}
If creating annotations is too much work for you, use the #Named annotation Guice ships with.
There's no single answer to your question, there are only options to choose from, based on your specific situation.
If you know your Configuration class is going to grow AND if it's likely for your A and B classes will use more from it, then pass the whole Configuration object to their constructors. NB: I know this is against the YAGNI principle but sometimes you may know you're gonna need it ;-)
Otherwise, you can consider using #Named injection of your paths so that you reduce A and B classes dependencies to their minimum, which is a good design practice.
The general rule is code to make the dependency graph (which classes know about or depend on other classes/ interfaces) as simple, regular and fixed as possible.
If not passing the Configuration class makes a or b have zero dependencies on on user-written classes, or is necessary to avoid a dependency loop, then use the individual path strings. Otherwise, if it makes more sense to say 'this class has access to configuration info, in a way that may change in the future', pass the class.
I'd avoid the singleton approach, especially if you already have Guice set up.
In the case of classes:
If we use the factory method we'll have to return created implementation as the type of an implemented interface.
public class Factory {
public Product getProduct() {
return new ProductA();
}
}
public interface Product {
}
class ProductA implements Product {
}
To avoid client's ability to cast returned Product to concrete implementation of the Product{A, B, C... etc.} we have to:
package client's and factory's code separately (let's say com.example.client and com.example.factory)
declare concrete implemantations with the default ("package") access (visible to Factory, not visible to Client)
package com.example.client;
...
public class Client {
public static void main(String[] args) {
Product i = new Factory().getProduct();
ProductA a = (ProductA) i; // the type of ProductA isn't visible.
}
}
In the case of methods:
For example we need to use the same factory with the hidden method
public class Factory {
public Product getProduct() {
return new ProductA();
}
Product[] getCreatedProducts() {
...
}
}
I see two problems here:
bad package structure: hidden classes and methods must be in one package with the calling code.
bad code: less intuitive and understandable. It's easy to break with the replacement of java files to another package.
The "default" access does not guarantee much of anything, since any rogue programmer can declare their class in your package. Also, regardless of your package structure, in java, you almost always can do an "instance of" check, and then downcast to the "instance of" type. So, if your goal is to prevent any downcasting whatsoever, you must use the private keyword. For example, you can declare the concrete implementations of your Product interface as private static or as anonymous inner classes within your Factory. Indeed, in Bloch's "How to design a good API" article, he makes a point that you should "Minimize Accessibility of Everything."
That said, I think you're being a little paranoid here. Does it really matter that much to you if somebody downcasts? Any code that you write can be misused, and certainly if you include a well-documented factory then you have provided clear information about how to use your API properly. Also, if you build a real factory method that takes arguments and has clear method names, as opposed to this toy Factory example that takes no arguments, then I think you'll find that you're broadcasting the publicly relevant part of what's being created anyway.
I do not really understand why do you want to put factory and classes to separate packages.
I usually create public interface, public factory class and package protected implementations in the same package. So client can create instances using factory only and cannot down cast because the concrete classes are not visible from other package.
In your case here, you have the client knows the factory which knows the implementation class. If they are all in the same process, then both the client and the implementation class are loaded into the same process, which means that the client can have access to the underlying methods of the implementation class via reflection. This assumes that you do not have complete control over the client runtime, i.e. taking measures to prevent reflection. However, if you did, then you probably wouldn't need to worry about the inability of the client to cast to the implementation class.
So, if you view this as a potential security mechanism against an untrusted client process, then I wouldn't put any faith in it. If you have control over the client, then this is probably good enough to keep errant programmers from making an unintentional mess.
I do not see the advantage of two packages. I suggest this alternative:
package com.example.client ;
public interface Product
{
/* stuff */
}
package com.example.client ;
public interface ProductFactory
{
Product make ( X1 x1 , X2 x2 , /* parameters */ , Xn xn ) ;
}
package com.example.manager;
interface ManagedProduct extends com.example.client.Product
{
/* management methods */
}
package com.example.manager ;
public final class DefaultProductFactory implements com.example.client.ProductFactory
{
public static final DefaultProductFactory instance = new DefaultProductFactory ( ) ;
private DefaultProductFactory ( )
{
super ( ) ;
}
public ManagedProduct make ( final X1 x1 , final X2 x2 , /* parameters */ , final Xn xn )
{
return new ManagedProduct ( )
{
/* implementation logic here */
} ;
}
/*
possibly other methods
The Product implementation class is invisible.
*/
}
Using two packages unnecessarily exposes the implementation Product class to the com.example.manager.DefaultProductFactory class. I would argue that my approach is superior to Bringer128's private inner class Factory. With my approach, the implementation Product class is even invisible to other methods that may exist in the implementation Factory class.
If you make the parameters final, then you can use them in the implementation Product class directly from the method arguments (no need to (1) create X1 x1, X2 x2, ..., Xn xn members; (2) this.x1=x1, this.x2=x2, ..., and this.xn=xn in the constructor; and (3) invoke the constructor with ProductImpl (x1,x2,...,xn). This is admittedly small but it saves you keystrokes.
I strongly agree with philwb. This should not be regarded as security.
This allows classes in com.example.manager to have more methods on the same object than classes in other packages - as requested in Is this a good practice to use the "default" Java access to hide classes and methods from client.
I'm trying to figure out how test a small library I'm working on . Using this simplified method as an example:
private int countMappableFields(Class<?> type) {
int mappableFields = 0;
Field[] fields = type.getFields();
for (int i = 0; i < fields.length ; i++) {
if (FieldHelper.isMappable(fields[i]))
mappableFields++;
}
return mappableFields;
}
Should I define a couple of classes in separate files and reference them in all my tests? Is there a different approach that will allow to construct an object for each case?
You can define the classes inline in your test class; there's no reason to make separate files for them.
public class TestCase {
private static class NoFieldClass
{
}
// And so on.
#Test
public void shouldFindZeroMappableFieldsInNoFieldClass() {
assertTrue(0 == countMappableFields(NoFieldClass.class));
}
}
This keeps your test source code area clean. It will create multiple class files, but at least the inline classes you define will look like "TestCase$NoFieldClass.class" instead of being the top-level "NoFieldClass.class".
I'd typically just make a private static class inside the test class for that sort of thing. If you have multiple test files needing to do the same sort of thing, you might want to create top level classes instead.
Depends on what you're testing for. If you're doing some sort of customized reflection (e.g. FieldHelper is only returning a subset of fields for some reason) you might want to actually test the objects you're going to be using it on) - i.e. actually run your reflection tests on a map<CLass,Integer> where the classes are mapped to the expected values.