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

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

一、定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。它是创建型设计模式之一。
二、使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值