设计模式之工厂方法模式

关于设计模式的学习笔记,教材:《设计模式的艺术之道》 刘伟 著

工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式,又可称作虚拟构造器模式(Virtual Constructor)或多态工厂模式(Polymorphic factory pattern)。工厂方法模式一种类创建型模式。

例题:使用工厂方法模式设计一个程序来读取各种不同类型的图片格式,针对每一种图片格式都设计一个图片读取器,例如GIF图片读取器用于读取GIT格式的图片,JPG图片读取器用于读取JPG格式的图片。

<?xml version="1.0"?>
<config>    <imgReaderFactory>designPattern.FactoryMethod.GIFReaderFactory</imgReaderFactory>
</config>

public class XMLUtil {
    public static Object getImgReader() {
        try {
            //创建文档对象
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document document = builder.parse(new File("config.xml"));

            NodeList nodeList = document.getElementsByTagName("imgReaderFactory");
            Node node = nodeList.item(0).getFirstChild();
            String className = node.getNodeValue().trim();
            Class c=Class.forName(className);
            Object o=c.newInstance();
            return o;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

public interface ImageReader {
    void readImg(String fileName);
}

public class JpgReader implements ImageReader {
    @Override
    public void readImg(String fileName) {
        System.out.println("JPG图片读取器读取"+fileName);
    }
    public JpgReader(){}
}

public class GifReader implements ImageReader {
    @Override
    public void readImg(String fileName) {
        System.out.println("GIF图片读取器读取"+fileName);
    }
    public GifReader(){}
}

public interface ReaderFactory {
    ImageReader createReader();
}

public class JPGReaderFactory implements ReaderFactory {
    @Override
    public ImageReader createReader() {
        //配置环境等 比如连接数据库
        ImageReader reader=new JpgReader();
        //初始化reader的数据等
        return reader;
    }
}

public class GIFReaderFactory implements ReaderFactory {
    @Override
    public ImageReader createReader() {
        //配置环境等 比如连接数据库
        ImageReader reader=new GifReader();
        //初始化reader的数据等
        return reader;
    }
}

public class Test {
    public static void main(String[] args){
        ReaderFactory factory= (ReaderFactory) XMLUtil.getImgReader();
        ImageReader reader=factory.createReader();
        reader.readImg("1.???");
        //输出 GIF图片读取器读取1.???
    }
}

思考:
有人说:可以在客户端代码中直接通过反射机制来生成产品对象,在定义产品对象时使用抽象类型,同样可以确保系统的灵活性和可拓展性,增加新的具体产品类无序修改源代码,只需要将其作为抽象产品类的子类再修改配置文件即可,根本不需要抽象工厂类和具体工厂类。
试思考,这种方法是否可行?是否存在问题?

我的思考:这样做的话,类的创建和使用就在同一个类,不符合单一职责原则,但这样似乎也没什么吧?或者说有些初始化工作不应该在构造函数内。(如果使用上述方法,初始化工作不能放在工厂里,只能放在构造函数内了)

老师的解释:http://blog.csdn.net/lovelion/article/details/7523392

我对上面文章的理解是:实际应用中,类的创建往往没有反射生成对象这样简单,一般需要在创建之前配置环境(连接数据库?没有相应经验,不太清楚)创建之后还要进行初始化操作,而这些是不适宜放在构造函数内的,因为单一职责原则,降低类的粒度。也不适宜放在客户端那,不然会造成冗余。
工厂就很好的将对象的创建和使用分离了。
还有一个好处是,一个类可能拥有多个构造函数,我们不需要去理解那些复杂的参数列表,而只需要使用工厂提供的名字完全不同的工厂方法即可,这样提高了可读性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值