工厂模式(Factory Pattern) 一

来源:互联网 发布:sql注入原理c 编辑:程序博客网 时间:2024/04/26 08:40

现实中有些产品具有相同或者相似的功能,按照Java的面对对象编程来讲很容实现。

// 抽象产品

interface Product {

    void serve();

}

// 具体产品

class ProductA implements Product {

    @Override

    public void serve() {

        System.out.println("Product A is serving you!");

    }

}

// 具体产品

class ProductB implements Product {

    @Override

    public void serve() {

        System.out.println("Product B is serving you!");

    }

}

客户端要A,一般这样来实现:

// 客户端

public class Client {

public static void main(String[] args) {

         Product product = new ProductA(); 

    }

}

这样确实可以,如果要的是B的话,把上面的Product product = new ProductA(); 改为Product product = new ProductB()就行。这样编码的缺点是客户端要负责创建产品类实例,而实际上有时候客户端可能不知道如何创建具体产品类实例或者事先并不知道要创建那个产品类实例。这时候,采用工厂模式把产品创建的任务分离出去,可以提高系统的可读性,可扩展性和可维护性。

工厂模式的实质是把Product product = new ProductA(),Product product = new ProductB()等创建具有相同接口对象的工作交给一个单独的工厂类或者接口来完成。根据它实现复杂程度工厂模式又可分为简单工厂模式,工厂方法模式和抽象工厂模式。

简单工厂(Simple Factory)模式 


核心是具体的工厂实体类(Factory),由它决定那一个产品应当被实例化。消费者只需调用它的静态工厂(create)方法得到产品就行,而不必关心产品如何被创建。

//工厂类

class Factory {

    public static Product create(String name) throws Exception{

        if (name.equals("A")) {

            return new ProductA();

        } else if (name.equals("B")) {

            return new ProductB();

        } else {

            throw new Exception("No such product!");

        }

    }

}

这时如果客户端买产品时只要创建,或者调用一个Factory类,并把产品的型号或者说明作为参数传入,这样Factory类能根据这个参数自动创建需要的产品。

// 客户端

public class Client {

public static void main(String[] args) {

        Factory factory = new Factory();

        Product product = factory().create("A");

    }

}

上面的Creator代码有个缺点,就是当增加具体产品类如C的时候

// 具体产品

class ProductC implements Product {

    @Override

    public void serve() {

        System.out.println("Product C is serving you!");

    }

}

必须要增加else if (name.equalsIgnoreCase("C")) 或者switch判断。当具体产品类很多时,它的长度要增加很多。下面给出一个用Java反射机制写的改进代码:

//工厂类

class Creator {

    public static Product factory(String name) {

        Product product = null;

        try {

            product = (Product) Class.forName("com.java.****. " +  "name").newInstance();

        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {

        }

        return product;

    }

}

这样当增加产品如C的时候就不需要更改这个Creator类了,但要注意的是Class.forName()的参数必须是完整的类名(包括包名)com.java.****.A

原创粉丝点击