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

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

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

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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值