工厂模式是什么?
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.即定义一个用于创建对象(这些对象有一个或者多个共同的特征)的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
Java中的设计模式分三大类:行为型模式,创建型模式,结构型模式。而工厂模式正是创建对象用的,是创建型模式中的一种。工厂模式又可以细分为三种模式:简单工厂模式(Simple Factory),工厂方法模式(Factory Method),抽象工厂模式(Abstract Factory),下面来一一介绍:
1 简单工厂模式:
又叫静态工厂模式,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。
先看一张图:
下面看实现的代码:
本次模拟的是生产电子产品的工厂,生产手机平板:
以上是项目的结构,下面插入代码:
package com.simple;
/**
*
* @author admin 电子产品
*
*/
public interface Product {
}
package com.simple;
/**
*
* @author admin 手机P6
*
*/
public class HuaWeiP6 implements Product{
public HuaWeiP6() {
System.out.println("大家好,我是华为P6");
}
}
package com.simple;
/**
*
* @author admin 手机P7
*
*/
public class HuaWeiP7 implements Product{
public HuaWeiP7() {
System.out.println("大家好,我是华为P7");
}
}
package com.simple;
/**
*
* @author admin 平板
*
*/
public class Tablet implements Product{
public Tablet() {
System.out.println("大家好,我是平板");
}
}
package com.simple;
/**
*
* @author admin 创建产品的工厂
*
*/
public class ProductFactory {
public static Product creatProduct(String name) {
if ("huaweip6".equals(name)) {
return new HuaWeiP6();
} else if ("huaweip7".equals(name)) {
return new HuaWeiP7();
}else if ("tablet".equals(name)) {
return new Tablet();
}else {
System.out.println("这个产品不存在的");
return null;
}
}
}
package com.simple;
public class SimpleTest {
public static void main(String[] args) {
ProductFactory.creatProduct("huaweip6");
ProductFactory.creatProduct("huaweip7");
ProductFactory.creatProduct("tablet");
ProductFactory.creatProduct("tablet33");
}
}
由上面的代码可以看出,简单工厂的核心就是ProductFactory 一个类,他拥有必要的逻辑判断能力和所有产品的创建权利,我们只需要向把产品名字给他,就能得到我们想要的产品。这使用起来似乎非常方便。但实际上,这个ProductFactory有很多的局限。首先,我们每次想要增加一种新产品的时候,都必须修改ProductFactory的原代码。其次,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这对以后的维护简直就是恐两个字...还有就是,整个系统都严重依赖ProductFactory类,只要ProductFactory类一出问题,系统就进入不能工作的状态,这也是最为致命的一点....
以上的不足将在工厂模式的另外两种状态中得到解决。
2 工厂方法模式
、还是先看图:
相关的代码:
先是和产品相关的:
package com.fmethod;
/**
*
* @author admin 对制造的产品抽象类
*
*/
public abstract class Mobile {
abstract void getCall();
abstract void takePhoto();
}
package com.fmethod;
/**
*
* @author admin 具体产品的实现类1
*
*/
public class HuaWeiP6 extends Mobile{
public HuaWeiP6() {
System.out.println("我是华为P6");
getCall();
takePhoto();
}
@Override
void getCall() {
System.out.println("P6我可以打电话");
}
@Override
void takePhoto() {
System.out.println("P6我拍照,效果一般");
}
}
package com.fmethod;
/**
*
* @author admin 具体产品的实现类2
*
*/
public class HuaWeiP7 extends Mobile{
public HuaWeiP7() {
System.out.println("我是华为P7");
getCall();
takePhoto();
}
@Override
void getCall() {
System.out.println("P7我能打电话");
}
@Override
void takePhoto() {
System.out.println("P7我拍照,效果非常好");
}
}
工厂相关:
package com.fmethod;
/**
*
* @author admin 工厂的抽象类
*
*/
public abstract class MobileFactory {
/**
*
* @param clazz 想要的手机
* @return 返回你要的手机
*/
abstract Mobile creatMobile();
}
package com.fmethod;
public class P6Factory extends MobileFactory{
@Override
Mobile creatMobile() {
return new HuaWeiP6();
}
}
package com.fmethod;
public class P7Factory extends MobileFactory{
@Override
Mobile creatMobile() {
return new HuaWeiP7();
}
}
测试类:
package com.fmethod;
public class MobileTest {
public static void main(String[] args) {
P6Factory p6Factory = new P6Factory();
Mobile p6 = p6Factory.creatMobile();
P7Factory p7Factory = new P7Factory();
Mobile p7 = p7Factory.creatMobile();
}
}
结果:
从上面创建产品对象的代码可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产手机外产品,还生产手机套产品,这样一来手机套和手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难.....
3 抽象工厂模式
先看图:
抽象工厂模式目的:意图在于创建一系列互相关联或互相依赖的对象。
产品接口:
package com.fabstract;
/**
*
* @author admin 对制造的产品抽象类
*
*/
public abstract class Mobile {
abstract void getCall();
abstract void takePhoto();
}
package com.fabstract;
/**
*
* @author admin 手机套的抽象
*
*/
public abstract class MobileSocket {
abstract void creatSocket();
}
产品的实现类:
package com.fabstract;
/**
*
* @author admin 具体产品的实现类1
*
*/
public class HuaWeiP6 extends Mobile{
public HuaWeiP6() {
System.out.println("我是华为P6");
getCall();
takePhoto();
}
@Override
void getCall() {
System.out.println("P6我可以打电话");
}
@Override
void takePhoto() {
System.out.println("P6我拍照,效果一般");
}
}
package com.fabstract;
/**
*
* @author admin 具体产品的实现类2
*
*/
public class HuaWeiP7 extends Mobile{
public HuaWeiP7() {
System.out.println("我是华为P7");
getCall();
takePhoto();
}
@Override
void getCall() {
System.out.println("P7我能打电话");
}
@Override
void takePhoto() {
System.out.println("P7我拍照,效果非常好");
}
}
package com.fabstract;
/**
*
* @author admin 手机套产品的实现类1
*
*/
public class P6Socket extends MobileSocket{
public P6Socket() {
creatSocket();
}
@Override
void creatSocket() {
System.out.println("我是华为P6的手机套");
}
}
package com.fabstract;
/**
*
* @author admin 手机套产品的实现类2
*
*/
public class P7Socket extends MobileSocket {
public P7Socket() {
creatSocket();
}
@Override
void creatSocket() {
System.out.println("我是华为P7的手机套");
}
}
抽象工厂和实现:
package com.fabstract;
/**
*
* @author admin 手机套产品的实现类2
*
*/
public class P7Socket extends MobileSocket {
public P7Socket() {
creatSocket();
}
@Override
void creatSocket() {
System.out.println("我是华为P7的手机套");
}
}
package com.fabstract;
/**
*
* @author admin 专门生产P6的工厂
*
*/
public class FactoryP6 implements ProductFactory{
@Override
public Mobile creatMobile() {
return new HuaWeiP6();
}
@Override
public MobileSocket creatMobileSocket() {
return new P6Socket();
}
}
package com.fabstract;
/**
*
* @author admin 专门生产P7的工厂
*
*/
public class FactoryP7 implements ProductFactory{
@Override
public Mobile creatMobile() {
return new HuaWeiP7();
}
@Override
public MobileSocket creatMobileSocket() {
return new P7Socket();
}
}
测试类和运行结果:
package com.fabstract;
public class AbstractTest {
public static void main(String[] args) {
FactoryP6 factoryP6 = new FactoryP6();
factoryP6.creatMobile();
factoryP6.creatMobileSocket();
}
}
好了,到此已经结束了,最后再说一句,之所以用工厂模式创建对象,关键在于这些对象都有一个相同的属性,比如p6和p7都是手机,p6的手机套和p7的手机套都是手机套,这样的对象用工厂模式来创建才方便,三种不同的创建方法在应用的时候需要结合到当前的情形,没有最好的,只有最适合你的。