Now Objects which are used in the application have some data which is either loaded from the
Database or provided by the user as input i.e.in both the cases the data becomes available at the time
of execution. To get the object initialize either from user input or from database factory method is
used.
In the application example 1; Two beans were configured by the name “num1” and “num2” with fixed values given by the programmer. Whenever these beans will be requested they will have same values.
In real application scenario different users want to provide the different values to their objects.
It can be facilitated by concerting the direct object creation approach to indirect object creating
approach i.e. we can add static factory methods to Complex.java and Rational.java to create and
initialize their object from the user input.
Now Application Example 1 is looks like the following:
1. Number.java
package com.jubilation.spring.user;
public interface Number {
public Number add(Number n);
public void display();
}
2. Complex.java
package com.jubilation.spring.user;
public class Complex implements Number {
private int real, img;
public Complex(int real, int img) {
this.real = real;
this.img = img;
}
@Override
public Number add(Number n) {
Complex c = (Complex) n;
int real = this.real + c.real;
int img = this.img + c.img;
return new Complex(real, img);
}
@Override
public void display() {
System.out.println("The Number is :" + real + "+" + img + "i");
}
public static Number getNumber()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the real part”);
int r=in.nextInt();
System.out.println(“Enter the imaginary part”);
int i=in.nextInt();
return new Complex(r,i);
} }
3. Rational.java
package com.jubilation.spring.user;
public class Rational implements Number{
private int p, q;
public Rational(int p, int q) {
this.p = p;
this.q = q;
}
@Override
public Number add(Number n) {
Rational r = (Rational) n;
int p= this.p*r.q + this.q*r.p;
int q = this.p* r.q;
return new Rational(p, q);
}
@Override
public void display() {
System.out.println("The Number is :" + p + "/" + q);
}
public static Number getNumber()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the denominator”);
int p=in.nextInt();
System.out.println(“Enter the numerator”);
int q=in.nextInt();
return new Rational(p,q);
}}
4. IOCUser.java
package com.jubilation.spring.user;
import org.springframework.beans.factory.BeanFactory;
public class IOCUser {
public static void main(String[] args) {
// TODO code application logic here
BeanFactory factory = MyFactory.getBeanFactory();
Number n1 = (Number) factory.getBean("num");
Number n2 = (Number) factory.getBean("num");
Number n3 = n1.add(n2);
n3.display();
Number N1 = (Number) factory.getBean("num");
Number N2 = (Number) factory.getBean("num");
Number N3 = N1.add(N2);
N3.display();
}
}
5. MyFactory.java
package com.jubilation.spring.user;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class MyFactory {
private static BeanFactory factory;
static{
Resource resource=new ClassPathResource("beanscfg.xml");
factory=new XmlBeanFactory(resource);
}
public static BeanFactory getBeanFactory() {
return factory;
}
}
6. Beanscfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="num"
class="com.jubilation.spring.user.Complex"
scope=”prototype”
factory-method=”getNumber”>
</bean>
</beans>
Now only one bean with id “num” is used because each time new object is created as we changed the
scope default to prototype.
Adding the factory method to each implementation is not a good idea sometimes it creates some
trouble same class static factory method approach can’t be used when the source code of the classes
to be instantiated is not available i.e. classes in jar file.In such scenario different class static factory method approach can be used. Let’s assume that we
don’t have the source code of the Relational and Complex classes but their objects are to be created
using the factory method. It can be done by defining the factory class as follows:
1. NumberFactory.java
package com.jubilation.spring.user;
public class NumberFactory {
public Number getRational()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the denominator”);
int p=in.nextInt();
System.out.println(“Enter the numerator”);
int q=in.nextInt();
return new Rational(p,q);
}
public Number getComplex()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the real part”);
int r=in.nextInt();
System.out.println(“Enter the imaginary part”);
int i=in.nextInt();
return new Complex(r,i);
} }
And the factory methods will be removed from the implementing classes and putted into a separate
class.
Now the configuration file will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="num"
class="com.jubilation.spring.user.NumberFactory"
scope=”prototype”
factory-method=”getRational”>
</bean>
</beans>
But this approach will not be good if a tie will have multiple implementations, each implementation is to be instantiated with the help of factory method. For example:
Number interface has two implementations by the name Complex and Rational in case of different class static factory we need to provide the two factory methods by the name getComplex and getRational i.e. in this approach a factory method for each implementation will need to be exposed to the end user such implementation will nullify the advantage of Interfaces. Each time a new implementation is provided or an existing implementation is needed application programmer need to be notified.
To solve this problem there should be one generalized factory method for all the implementation such
a method need some input from the user to decide which implementation is to be instantiated. The problem with spring is that we can’t pass parameters to the factory methods. This limitation can
be overcome if the static factory is to be non-static because we can pass parameters to the constructor.
It can be done by defining the factory class as follows:
1. NumberFactory.java
package com.jubilation.spring.user;
public class NumberFactory {
private String numType;
public NumberFactory(String nType)
{
numType=nType;
}
public number getNumber()
{i
f(numType.equalsIgnoreCase(“Rational”))
return getRational();
if(numType.equalsIgnoreCase(“Complex”))
return getComplex();
}
private Number getRational()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the denominator”);
int p=in.nextInt();
System.out.println(“Enter the numerator”);
int q=in.nextInt();
return new Rational(p,q);
}
private Number getComplex()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the real part”);
int r=in.nextInt();
System.out.println(“Enter the imaginary part”);
int i=in.nextInt();
return new Complex(r,i);
}}
Now the configuration file will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cf" class="com.jubilation.spring.user.NumberFactory" >
<constructor-arg value=”Complex”/>
</bean>
<bean id="rf" class="com.jubilation.spring.user.NumberFactory" >
<constructor-arg value=”Rational”/>
</bean>
<bean id="num"
scope=”prototype”
factory-bean=”cf”
factory-method=”getNumber”>
</bean>
</beans>
Note: Spring can make objects even factory method is private or constructor is private.
Database or provided by the user as input i.e.in both the cases the data becomes available at the time
of execution. To get the object initialize either from user input or from database factory method is
used.
In the application example 1; Two beans were configured by the name “num1” and “num2” with fixed values given by the programmer. Whenever these beans will be requested they will have same values.
In real application scenario different users want to provide the different values to their objects.
It can be facilitated by concerting the direct object creation approach to indirect object creating
approach i.e. we can add static factory methods to Complex.java and Rational.java to create and
initialize their object from the user input.
Now Application Example 1 is looks like the following:
1. Number.java
package com.jubilation.spring.user;
public interface Number {
public Number add(Number n);
public void display();
}
2. Complex.java
package com.jubilation.spring.user;
public class Complex implements Number {
private int real, img;
public Complex(int real, int img) {
this.real = real;
this.img = img;
}
@Override
public Number add(Number n) {
Complex c = (Complex) n;
int real = this.real + c.real;
int img = this.img + c.img;
return new Complex(real, img);
}
@Override
public void display() {
System.out.println("The Number is :" + real + "+" + img + "i");
}
public static Number getNumber()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the real part”);
int r=in.nextInt();
System.out.println(“Enter the imaginary part”);
int i=in.nextInt();
return new Complex(r,i);
} }
3. Rational.java
package com.jubilation.spring.user;
public class Rational implements Number{
private int p, q;
public Rational(int p, int q) {
this.p = p;
this.q = q;
}
@Override
public Number add(Number n) {
Rational r = (Rational) n;
int p= this.p*r.q + this.q*r.p;
int q = this.p* r.q;
return new Rational(p, q);
}
@Override
public void display() {
System.out.println("The Number is :" + p + "/" + q);
}
public static Number getNumber()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the denominator”);
int p=in.nextInt();
System.out.println(“Enter the numerator”);
int q=in.nextInt();
return new Rational(p,q);
}}
4. IOCUser.java
package com.jubilation.spring.user;
import org.springframework.beans.factory.BeanFactory;
public class IOCUser {
public static void main(String[] args) {
// TODO code application logic here
BeanFactory factory = MyFactory.getBeanFactory();
Number n1 = (Number) factory.getBean("num");
Number n2 = (Number) factory.getBean("num");
Number n3 = n1.add(n2);
n3.display();
Number N1 = (Number) factory.getBean("num");
Number N2 = (Number) factory.getBean("num");
Number N3 = N1.add(N2);
N3.display();
}
}
5. MyFactory.java
package com.jubilation.spring.user;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class MyFactory {
private static BeanFactory factory;
static{
Resource resource=new ClassPathResource("beanscfg.xml");
factory=new XmlBeanFactory(resource);
}
public static BeanFactory getBeanFactory() {
return factory;
}
}
6. Beanscfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="num"
class="com.jubilation.spring.user.Complex"
scope=”prototype”
factory-method=”getNumber”>
</bean>
</beans>
Now only one bean with id “num” is used because each time new object is created as we changed the
scope default to prototype.
Adding the factory method to each implementation is not a good idea sometimes it creates some
trouble same class static factory method approach can’t be used when the source code of the classes
to be instantiated is not available i.e. classes in jar file.In such scenario different class static factory method approach can be used. Let’s assume that we
don’t have the source code of the Relational and Complex classes but their objects are to be created
using the factory method. It can be done by defining the factory class as follows:
1. NumberFactory.java
package com.jubilation.spring.user;
public class NumberFactory {
public Number getRational()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the denominator”);
int p=in.nextInt();
System.out.println(“Enter the numerator”);
int q=in.nextInt();
return new Rational(p,q);
}
public Number getComplex()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the real part”);
int r=in.nextInt();
System.out.println(“Enter the imaginary part”);
int i=in.nextInt();
return new Complex(r,i);
} }
And the factory methods will be removed from the implementing classes and putted into a separate
class.
Now the configuration file will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="num"
class="com.jubilation.spring.user.NumberFactory"
scope=”prototype”
factory-method=”getRational”>
</bean>
</beans>
But this approach will not be good if a tie will have multiple implementations, each implementation is to be instantiated with the help of factory method. For example:
Number interface has two implementations by the name Complex and Rational in case of different class static factory we need to provide the two factory methods by the name getComplex and getRational i.e. in this approach a factory method for each implementation will need to be exposed to the end user such implementation will nullify the advantage of Interfaces. Each time a new implementation is provided or an existing implementation is needed application programmer need to be notified.
To solve this problem there should be one generalized factory method for all the implementation such
a method need some input from the user to decide which implementation is to be instantiated. The problem with spring is that we can’t pass parameters to the factory methods. This limitation can
be overcome if the static factory is to be non-static because we can pass parameters to the constructor.
It can be done by defining the factory class as follows:
1. NumberFactory.java
package com.jubilation.spring.user;
public class NumberFactory {
private String numType;
public NumberFactory(String nType)
{
numType=nType;
}
public number getNumber()
{i
f(numType.equalsIgnoreCase(“Rational”))
return getRational();
if(numType.equalsIgnoreCase(“Complex”))
return getComplex();
}
private Number getRational()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the denominator”);
int p=in.nextInt();
System.out.println(“Enter the numerator”);
int q=in.nextInt();
return new Rational(p,q);
}
private Number getComplex()
{
Scanner in= new Scanner(System.in);
System.out.println(“Enter the real part”);
int r=in.nextInt();
System.out.println(“Enter the imaginary part”);
int i=in.nextInt();
return new Complex(r,i);
}}
Now the configuration file will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cf" class="com.jubilation.spring.user.NumberFactory" >
<constructor-arg value=”Complex”/>
</bean>
<bean id="rf" class="com.jubilation.spring.user.NumberFactory" >
<constructor-arg value=”Rational”/>
</bean>
<bean id="num"
scope=”prototype”
factory-bean=”cf”
factory-method=”getNumber”>
</bean>
</beans>
Note: Spring can make objects even factory method is private or constructor is private.
Comments
Post a Comment