java设计模式之—-工厂设计模式
1.定义
工厂设计模式: 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类.在我们平常的开发中,工厂设计模式使用的及其频繁,因为它运用设计模式中的依赖导致原则,也就是我们常说的”面向接口编程”.接口或抽象类不依赖于具体的实现类,实现类依赖接口或抽象类.
2.步骤及要点
- 创建子类的共同接口,意为抽象类.
- 创建具体的实现类,并实现该接口.
- 创建一个工厂用于专门生产这些对象.
3.实现过程
(1) 简单工厂模式
/**
* 这是一个父类的接口
* @author psp
*
*/
public interface Human {
void eat();
void talk();
}
/**
* 这是一个实现类
* @author psp
*
*/
public class Man implements Human {
public void eat() {
System.out.println("男人吃饭.");
}
public void talk() {
System.out.println("女人吃饭.");
}
}
/**
* 这是另一个实现类
*
* @author psp
*
*/
public class Woman implements Human {
public void eat() {
System.out.println("女人吃饭.");
}
public void talk() {
System.out.println("女人说话");
}
}
下面实现工厂类
/**
* 工厂类
* @author psp
*
*/
public class HumanFactory {
public Human createHumanMethod(Class c) {
Human human = null;
try {
human = (Human) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return human;
}
}
测试类
/**
* 测试类
* @author psp
*
*/
public class FactoryTest {
public static void main(String[] args) {
HumanFactory humanFactory = new HumanFactory();
Human man = humanFactory.createHumanMethod(Man.class);
man.eat();
man.talk();
Human woman = humanFactory.createHumanMethod(Woman.class);
woman.eat();
woman.talk();
}
}
(2)多个工厂方法模式
多个工厂方法模式是对普通工厂模式的改进,在普通工厂模式需要传递具体的字节码对象,加入字节码对象出错,则不能正确的创建对象,而多个工厂方法模式提供多个工厂方法,创建多个不同的对象.
只需修改工厂类如下:
/**
* 多个方法的工厂类
*
* @author psp
*
*/
public class HumanFactory1 {
public Human createManMethod() {
return new Man();
}
public Human createWomenMethod() {
return new Woman();
}
}
(3)静态工厂模式
当我们需要创建具体的对象的时候,还需要创建工厂类的实例,假如改成静态方法,就不需要创建具体的工厂类实例了.
/**
* 静态工厂类
*
* @author psp
*
*/
public class HumanFactory2 {
public static Human createManMethod() {
return new Man();
}
public static Human createWomenMethod() {
return new Woman();
}
}
比较:工厂模式适合出现在需要创建大量的产品或对象的时候,并且具有共同的接口,就可以用工厂设计模式来创建.以上三种工厂模式中第三种最优,不需要创建工厂类的实例,也不需要传递具体的字节码参数.总的来说,第三种方法最优.
(3)抽象工厂模式(多个工厂)
思考: 工厂模式固然可以用来生产大量产品,但是有一个问题,类的创建必须依赖于工厂类,我们很有可能需要对程序扩展,然后我们就要去修改工厂类,这样就违背了设计模式中的开闭原则.我们可以这样,我们把工厂类也抽象到一个父类去,然后假如需要修改原有的工厂类,我们不修改,重新创建一个工厂类就可以了.我们也同时创建多个工厂类,这样也符合设计模式的单一职责原则.
实例类保持不变,工厂类改为如下形式:
先创建一个工厂类需要实现的接口:
/**
* 工厂类实现的接口
* @author psp
*
*/
public interface AbstractHumanFactory {
void createHumanMethod();
}
再创建两个具体的工厂实现类:
/**
* 第一个工厂类
* @author psp
*
*/
public class ManFactory implements AbstractHumanFactory {
public Human createHumanMethod() {
return new Man();
}
}
/**
* 另一个工厂类
* @author psp
*
*/
public class WomanFactory implements AbstractHumanFactory {
public Human createHumanMethod() {
return new Woman();
}
}
假如我们需求有变化,我们不需要改变原有的工厂类,只需要创建一个新的工厂类.
(4)延迟加载的工厂类,或者叫做带缓存的工厂类.
具体常见场景: 现在android的项目中界面的主体大多都是包含多个tab 的多个界面划分,例如viewPager 中有多个fragment的切换,那么在实现viewPager 的 adapter 的时候我们就可以用这种延迟加载的工厂设计模式,这样可以不需要重复创建fragment ,既节省了资源,又提供了运行的效率,这是一个很好的应用场景.
下面看具体实现的过程;
/**
* 延迟加载的工厂类
* @author psp
*
*/
public class DelayLoadFactory {
private static final Map<String, Human> factoryMap = new HashMap<String, Human>();
public static synchronized Human createHumanMethod(String type) {
Human human = null;
if (factoryMap.containsKey(type)) {
factoryMap.get(type);
} else {
if (type.equals("Man")) {
human = new Man();
} else if (type.equals("Womon")) {
human = new Woman();
}
factoryMap.put(type, human);
}
return human;
}
}