一、前言
1、为了提高内聚和松耦合,我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们就可以通过基类的子类的实现来达到多态的目的。这里容易出现一个问题n个子类继承自抽象基类,我们不得不在每次用到子类的地方编写new xxx;代码
2、程序的扩展性和维护性变得越来越困难
3、有时候父类并不知道具体要实例化哪一个具体子类。假设我们在类A中要使用类B,类B 是一个抽象父类或者接口,在A中并不知道要实例化那一个B的子类,但是在类A的子类D是知道的。在A中我们没有办法直接使用类似new xxx的语句。
spring /工厂设计模式是怎样解决两个问题的?
二、Factory
在Factory方法中有一个类担任工厂角色负责生产类,如Factory2
package com.bitch.design.action.factory;
/**
* @author chenhaipeng
* @version 1.0
* @date 2015/10/30 17:59
*/
public class Factory2 {
//
public static Product getInstance(Class clazz){
if(clazz.equals(ConcreateProduct1.class)){
return new ConcreateProduct1();
}else if(clazz.equals(ConcreateProduct2.class)){
return new ConcreateProduct2();
}
return null;
}
}
这个类有个特点,往往是需要一些判断来创建的是什么类,但是问题来了,如果子类增加需要修改工厂方法 的判断。
三、abstract Factory
子类的增加不会修改工厂只需要实现其相应的子类即可
package com.bitch.design.action.factory;
/**
* @author chenhaipeng
* @version 1.0
* @date 2015/10/30 16:25
*/
public abstract class Factory {
public abstract Product getInstance();
public abstract Product getInstance2(Class clazz);
}
package com.bitch.design.action.factory;
/**
* @author chenhaipeng
* @version 1.0
* @date 2015/10/30 17:01
*/
public class ConcreateFactory extends Factory {
@Override
public Product getInstance() {
return new ConcreateProduct1();
}
@Override
public Product getInstance2(Class clazz) {
return null;
}
}
package com.bitch.design.action.factory;
/**
* @author chenhaipeng
* @version 1.0
* @date 2015/10/30 17:04
*/
public class FactoryMainTest {
//这里如果是spring 的话一般会用注入的方法
Product p ;
public FactoryMainTest(Product p) {
this.p = p;
}
public void Operation(){
p.Operation();
}
public void getPrice(Price p ){
p.getPrice();
}
public static void main(String[] args) {
Factory factory = new ConcreateFactory();
ConcreateProduct1 p = (ConcreateProduct1) factory.getInstance();
FactoryMainTest f = new FactoryMainTest(p);
f.Operation();
}
}
四、那么在spring 中是如何使用工厂方法
<bean id = "product1Price" class="com.bitch.design.action.factory.Product1Price"></bean>
<bean id = "product2Price" class="com.bitch.design.action.factory.Product2Price"></bean>
<bean id="concreateProduct1" class="com.bitch.design.action.factory.Factory2" factory-method="getInstance">
<constructor-arg value="com.bitch.design.action.factory.ConcreateProduct1"/>
<property name="price" ref="product1Price"/>
</bean>
<bean id="concreateProduct2" class="com.bitch.design.action.factory.Factory2" factory-method="getInstance">
<constructor-arg value="com.bitch.design.action.factory.ConcreateProduct1"/>
<property name="price" ref="product2Price"/>
</bean>
当然你也可以使用注解来实现!
测试代码如下
package com.bitch.design.action.factory;
import com.sishuok.es.common.test.BaseIT;
import com.sishuok.es.common.utils.SpringUtils;
import org.junit.Test;
/**
* @author chenhaipeng
* @version 1.0
* @date 2015/10/30 21:38
*/
public class SpringFactoryMainTest extends BaseIT {
@Test
public void test() {
// ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bitch.xml");
// ConcreateProduct1 product1 = ctx.getBean("concreateProduct1",ConcreateProduct1.class);
ConcreateProduct1 product1 = SpringUtils.getBean("concreateProduct1");
System.out.println(product1);
product1.getPrice();
}
}