设计模式学习笔记—工厂方法模式

来源:互联网 发布:宁乡农村淘宝服务站 编辑:程序博客网 时间:2024/05/22 11:54

对于工厂模式而言,其核心目标应该就是一下一点

专门构建一个类负责提供组件

所以,很容易就可以得到以下几点需求

1.工厂类有可以返回某个组件的方法2.工厂类应该负责组件之间的依赖

然后,一个简单工厂就这样诞生了
比较常见的,它可以长这样

public class SimpleFactory {    public UserDao getUserDao() {        return UserDaoImpl();    }    public BookDao getBookDao() {        return UserDaoImpl();    }    public UserService getUserService() {        UserService userService = new UserServiceImpl();        userService.setUserDao(this.getUserDao());        userService.setBookDao(this.getBookDao());        return userService;    }    public BookService getBookService() {        BookService bookService = new BookServiceImpl();        bookService.setBookDao(this.getBookDao());        return bookService;    }}

可以在每个方法里面处理依赖关系,包括 dao 和 service 一般情况下可以处理成单例。如果是静态工厂的话可以这样。

    public static BookService getBookService() {        BookService bookService = new BookServiceImpl();        bookService.setBookDao(SimpleFactory.getBookDao());        return bookService;    }

其实并没有多少区别,然后,另外一种常见的形式大概是这样

public class SimpleFactory {    public BaseDao getDao(String name) {        if ("userDao".equals(name)) {            return new UserDaoImpl();        } else if ("bookDao".equals(name)) {            return new BookDaoImpl();        } else {            return null;        }    }    public BaseService getService(String name) {        if ("userService".equals(name)) {            return new UserServiceImpl();        } else if ("bookService".equals(name)) {            return new BookServiceImpl();        } else {            return null;        }    }}

或者合并在一起变成这样

public Object getBean(String name) {        if ("userDao".equals(name)) {            return new UserDaoImpl();        } else if ("bookDao".equals(name)) {            return new BookDaoImpl();        } else if ("userService".equals(name)) {            return new UserServiceImpl();        } else if ("bookService".equals(name)) {            return new BookServiceImpl();        }  else {            return null;        }    }

这两种方法的弊端就是,不能保证一定会获得对象,或者参数写错的话,一定是一件非常让人喜悦的事情。
同样,这两种方法也可以根据不同情况改成静态方法,但是,如果静态方法的弊端就是,很难在构造方法中去处理一些东西,其实最后一种方法已经比较接近平常使用的形式了(大概),如果调用的话会是这个样子。

SimpleFactory factory = new SimpleFactory();UserDao userDao = (UserDao) factory.getBean("userDao");

构造方法中也可以传递一些配置名字什么的,大概整体会变成这样

public class SimpleFactory {    private Map<String, Object> mDataMap = new HashMap<String, Object>();    public SimpleFactory(String fileName) {        // 正常情况下应该是去读某个xml的,这里就算了        mDataMap.put("userDao", new UserDaoImpl());        mDataMap.put("bookDao", new BookDaoImpl());        mDataMap.put("userService", new UserServiceImpl());        mDataMap.put("bookService", new BookServiceImpl());    }    public Object getBean(String name) {        return mDataMap.get(name);    }}

如果工厂取出的组件不是要求单例则可以这样

public class SimpleFactory {    private Map<String, Class<?>> mDataMap = new HashMap<String, Class<?>>();    public SimpleFactory(String fileName) {        // 正常情况下应该是去读某个xml的,这里就算了        mDataMap.put("userDao", UserDaoImpl.class);        mDataMap.put("bookDao", BookDaoImpl.class);        mDataMap.put("userService", UserServiceImpl.class);        mDataMap.put("bookService", BookServiceImpl.class);    }    public Object getBean(String name) {        Class<?> cls = mDataMap.get(name);        if (cls == null) {            return null;        }        Object obj = null;        try {            obj = cls.newInstance();        } catch (Exception e) {            e.printStackTrace();        }        return obj;    }}

话说随着代码的改动已经看不到 new 关键字了哎,然而,以上并不是一种设计模式,只是简单工厂而已,不过,实际中应该比较常用吧。

工厂方法模式(Factory Method Pattern)

对于工厂模式而言,简单工厂基本上已经足够用了吧,但简单工厂的扩展比较依赖于配置文件,所以,纯粹的代码设计中就有了工厂方法

public interface FoodFactory {    Food getFood(String name);}
public class StoreFactory implements FoodFactory {    @Override    public Food getFood(String name) {        if ("cake".equals(name)) {            return new Cake();        } else if ("bread".equals(name)) {            return new Bread();        }        return null;    }}
public class HomeFactory implements FoodFactory {    @Override    public Food getFood(String name) {        if ("bread".equals(name)) {            return new Bread();        }        return null;    }}

调用的时候大概是这样

FoodFactory factory = new HomeFactory();Food food = factory.getFood("cake");

而实际上,常见的形式应该是这种

Connection conn = DriverManager.getConnection("");Statement statment = conn.prepareStatement("sql");

对比之下可以发现,我们如果是有一个新的“食物工厂”,只需要实现那个接口类,而调用方面,如果是用工厂去创建工厂,同样也是去改一行参数,所以,对于一个新的数据库而言,只需要数据库开发者去实现 JDBC 接口,用户方面需要做的也只是去改变创建数据库的参数就可以了。
(以上是我自己编的,正确率有待考证)

PS: 抽象工厂还没看~
end

0 0
原创粉丝点击