AbstractFactory with a twist - java

I am stuck with a programming problem:
I have two Java projects, in my Eclipse IDE: ProjectA, and ProjectB.
ProjectB references ProjectA
I have declared a class in ProjectA: ClassA, and one in ProjectB: ClassB, such that:
public class ClassA{
public static Object foo(){
//blah
}
}
public class ClassB extends ClassA{
public static Object foo(){
//blah
}
}
I also have a class called ClientClass, in ProjectA. This ClientClass earlier used to create an instance of ClassA and use it. But now, based on an environment setting, the ClientClass should be provided the option to use ClassA or ClassB.
This seemed to be a problem for the AbstractFactory pattern, or so I thought.
I need to create a Factory that provides access to ClassA or ClassB. ClientClass should not be aware that it is ClassA or ClassB. This requires me to create an interface for ClassA and ClassB.
Issues I ran into:
ClientClass cannot refer to ClassB directly (no import statements / or new invocation), because ClassB is in a different project. This may be an Eclipse IDE restriction, but it also makes sense to me when viewing these two projects as jar files. A cyclic relationship is avoidable.
I cannot create a Factory interface and a common interface for ClassA & ClassB, and then via the AbstractFactory pattern provide a ClassAFactory or a ClassBFactory. This is because the methods to be invoked on ClassA and ClassB are static ones. The methods on these classes would need to be present on the interface. But then, in Java, one can't have an "abstract static" modifier
Can anyone suggest an elegant solution for this problem?

Well, there are a number of problems here. For starters, and this is the biggest one, this isn't going to work because you can't override static methods in Java. The goal, I think, of what you're saying is to be able to substitute, at run time, ClassA for ClassB or B or A or whatever, depending on some parameters. In order to do that, you need to be able to take advantage of dynamic dispatch (or, simply put, virtual methods) that would allow the runtime system to select the memory address of the method to be executed at run time. This isn't possible with static methods. You need to make the methods nonstatic for this to work. You don't have to specifically design a Java Interface but when you extend ClassA with ClassB, you'll be able to treat your objects as if they are simply a ClassA object.
All of that said, if you remove the static modifiers from the methods and make them nonstatic, then you could use ClassB in project A without having any import statements what-so-ever in the client class you're talking about. However, somewhere in project A, somebody is going to need to be aware of ClassB in order to instantiate it. That is, of course, unless you want to do some runtime binding stuff and load the class dynamically using a string. Does that make sense?

Firs problem: Your Class B and Class A's foo method is static. Hence nothing is being overriden. You should not make them static if you intend to override foo in ClassB.
The second problem here is that upstream needs to be aware of the downstream. That is just wrong isn't it?
The question of whether this is an abstract factor pattern or not is besides the point. Design patterns just make code follow a known structure. It is not an end in itself.
For now, why is it that your ClientClass in Project A needs to know about ClientB?
As for the factory, your factory needs to be in Project B and it can be something like:
class Factory {
public static ClassA createTheRightOne(EnvironmentSettings settings) { //do the right thing }
}
once you fix the static modifier
Pavan

Related

Hide classes from my library (aar)

im trying to create my little library. But i have little problem. I cant right understand how to hide some classes/methods from public usage.
Say i have structure :
-myPackage.com
-classA (public class example : public classA {...})
-classB (just a class example : class classB {...}
in this way when i add my aar file to android project. I can use from library only classA. classB hided(invisible for developer) and i cant call him (its ok). But classA can use functions from classB . Because its in same package. And its ok.
So how correctly create classes in another packages ?
-myPackage.com
-myHelpPackage
-classC (public class example: public class classC {...}
-classD (just a class example: class classD {...}
-classA (public class example : public classA {...})
-classB (just a class example : class classB {...}
in this way i have two public classes which developer can call
classA
classC
classD visible only for classA. So i cant call classD(functions) from classA.
Main question : how to achive it ?
I want to have only one classA to call. classC is ok. classD and classB should be invisible for developer. But visible only for classA. Anyone can help me with this ?
If you don't specify any access level modifier, e.g.:
package myPackage.com
class classA {
}
then the class will be package-private by default.
This means it is only visible to classes inside your package.
See also the documentation by Oracle here
This question has been answered in the comments by JakobJeremais, but in case it's not clear to anyone, or they skip over it because they only read top-level answers (understandable). If you have a package-private class in your aar, it will still be publicly accessible, so I would recommend nesting the class in whatever calls it, an you will be safe.
For instance, I had to extend EditText so that I could override just one method, and nothing else. Then I had to reference that from only one other class, but didn't want it accessible from whatever projects I added my library to. So I nested it, and now it's fine.
public class VisibleClass extends View {
public static HiddenClass extends EditTextCompat {
#Override
public void annoyingFunction() {
//Disable this function
}
}
}
I should note, though: The compiler isn't happy about accessing it from layout, so I suppose it hasn't really helped, so I wouldn't recommend it, for now. If you have time to tinker, go ahead, though.

How to make one method be called by some classes, but the rest could not?

There is one class named ClassA, it has one public function named FunctionA.
There is another class named ClassB, it needs to use FunctionA and it is not a subclass of ClassA.
The third one named ClassC, FunctionA should not be called by ClassC and it is not a subclass of ClassA.
In addition, the relationship between ClassB and ClassC is not inheritance.
If there are some solutions provided? or if there are suitable design patterns?
Thanks for help.
You can place ClassA and ClassB in the same package (and ClassC in the other) and use package-private (or default) access modifier for method FunctionA.
This solution is the easiest and uses only JLS specs (works for any language level and on any JVM implementation):
Example 6.6-4. Access to Package-Access Fields, Methods, and Constructors
If none of the access modifiers public, protected, or private are specified, a class member or constructor has package access: it is accessible throughout the package that contains the declaration of the class in which the class member is declared, but the class member or constructor is not accessible in any other package.
Other ways to deal with your problem - reflection, code generation etc - is much more complex, buggy and slow
PS: also it is possible to leave method FunctionA public and decompose your application into two modules. In the first module you should place ClassA and ClassB and in the second ClassC. First module can use the second as a dependency but the second one shouldn't have an access to the first. This way is more suitable for complex applications and I recommended to use build tools such as Maven or Gradle to handle with such oriented dependency graphs (may be very tricky for large scale apps)
Maybe the Interface segregation principle, one of the SOLID principles, can solve your issue.
Make class A implement an interface AB that is used by class B and an interface AC that is used by class C. In this way class C doesn't see the methods provided for class B.

Write own dependency injection

we are developing an application. The application will be deployed in a proprietary event processing engine. We are not supposed to use any api such as spring core for DI. There are not proprietary DI frameworks yet. So the idea is to write one and a simple one.
Can any one please provide some inputs.
My idea is to write a factory class which has static methods in it. The static methods will return instances of the classes we want. For now we only want a single instance. I am assuming the below kind of code
public final class MyFactory {
private static ClassA classA = new ClassA();
private static ClassB classB = new ClassB();
private MyFactory() {
throw new CustomException("Cannot create instance");
}
public static ClassA getClassAInstance() {
return classA;
}
public static ClassB getClassBInstance() {
return classB;
}
}
Later I will use it like this
public class SomeRandomClass {
private ClassA classA = MyFactory.getClassAInstance();
}
Other thing I see is I need not test ClassA and ClassB. Testing SomeRandomClass will cover ClassA and ClassB. Because static content is always loaded first. So while testing SomeRandomClass I always have ClassA instance in it. So writing a junit on some method in SomeRandomClass will invoke methods in ClassA. Is this good?
Is it the right way I am doing? Can I improve it even?
For starters, the factory API shouldn't reference the concrete class implementations directly like that. It kind of defeats the purpose. You won't be able to change the concrete classes without recompiling and you won't be able to do things like stubbing out interfaces for testing and development.
Then, assuming you want singletons (which is not how your example is written), you'll need to make sure your factory methods are thread safe in how they produce the singletons.
You should at a minimum have your factory return true singleton instances of interfaces. Then, you could implement some kind of configuration system and use the Java reflection API to determine which concrete classes should be created at runtime. This will also enable you to do things like stub out the interfaces for testing or development.
This isn't really DI. There's a lot more to it and it has benefits in readability/writability/configurability/maintainability that go far beyond what a factory can provide. I'm not sure why using Spring would be a problem in proprietary software. AFAIK Spring's license doesn't force code to be open source or free...

JMockit : How to avoid code from superclasses' constructors

I need to test a class SportCar, which extends Car. The problem is that when I create my object under test
SportCar car = new SportCar();
it will also call the constructor from parent classes, for example, Car(). Those constructors do a lot of things, have a lot of environment dependencies and need a lot of configuration files I don't have, so I would like to create an instance of SportCar without calling inherited constructors.
The only solution I know for this is to create a Mockup for Car in which I overwrite constructor ($init) and static block ($clinit). But now my problem is, what happens if there are many classes in my hierarchy (SportCar extends Car that extends A that extends B that extends C...) and I want to avoid all the constructors? Should I create Mocks for ALL the previous classes?
class A extends B{
public A(){
// Plenty of things to avoid during tests
}
}
class Car extends A{
public Car(){
// Plenty of things to avoid during tests
}
}
class SportCar extends Car(){
}
If you are using jmockit, you do not have to do anything at all, as all the superclass constructors are mocked by default. In you unit test method you can just do:
public void testMockedStuff(#Mocked final ClassToBeMocked instance) {
to have evrything mocked away for you. You do not even have to create instances yourself.
Then you can modify annotation parameters to exclude methods you are teting from mocking.
Create a protected "do nothing" constructor in Car and have a protected constructor in SportsCar that calls it and call that from your test class, which can see that constructor btw - it has the privileges to do so.
This could be considered a slight stretch of the "design for test" pattern.
You can suppress the parent constructor using PowerMock
suppress(constructor(EvilParent.class));
However, if you have to do a lot of unit tests it may be worth figuring out how to fake out the enironment as well. Or convince other developers to let you do a little refactoring to allow service injection at least.

Is it possible that Different child classes have different visibility to the methods of the Parent in java

Is it possible that different child classes have different visibilities to the methods of the parent. Suppose there is a class A which has 10 methods defined. It has two different child ClassB and ClassC. Is it possible that that ClassB and ClassC has access to different methods of ClassA. Like ClassB has access to only 6 of 10 methods defined in ClassA and ClassC has acess only to the other 4 methods of ClassA? ClassB and ClassC are in same package.
Thanks,
Asit
I don't think it is possible with classes. To segregate functionality you should use interfaces instead of extending classes.
It is quite likely that your class A is violating the Single Responsibility Principal if you need to divide methods like that.
Then look to use composition instead of inheritance to compose complex classes from the simpler ones. Also take a look at the strategy pattern.
Divide your functionality in interfaces like this -
public interface IFlyable
{
void FlapWings();
void Fly();
}
public interface IHuntingAnimal
{
void Hunt();
}
Then implement your classes like this -
public class Duck : IFlyable { ...
public class Eagle : IFlyable, IHuntingAnimal { ...
public class Tiger : IHuntingAnimal { ..
Note: The example is in C#. You need to work out the java equivalent.
You can do such a thing with interfaces, but not concrete classes.
Adapter or Decorator pattern will help you.
From you wrote, i suppose what you have is
package first;
class A {
protected methodA() {...}
private methodB() {...}
public methodC() {...}
methodD() {...}
}
package second;
class B extends A {...}
class C extends A {...}
In this case, B and C will only see methods methodA and methodC from class A.
methodB is private, so unreachable
methodD is package protected, that's to say restricted to classes in same packgae (a weird way to have an equivalent of the C++ friend keyword, I realize now), and as a consequence not visible outside of packgae first.
not really understood what do you mean...
it is generally possible that methods of a parent class have different access modifiers as possible inherent classes. but with one condition (citation from lang spec):
The access modifier of an overriding or hiding method must provide at least as much access as the overridden or hidden method, or a compile-time error occurs.
you cannot coarct usability of a class, i.e. if a method from your class A was "protected" then you can declare an overriding method in your class B as "public". but it doesn't work vice-versa
I don't know the context of your question so I can't comment as to whether your design is sound and by extension, whether your motivation for this is justified. Since others have already taken the stance that your ClassA requires refactoring, I'm going to do the opposite and assume that it's a sensible class with a single well-defined purpose and it doesn't require subdivision.
In which case, why not use the object adapter pattern to achieve what you're after? You can expose the ClassA methods you want to in your ClassB and ClassC adapters by implementing wrapper methods which forward invocations to your ClassA adaptee. And of course, you can optionally extend those methods.
This answer is predicated on your use of the term child class
Short answer no
Longer answer
In this situation:
class Base has the following methods: method1, method2, method3
There is no way, using Java, to setup the following situation:
class Derived1 (this class extends class Base) can access method1 and method2, but cannot access method3.
class Derived2 (this class extends class Base) can access method1, method2, and method3.
Both classes are in the same package.
In Java, when one class extends another class these things always apply:
The derived class may call every public method of the base class.
The derived class may call every protected method of the base class.
The derived class may not call any private method of the base class.
If the derived class is in the same package as the base class,
the derived class may call every package access method of the base class.

Categories