工厂方法模式——应用最广泛

来源:互联网 发布:科比布莱恩特数据 编辑:程序博客网 时间:2024/05/16 14:44

(《设计模式解析与实战》读书笔记)

一、定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。它是创建型设计模式之一。
二、使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
三、工厂方法模式的通用模式代码

/** * 抽象产品类 */public abstract class Product {    /**     * 产品类的抽象方法由具体的产品类去实现     */    public abstract void method();}
/** * 具体产品类A */public class ConcreteProductA extends Product{    @Override    public void method() {        System.out.println("我是具体的产品A");    }}
/** * 具体产品类B */public class ConcreteProductB extends Product{    @Override    public void method() {        System.out.println("我是具体的产品B");    }}
/** * 抽象工厂类 */public abstract class Factory {    /**     * 抽象工厂方法具体生产什么由子类去实现     *      * @return 具体的产品对象     */    public abstract Product createProduct();}
/** * 具体工厂类 */public class ConcreteFactory extends Factory {    @Override    public Product createProduct() {        return new ConcreteProductA();    }}
/** * 客户类 */public class Client {    public static void main(String[] args) {        Factory factory = new ConcreteFactory();        Product product = factory.createProduct();        product.method();    }}

运行:
这里写图片描述
主要分为四大模块:
(1)抽象工厂,核心;
(2)具体工厂,具体的业务逻辑;
(3)抽象产品,所创建的产品的父类;
(4)具体产品,实现抽象产品的某个具体产品的对象。

当然可以利用反射的方式更简洁的来生产具体产品对象:

/** * 抽象工厂类 */public abstract class Factory {    /**     * 抽象工厂方法具体生产什么由子类去实现     *      * @param clz     *            产品对象类型     * @return 具体的产品对象     */    public abstract <T extends Product> T createProduct(Class<T> clz);}/** * 具体工厂类 */public class ConcreteFactory extends Factory {    @Override    public <T extends Product> T createProduct(Class<T> clz) {        Product product = null;        try {            product = (Product) Class.forName(clz.getName()).newInstance();        } catch (Exception e) {            e.printStackTrace();        }        return (T) product;    }}/** * 客户类 */public class Client {    public static void main(String[] args) {        Factory factory = new ConcreteFactory();        Product product = factory.createProduct(ConcreteProductA.class);        product.method();    }}

这种方法简洁、动态,不需要为每一个产品都定义一个具体的工厂。
如果工厂类只有一个,那么就可以简化掉抽象类,只需要将工厂方法改为静态方法。

/** * 简单工厂模式或静态工厂模式 */public class EasyFactory {    public static Product createProduct() {        return new ConcreteProductA();    }}

四、实例
以数据存储为例,将每一种数据操作的方式作为一个产品类,在抽象产品类中定义操作的方法:

/** * 抽象数据存储类 */public abstract class IOHandler {    /**     * 添加一条个人信息     *      * @param id     *            身份证号码     * @param name     *            名字     */    public abstract void add(String id, String name);    /**     * 删除一条个人信息     *      * @param id     */    public abstract void remove(String id);    /**     * 更新一条个人信息     *      * @param id     *            身份证号码     * @param name     *            名字     */    public abstract void update(String id, String name);    /**     * 查询身份证对应的人名     *      * @param id     */    public abstract String query(String id);}/** * 文件存储 */public class FileHandler extends IOHandler {    @Override    public void add(String id, String name) {        // TODO 文件存储代码    }    @Override    public void remove(String id) {        // TODO 文件删除代码    }    @Override    public void update(String id, String name) {        // TODO 文件修改代码    }    @Override    public String query(String id) {        // TODO 文件查询代码        return "文件存储";    }}/** * XML文件存储 */public class XMLHandler extends IOHandler{    @Override    public void add(String id, String name) {        // TODO 业务处理    }    @Override    public void remove(String id) {        // TODO Auto-generated method stub    }    @Override    public void update(String id, String name) {        // TODO Auto-generated method stub    }    @Override    public String query(String id) {        // TODO Auto-generated method stub        return "XML文件存储";    }}/** * SQLite数据库存储 */public class DBHandler extends IOHandler {    @Override    public void add(String id, String name) {        // TODO 业务处理    }    @Override    public void remove(String id) {        // TODO Auto-generated method stub    }    @Override    public void update(String id, String name) {        // TODO Auto-generated method stub    }    @Override    public String query(String id) {        // TODO Auto-generated method stub        return "SQLite数据库存储";    }}/** * 数据存储工厂类 */public class IOFactory {    /**     * 获取IO处理者     *      * @param clz     *            处理类的类型     * @return IOHandler对象     */    public static <T extends IOHandler> T getIOHandler(Class<T> clz) {        IOHandler handler = null;        try {            handler = (IOHandler) Class.forName(clz.getName()).newInstance();        } catch (Exception e) {            e.printStackTrace();        }        return (T) handler;    }}
public class MainActivity extends Activity {    private IOHandler handler;    private TextView mTextView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mTextView = (TextView) findViewById(R.id.tv_text);    }    public void onClick(View v) {        switch (v.getId()) {        // 查询普通文本数据        case R.id.btn_file:            handler = IOFactory.getIOHandler(FileHandler.class);            mTextView.setText(handler.query("123"));            break;        // 查询XML文件数据        case R.id.btn_xml:            handler = IOFactory.getIOHandler(XMLHandler.class);            mTextView.setText(handler.query("123"));            break;        // 查询数据库数据        case R.id.btn_db:            handler = IOFactory.getIOHandler(DBHandler.class);            mTextView.setText(handler.query("123"));            break;        case R.id.btn_default:            mTextView.setText("点击按钮查询结果");            break;        default:            break;        }    }}

演示结果:
这里写图片描述
五、优缺点
优点:
(1)降低了对象之间的耦合度;
(2)将实例化的任务交由子类去完成,有非常好的扩展性;
(3)结构简单,逻辑基本类似。
缺点:
每次为工厂方法模式添加新的产品时就要编写一个新的产品类,同时还要引入抽象层,这会导致类结构的复杂化。

0 0
原创粉丝点击