I want to ask you something more on this matter for the below code for SOLID. If all these 3 classes are are following SOLID concept.
public interface A {
public void calculate(String a);
}
public class B implements A {
#Override
public void calculate(String b) {
System.out.println("value: " + b);
}
}
public class C {
private A a;
public void show() {
a = new B();
a.calculate("test");
}
}
From how I look at things,
Class C breaks the
Single Responsibility Principle by handling two responsibilities, namely, instantiating other objects(instance of B) and the show functionality whatever that is. Object creation should be handled by a separate class and the dependencies should be injected to the users.
Open Closed Principle by being tightly coupled to B, whereas it could have depended on the interface A, thus being open for extension by using another implementation of A. See this for more information. In other words, C should have used A, and the actual implementation should have been injected to C.
Following is how you could write C to be SOLID.
class C {
private A a;
public C(A a) {
super();
this.a = a;
}
public void show() {
a.calculate("test");
}
}
class Creator {
C createC() {
A b = new B();
return new C(b);
}
}
Creator could be replaced by a dependency injection framework like Spring.
I hope the below code snippet is following SOLID strongly.
public class Creator {
public static A getA(){
A a = new B();
return a;
}
}
public class C {
private A a;
public void show() {
setB();
a.calculate("test");
}
private void setB(){
a = Creator.getA();
}
}
Related
I have 3 Data Classes
#Data
class A
{
private int a;
}
#Data
class B extends A
{
private int b;
}
#Data
class C extends A
{
private int c;
}
Class B and C have some common fields between them which is kept in their parent class A.
Following is the tester class
class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args) // assume this to be the client
{
A a;
if (bOrC.equals("B")) {
B b = new B();
b.setB(11);
a = b;
} else {
C c = new C();
c.setC(12);
a = c;
}
a.setA(10);
doSomething(bOrC, a);
}
// Below are the service methods
// only this method in the service exposed
public static void doSomething(String bOrC, A a) {
if (bOrC.equals("B")) {
doSomethingWithB(a);
} else if (bOrC.equals("C")) {
doSomethingWithC(a);
}
}
public static void doSomethingWithB(A a) {
B b = (B) a; // possible ClassCastException
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(A a) {
C c = (C) a; // possible ClassCastException
System.out.println(c.getA());
System.out.println(c.getC());
}
}
Now the problem I see with this is unsafe Dynamic Type Casting which can run into Class Cast Problems. One possible solution would be to create separate data objects and set the common fields (which are too many for my actual case) for both the objects separately in both classes B and C which would then look as follows:
public class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args)
{
if (bOrC.equals("B")) {
B b = new B();
b.setA(10); // duplication
b.setB(11);
doSomethingWithB(b);
} else {
C c = new C();
c.setA(10); // duplication
c.setC(12);
doSomethingWithC(c);
}
}
public static void doSomethingWithB(B b) {
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(C c) {
System.out.println(c.getA());
System.out.println(c.getC());
}
}
I'm looking for a way to avoid this dynamic type casting but at the same time avoid having to duplicate the common variables. Can anyone suggest a solution?
Abstraction is one solution for the behavior you are explaining. Creating an abstract method doSomething(...) in class A and implementing it in child class B and C respectively. By doing this you don't need to have a static method and processing will be done bases on the instance of B or C objects itself.
#Data
class A
{
private int a;
public abstract void doSomething();
}
#Data
class B extends A
{
private int b;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with #Data you will have access to getA() method, * hence you can also use parent properties.
*/
}
}
#Data
class C extends A
{
private int c;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with #Data you will have access to
* getA() method, * hence you can also use parent properties.
*/
}
Now you can use it as below
public static void main(Strings[] args){
A a;
B b = new B();
b.setB(10);
b.doSomething();
C c = new C();
c.setC(30);
c.doSomething();
}
I have following situation and would like to know the best way to design my solution
public abstract class A {
public abstract A getHelper();
public abstract void launchHandle();
public static A initHelper(String condition) throws Exception {
if ( condition == 'xyz') {
return C.getHelper();
} else {
return B.getHelper();
}
}
}
public class B extends A {
protected static A b;
#Override
public A getHelper() {
b = new B();
return b;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle");
}
public String getName() {
return "I am from Class B";
}
}
public class C extends A {
protected static A c;
#Override
public A getHelper() {
c = new C();
return c;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle from C");
}
public String getValue() {
return "I am from Class C";
}
}
**Executor class**
public class Executor {
public static void main(String[] args) {
A aa = a.initHelper(condition);
}
}
Now in the above approach, i am unable to access methods like aa.getName() from Class B OR aa.getValue() from Class C, which makes sense. However how to get these methods in executor class? Executor does not know anything about Class B & C and should not know. Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
Please help design this and what could be best way to solve this.
Thanks in advance.
Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
If you take a closer look at your code, you will notice that the only contract constant across all your classes is the launchHandle method (baring getHelper and initHelper which are simply used for instantiating the right subclass). There is no real relation between B and C other than the fact that their instantiation is controlled by A.
This is how I would consider approaching the problem :
Executor Factory
Make Executor an abstract class rather than making it the entry point of your program :
public abstract class Executor {
public abstract void performTask();
public static void execute(String condition) {
Executor executor = null;
if ( condition.equals("xyz")) {
executor = new AExector();
} else {
executor = new BExecutor();
}
executor.performTask();
}
}
Executor implementations
Create a different implementation for operating on B called BExecutor :
public class BExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from B");
//create or get data to perform the task on
B b = new B();
String name = b.getName();
System.out.println("I am from "+name);
}
}
Create a different implementation for operating on C called CExecutor :
public class CExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from C");
//create or get data to perform the task on
C c = new C();
String value = c.getValue();
System.out.println("I am from "+value);
}
}
Your main method can then look like this :
public static void main(String []args) {
Executor executor = Executor.execute(condition);
}
And for some reason, if you do find some common contract between B and C, you an always create an interface which both B and C can implement and use a reference of this interface instead of using a B or C reference.
Add getName and getValue to A as abstract methods.
I have a basic class structure like this:
public class A {
}
public class B extends A {
private C objC;
public B() {
this.objC = new C();
}
}
public class C extends A {
private B objB;
public C() {
this.objB = new B();
}
}
I need B and C to know about each other so they can access each other's methods but obviously at runtime this creates a cyclic dependency and results in a java.lang.StackOverflowError: null. I have read this and this but I can't seem to get a good resolution on what I should do in my case.
Is there a better way to approach this?
Edit 1: A more descriptive of my situation while keeping simplicity:
public class A {
}
public class B extends A {
private C objC;
public B() {
this.objC = new C();
}
public String foo1() {
int x = C.foo3();
//do something
return Integer.toString(int);
}
public int foo2() {
// do something
}
}
public class C extends A {
private B objB;
public C() {
this.objB = new B();
}
public int foo3() {
int y = B.foo2();
//do something
return y;
}
}
Use Mediator pattern if you want to establish communication among different objects.
Mediator - defines the interface for communication between Colleague objects
ConcreteMediator - implements the Mediator interface and coordinates communication between Colleague objects. It is aware of all the Colleagues and their purpose with regards to inter communication.
ConcreteColleague - communicates with other Colleagues through its Mediator
Have a look at this link : https://en.m.wikipedia.org/wiki/Mediator_pattern
I see quite a lot of this kind of design patterns in our code. Does it look reasonable to you?
interface A {
void doSmth();
}
interface B extends A {
}
class C implements A {
A a;
public C(A a) {
this.a = a;
}
#Override
public void doSmth() {
}
}
class D implements B {
A a;
public D() {
a = new C(this);
}
#Override
public void doSmth() {
a.doSmth();
}
}
This seems to be a "composition" or "strategy" pattern. Using IoC you pass the class which is actually responsible of doing something.
Without knowing the purpose of your SW and your requirements, it is not easy to give you an answer, but in any case, it is a good design to rely on such patterns.
Can one create an extensible class hierarchy in java whose methods are fluent and can be invoked in any order? (YES! see answer below), even for existing classes when you don't have access to the source, provided the methods are fluant!
I'm retrofitting an existing hierarchy and hope to use a factory or at least a generic constructor and (eventually) immutable builder patterns (JB P.14). The methods that set fields return void - it would be better for them to return a generic T instead - that way we will gain the ability to do method chaining (they all call super now).
Goals:
1. Avoid having to create a static getFactory() method in every class.
2. Simple method signatures.
3. Create a factory method that is generic, yet will catch problems at compile time.
4. Get compile time errors instead of run time errors when mistakes are made.
As requested, the non-generic code is very simple, but doesn't work.
public class A {
private String a = null;
protected A setA(String a){
this.a = a;
return this;//<== DESIRE THIS TO BE CHAINABLE
}
protected static A factory(){
return new A();
}
}
.
public class B extends A {
private String b = null;
protected Foo setB(String b){
this.b = b;
return this;//<== DESIRE THIS TO BE CHAINABLE
}
protected static B factory(){
return new B();
}
}
Now a caller could TRY to call B.factory().setA("a").setB("b")//won't compile
But that can't compile because setA() returns an A, not a B. You COULD make it work by overriding the setA() in B, calling setB() and returning B instead of the A. To avoid delegating for each of those methods is the point. I simply want an extensible group of chainable class methods that can be invoked in any order. B.getFactory().B("b").A("a") works obviously.
The answer (to my surprise and satisfaction) is YES. I answered this question myself:
You can do this with a little work if the method invocations return instances of the class in question (see chainable below). I also found an even easier way do this if you can edit the top level source:
In the top level class (A):
protected final <T> T a(T type) {
return type
}
Assuming C extends B and B extends A.
Invoking:
C c = new C();
//Any order is fine and you have compile time safety and IDE assistance.
c.setA("a").a(c).setB("b").a(c).setC("c");
Example 1 and 3 are ways to make a existing class hierarchy fluent and to allow methods to be called in any order so long as the existing classes are fluent (but you don't have access to or can't change the source). WAY2 is an example where you do have access to the source, and want the calls to be as simple as possible.
Full SSCCE:
import static java.lang.System.out;
public class AATester {
public static void main(String[] args){
//Test 1:
for(int x: new int[]{ 0, 1, 2 } ){
A w = getA(x);
//I agree this is a nasty way to do it... but you CAN do it.
Chain.a(w.setA("a1")).a(w instanceof C ? ((C) w).setC("c1") : null );
out.println(w);
}
//Test for WAY 2: Hope this wins Paul Bellora's approval
//for conciseness, ease of use and syntactic sugar.
C c = new C();
//Invoke methods in any order with compile time type safety!
c.setA("a2").a(c).setB("b2").a(c).set("C2");
out.println(w);
//Example 3, which is Example 1, but where the top level class IS known to be a "C"
//but you don't have access to the source and can't add the "a" method to the
//top level class. The method invocations don't have to be as nasty as Example 1.
c = new C();
Chain.a(c.setA("a3")).a(c.setB("b3")).a(c.setC("c3"));//Not much larger than Example 2.
out.println(w);
}
public static getA(int a){//A factory method.
A retval;//I don't like multiple returns.
switch(a){
case 0: retval = new A(); break;
case 1: retval = new B(); break;
default: retval = new C(); break;
}
return retval;
}
}
Test class A
public class A {
private String a;
protected String getA() { return a; }
//WAY 2 - where you have access to the top level source class.
protected final <T> T a(T type) { return type; }//This is awesome!
protected A setA(String a) { this.a=a; return this; }//Fluent method
#Override
public String toString() {
return "A[getA()=" + getA() + "]";
}
}
Test class B
public class B extends A {
private String b;
protected String getB() { return b; }
protected B setB(String b) { this.b=b; return this; }//Fluent method
#Override
public String toString() {
return "B[getA()=" + getA() + ", getB()=" + getB() + "]\n "
+ super.toString();
}
}
Test Class C
public class C extends B {
private String c;
protected String getC() { return c; }
protected C setC(String c) { this.c=c; return this; }//Fluent method
#Override
public String toString() {
return "C [getA()=" + getA() + ", getB()=" + getB() + ", getC()="
+ getC() + "]\n " + super.toString();
}
}
The Chain class
/**
* Allows chaining with any class, even one you didn't write and don't have
* access to the source code for, so long as that class is fluent.
* #author Gregory G. Bishop ggb667#gmail.com (C) 11/5/2013 all rights reserved.
*/
public final class Chain {
public static <K> _<K> a(K value) {//Note that this is static
return new _<K>(value);//So the IDE names aren't nasty
}
}
Chain's helper class.
/**
* An instance method cannot override the static method from Chain,
* which is why this class exists (i.e. to suppress IDE warnings,
* and provide fluent usage).
*
* #author Gregory G. Bishop ggb667#gmail.com (C) 11/5/2013 all rights reserved.
*/
final class _<T> {
public T a;//So we may get a return value from the final link in the chain.
protected _(T t) { this.a = t }//Required by Chain above
public <K> _<K> a(K value) {
return new _<K>(value);
}
}
Output:
A [get(A)=a]
B [get(A)=a, getB()=null]
A [getA()=a]
C [getA()=a, getB()=null, getC()=c)]
B [get(A)=a, getB()=null]
A [get(A)=a]
QED. :)
I've not ever seen anyone do this; I think it could be a new and potentially valuable technique.
P.S. With regard to the "elvis like usage", it is 1 or 2 lines vs 8 or more.
Book b = null;
Publisher p = null;
List books = null;
String id = "Elric of Melnibone";
books = Chain.a(b = findBook(id)).a(b != null ? p = b.getPublisher() : null)
.a(p != null ? p.getPublishedBooks(): null).a;
out.println(books==null ? null : Arrays.toString(books.toArray()));
vs:
Book b = null;
Publisher p = null;
List books = null;
String id = "Elric of Melnibone";
b = findBook(id);
Array[] books = null;
if( b != null ) {
p = b.getPublisher();
if(p != null) {
books = p.getPublishedBooks();
}
}
out.println(books==null ? null : Arrays.toString(books.toArray()));
No NPE, and if the chain completes you get all the books published by the publisher of "Elric of Melnibone" (i.e. all the books "Ace" publishers has published), and if not you get a null.
I believe there is a way to do this with generics... Syntax is a little less clean than the desired...
Here is the client code...
B<B> b = B.factoryB();
b.setA("a").setB("b");
A<A> ba = A.factoryA();
ba.setA("a");
Top level (real) class
public class A<S extends A> extends Chained<S> {
private String a = null;
protected A() {
}
public S setA(String a) {
this.a = a;
return me();
}
public static A<A> factoryA() {
return new A<A>();
}
}
Example Subclass
public class B<S extends B> extends A<S> {
private String b = null;
B() {
}
public S setB(String b) {
this.b = b;
return me();
}
public static B<B> factoryB() {
return new B<B>();
}
}
Helper
public abstract class Chained<S extends Chained> {
// class should be extended like:
// ... class A<S extends A> extends Chained<S>
public Chained() {
}
public final S me() {
return (S) this;
}
}
It's far from perfect and can be made not to work (if you really wanted to)
If source code is accessible, by extending what Alan wrote, I would add supplementary classes to hide generics while allowing inheritance and very compact syntax. BaseA and BaseB do the hierarchy while A and B do hide the generics.
BaseA
+- A
+- BaseB
+- B
public class BaseA<S extends BaseA<?>> {
private String a = null;
protected BaseA() {
}
#SuppressWarnings("unchecked")
public S setA(String a) {
this.a = a;
return (S) this;
}
}
public class A extends BaseA<A> {
public static A factoryA() {
return new A();
}
}
public class BaseB<S extends BaseB<?>> extends BaseA<S> {
private String b = null;
protected BaseB() {
}
#SuppressWarnings("unchecked")
public S setB(String b) {
this.b = b;
return (S) this;
}
}
public class B extends BaseB<B> {
public static B factoryB() {
return new B();
}
}
public class Main {
public static void main(String[] args) {
B.factoryB().setA("").setB("").setB("").setA("").setA("");
}
}
A fluent interface is a different concern from the normal set of command-query methods that you already have. Separation of concerns makes it a good idea to separate them.
Since you have an existing hierarchy of code: Write a fluent facade that does the dirty work for you.
See also Martin Fowler: Domain-Specific Languages, 4.2: The need for a Parsing Layer.