关闭

Java设计模式之工厂方法模式

标签: javajava设计模式工厂方法模式设计模式结构
126人阅读 评论(0) 收藏 举报
分类:

Java设计模式之工厂方法模式

  1. 工厂方法模式介绍
      
      工厂方式模式是创建型设计模式之一。工厂方法模式是一种结构简单的模式,其在我们平时开发的过程中应用很广泛,也许你并不知道,但是你已经使用了无数次该模式了,如在Android中的Activity里的各个声明周期方法,以onCreate方法为例,它就可以看作是一个工厂方法,我们在其中可以构造我们的View并通过setContentView返回给framework处理等。

  2. 工厂方法模式的定义

      定义一个用于创建对象的接口,让子类决定实例化哪个类。

  3. 工厂方法模式的使用场景

      在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。

  4. 工厂方法模式的UML类图
     
     这里写图片描述
     
    这里的角色主要分为四大模块:一是抽象工厂,其为工厂方法模式的核心;而是具体的工厂,其实现了具体的业务逻辑;三是抽象产品,是工厂方法模式所创建的产品的父类;四是具体的产品,为实现产品的某个具体产品的对象,以及每个产品所实现的方法逻辑。

  5. 简单的工厂方法模式示例

      首先我们定义个小米产品的抽象类,主要是统一齐下的所有产品,便于管理和功能的扩充
      
    MIProduct.java

/**
 * 抽象小米产品类
 */
public abstract class MIProduct {
    /**
     * 开机
     */
    public abstract void openMachine();

    /**
     * 运行
     */
    public abstract void running();

    /**
     * 关机
     */
    public abstract void closeMachine();
}

  然后定义每个不同型号的小米手机
MI3.java

/**
 * 具体的手机品牌类(MI3)
 */
public class MI3 extends MIProduct{
    @Override
    public void openMachine() {
        System.out.println("小米3开机");
    }

    @Override
    public void running() {
        System.out.println("小米3正在运行,运行内存为2G");
    }

    @Override
    public void closeMachine() {
        System.out.println("小米3关机");
    }
}

MI4.java

/**
 * 具体的手机品牌类(MI4)
 */
public class MI4 extends MIProduct {
    @Override
    public void openMachine() {
        System.out.println("小米4开机");
    }

    @Override
    public void running() {
        System.out.println("小米4正在运行,运行内存为2G");
    }

    @Override
    public void closeMachine() {
        System.out.println("小米4关机");
    }
}

MINote.java

/**
 * 具体的手机品牌类(MINote)
 */
public class MINote extends MIProduct{
    @Override
    public void openMachine() {
        System.out.println("小米NOTE开机");
    }

    @Override
    public void running() {
        System.out.println("小米NOTE正在运行,运行内存为3G");
    }

    @Override
    public void closeMachine() {
        System.out.println("小米NOTE关机");
    }
}

  定义一个抽象的小米工厂类,便于工厂类的扩展
ABSMIFactory.java

/**
 * 抽象的小米工厂类
 */
public abstract class ABSMIFactory {
    public abstract MIProduct createMIPhone();
}

  定义一个具体的生产小米手机的类
ConcreteMIFactory.java

/**
 * 具体的小米工厂类(生产手机,客户需要什么样的手机就生产什么样的手机)
 */
public class ConcreteMIFactory extends ABSMIFactory{
    @Override
    public MIProduct createMIPhone() {
        return new MI3();
    }
}

  客户端测试类
Client.java

/**
 * 客户端类
 */
public class Client {
    public static void main(String[] args) {
        ConcreteMIFactory miFactory = new ConcreteMIFactory();
        MIProduct product = miFactory.createMIPhone();
        product.openMachine();
        product.running();
        product.closeMachine();
    }
}

运行结果如下:

    小米3开机
    小米3正在运行,运行内存为2G
    小米3关机

 从上面的结果来看,客户端需要的是一台MI3型号的手机,所以工厂类就为它提供了生产了一台MI3型号的手机,如果说用户端需要MINote的手机,那么则需要修改ConcreteFactory类中的方法,修改其返回类型为new MINote()即可,对于上面这个例子,这只是个简单的实现,但是有时候,这样会非常麻烦,加入客户亮一增多,需要各种各样型号的手机,那按照这样的方式一个个的该,肯定对程序的通用性就会产生很大的影响,所以为了解决这个问题,我们可以通过反射来处理不同的请求,你需要什么样型号的手机,我就给你自动生产什么型号的手机,代码如下。
6. 改进的工厂方法模式示例
我们只需要改进抽象小米工厂类中的方法即可
ABSMIFactory.java

/**
 * 抽象的小米工厂类
 */
public abstract class ABSMIFactory {
    public abstract MIProduct createMIPhone(Class<?> clazz);
}

ConcreteFactory..java

/**
 * 具体的小米工厂类(生产手机,客户需要什么样的手机就生产什么样的手机)
 */
public class ConcreteMIFactory extends ABSMIFactory{
    @Override
    public MIProduct createMIPhone(Class<?> clazz) {
        MIProduct product = null;
        try {
            product = (MIProduct) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return product;
    }
}

Client.java

/**
 * 客户端类
 */
public class Client {
    public static void main(String[] args) {
        ConcreteMIFactory miFactory = new ConcreteMIFactory();
        MIProduct product = miFactory.createMIPhone(MI4.class);
        product.openMachine();
        product.running();
        product.closeMachine();
    }
}

通过上面的代码,则可以很好的让工厂自动的去生产了,用户需要什么样的型号,就传递对应的类型即可,这样就不需要手动去修改具体的型号了。

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:30777次
    • 积分:972
    • 等级:
    • 排名:千里之外
    • 原创:58篇
    • 转载:6篇
    • 译文:2篇
    • 评论:16条
    博客专栏
    文章存档
    最新评论