有款游戏叫模拟人生,我这里就例子就叫北漂人生吧。

北漂人生 规定安家模式

a.结婚 b.买房 c. 买车 d. 生娃

先看几种情况:

1. 我初来帝都,按照北漂人生规则,如果要安家,要遵守

a. 结婚

b. 买车(不可以,纳税不够5年)

c. 买房(不可以,纳税不够5年)

d. 生娃(不享受北京相关政策福利)

2. 我来帝都5年,要安家,也遵守

a. 结婚

b. 买房(有资格,看你储备和运气)

c. 买车(同上)

d. 生娃(不享受)

3. 帝都郊区人民

a. 结婚

b. 买房

c. 买车

d. 生娃(可以2个)

注:以上规则不适用“我爸是李刚”等开挂模式。

作为一个全方位的考虑,你要实现很多种情况,但是规则比较固定,所以假如我有个工厂类,并且用if/else来解决

  1. if(//初来帝都,不够5年){
  2. //执行了安家模式abcd,只有结婚无限制,其他有特殊规则
  3. }else
  4. if(//来帝都5年){
  5. //安家模式abcd,放开部分限制
  6. }else
  7. if(//帝都郊区){
  8. //安家模式abcd,遵守规则
  9. }else
  10. if(//帝都土著){
  11. //安家模式abcd,福利分房,补贴
  12. }

太乱!时也许你会整理整理,于是对外地人和本地人做了个区分

  1. if(//外地人){
  2. //5年限制
  3. }else
  4. if(//本地人){
  5. }

然后你开始面对一个问题,每个if/else里都有abcd,但是又略有不同,如何重构?

一般我们考虑继承或者组合两种方式,设计模式可以考虑策略,装饰器等。那这里就是讲工厂方法,所以就采用继承。

  1. if(//外地人){
  2. if(//level A){
  3. //类unlocalA的对象
  4. }
  5. else if(//level B){
  6. //类unlocalB的对象
  7. }
  8. }
  9. else if(//本地人){
  10. if(//level A){
  11. //类localA的对象
  12. }else if(//level B){
  13. //类localB的对象
  14. }
  15. }

再次重构呢?能不能更好一点,假如我新增加一个老外模式进来,能不能不修改原来的工厂类了呢?

尝试将工厂分为本地工厂和外地工厂,这样再加入新的老外工厂就不会影响其他已经封装的源代码了。

记得在区别 工厂方法 和 抽象工厂的这个图,是这样的:

假如我添加老外安家:

通过上面的推导过程,我们无赖似的推出了个工厂方法模式。再补充一下,这个例子并不是很适合工厂方法,我们来看看工厂方法适合的场景。

工厂方法模式适合的情况

我们注意到几个问题

1. 变化少:产品(我们这里的是产品是安家)接口内容不会有太多变化。

2. 松耦合:新增加一工厂以及相关产品,不需要改动原来的代码

3. 相同接口:产品都是实现同一个接口

4. 相同层级:每个工厂,层级都基本相同。

如果我们仔细回忆一下,spring在对ORM框架和EJB对于安全策略的集成,都与工厂方法有非常相似的地方。 都是制定了一些共同的约束,非常符合我们变化少的原则。

何时用?

工厂方法模式一般在一些比较大的系统中会用到,尤其在做spring这种组件分离,但遵循某些共同约束的场景下,结合一些其他模式,将会更加灵活强大。

我为这个模式写个些粗糙的代码:

层级:

  1. /**
  2. * 家庭级别
  3. * @author 书生
  4. *
  5. */
  6. public enum Level {
  7. /*高级*/A,
  8. /*普通*/B
  9. }

抽象工厂

  1. /**
  2. * 创建家庭
  3. * @author 书生
  4. *
  5. */
  6. public abstract class FamilyBuild {
  7. public Family buildFamily(Level level) {
  8. Family family;
  9. family = marry(level);
  10. family.buyHouse();
  11. family.buyCar();
  12. family.babyBirth();
  13. return family;
  14. }
  15. /**
  16. * 结婚组成家庭,传入级别
  17. * @param level
  18. * @return
  19. */
  20. protected abstract Family marry(Level level);
  21. }

一个具体的工厂

  1. public class UnLocalFamilyBuild extends FamilyBuild {
  2. @Override
  3. protected Family marry(Level level) {
  4. Family family;
  5. if(level==Level.A) {
  6. family = new UnLocalSeniorFamily();
  7. }else {
  8. family = new UnLocalCommonFamily();
  9. }
  10. return family;
  11. }
  12. }

家庭接口

  1. /**
  2. * 家庭
  3. * @author 书生
  4. *
  5. */
  6. public abstract class Family {
  7. /*户主等相关信息描述*/
  8. public String hostName;
  9. /*家庭住址*/
  10. public String adr;
  11. public void buyHouse() {
  12. System.out.println("buy house");
  13. }
  14. public  void marry() {
  15. System.out.println("Important moment,Happy Times");
  16. }
  17. public void babyBirth() {
  18. System.out.println("make new people :)");
  19. }
  20. public void buyCar() {
  21. System.out.println("buy a car");
  22. }
  23. }

普通外地人接口

  1. /**
  2. * 普通外地人组件家庭
  3. * @author 书生
  4. *
  5. */
  6. public class UnlocalCommonFamily extends Family {
  7. public UnlocalCommonFamily() {
  8. hostName = "工作不满5年的外地人";
  9. adr = "租房";
  10. }
  11. @Override
  12. public void babyBirth() {
  13. //TODO 生孩子相关政策
  14. }
  15. @Override
  16. public void buyHouse() {
  17. // TODO 不足5年,不能买房
  18. //完全重写
  19. }
  20. @Override
  21. public void buyCar() {
  22. // TODO 不足5年,不能买车
  23. // 完全重写
  24. }
  25. }

如果我想创建一个普通外地人家庭,需要

  1. public class TestFactoryMethod {
  2. public static void main(String[] args) {
  3. FamilyBuild fb = new UnLocalFamilyBuild();
  4. Family family = fb.buildFamily(Level.B);
  5. }
  6. }

我想你也注意到了,new UnLocalFamilyBuild(); 每一个工厂都有一套自己的规则。如果能做到只要一个配置就得到需要的工厂功能,而不需要知道具体工厂类会不会更好?答案是也许会。我们在spring中也看到有多个Factory的情况,当一个工厂类,包含的信息非常丰富,或者通过类名,能够基本知道他所代表的喊一声时,这已经是一个不错的工厂了。这个可能会引发一个争论,到底精简到什么地步是最好,或者说,设计模式的原则都是合理的吗? 不过这不是我们要讨论的,我们通过此文最重要的是对工厂方法的思想理解。

我上传一下我写的工厂方法的一些代码,大多是伪码。

附件:http://down.51cto.com/data/2361293

本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/yjplxq/967623,如需转载请自行联系原作者

我是架构师-设计模式-工厂模式-工厂方法相关推荐

  1. 我是架构师--设计模式-单例模式

    来次面试吧?准备好没,GO! 问:自我介绍下吧.(开个玩笑...往下)请问你用过单例模式吗?什么是单例? 答:用过啊,单例模式就是只创建一个实例. 问:噢?那是单线程,还是多线程下都是呢? 答:这个类 ...

  2. 研磨23种大话设计模式------简单工厂模式 + 工厂方法模式 + 抽象工厂模式

    大家好,我是一位在java学习圈中不愿意透露姓名并苟且偷生的小学员,如果文章有错误之处,还望海涵,欢迎多多指正 如果你从本文 get 到有用的干货知识,请帮忙点个赞呗,据说点赞的都拿到了offer 简 ...

  3. 策略模式和工厂模式的区别_设计模式之工厂模式-工厂方法模式

    设计模式之工厂模式-工厂方法模式 大家好,欢迎来到污污弹公司,今天司小司又接到了一个新活-披萨项目. 来源:凯哥Java(kaigejava) 需求: 披萨项目: 要方便披萨品种的扩展.要便于维护.要 ...

  4. 【设计模式】简单工厂模式+工厂方法模式+抽象工厂模式

    前提导论 故事 不采用工厂模式 简单工厂模式 工厂方法模式 故事 抽象工厂模式 故事结局 前提导论 为了学习设计模式时便于理解,我将用基于农夫和他的村子与森林为背景环境,讲一个故事时,阐述一个设计模式 ...

  5. 重学Java设计模式-创建者模式-工厂方法模式

    重学Java设计模式-创建者模式-工厂方法模式 内容摘自:重学 Java 设计模式:实战工厂方法模式「多种类型商品不同接口,统一发奖服务搭建场景」 | bugstack 虫洞栈 工厂方法模式介绍 图片 ...

  6. UML图解简单工厂模式工厂方法模式抽象工厂模式区别

    简述 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一: 工厂模式包含 简单工厂模式& 工厂方法模式& 抽象工厂模式这三种: 这三者主要区别在于工厂实现的 ...

  7. 简单工厂模式--工厂方法模式(简介)

    一.简单工厂模式(静态工厂) 简单工厂模式不属于23种标准设计模式 简单工厂模式是工厂方法模式的一个特殊的实现 简单工厂就是由一个工厂类根据传入的参数决定创建出哪一种产品类的实例  二.实现 产品接口 ...

  8. java-抽象工厂模式+工厂方法模式+策略模式简单应用实战(登录场景)

    前言 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证代码可靠性. 设计模式 ...

  9. 常见几种显示器进入工厂模式的方法

    常见几种显示器进入工厂模式的方法 ⒈ 方正显示器 ⑴方正15英寸和17英寸飞梭显示器:开机前按住飞梭键后再开机即可进入工厂模式. ⑵方正OSD显示器:开机前按住最中间那个按键后再开机就可以进入工厂模式 ...

最新文章

  1. session和Cookie的区别
  2. 关于STL 容器的嵌套使用, 小试牛刀
  3. Vue CLI3 基本使用配置;
  4. Android 应用性能优化(4)---Android App性能评测分析-启动时间篇
  5. MTKI 驱动(57)---音频参数含义
  6. 端口截听实现端口隐藏 嗅探与攻击
  7. 「leetcode」617. 合并二叉树:【三种递归】【一种迭代】详解
  8. 代发核心期刊骗局_警惕“代发论文”骗局,落入骗子圈套
  9. sysservers 中找不到服务器,请执行 sp_addlinkedserver 将该服务器添加到sysserver
  10. 鸿蒙智慧屏安装应用,谁说华为智慧屏不能装APP,我来打脸了,附零难度安装APP教程...
  11. 【mongodb】连接报错Prematurely reached end of stream
  12. python识别重影验证码_python+opencv实现移动侦测(帧差法)
  13. 彩色图直方图均衡化matlab
  14. 淘宝新开店铺容易忽略的地方,如何安全提升宝贝排名
  15. Linux ——objdump和readelf的使用
  16. python光棍节快乐_2020年祝光棍节快乐的祝福语18条
  17. 安卓平台的功耗一般分析
  18. Unity之手机键盘自定义输入栏位置适配不同手机分辨率适配
  19. left join 用法
  20. RK3368评测 RK3368方案 RK3368方案设计 RK3368性能如何 RK3368设计定制

热门文章

  1. 一个 Mybatis 开发神器:Fast MyBatis 超好用
  2. IDEA 强大的 Live Templates,代码生成利器
  3. Java 常用代码汇总
  4. Dubbo中的连接控制,你真的理解吗?
  5. SpringBoot 线程池,也太好用了叭!
  6. CMS 被废弃了,该怎么办呢?
  7. ​Openresty最佳案例 | 第8篇:RBAC介绍、sql和redis模块工具类
  8. ShakeDrop:深度残差学习中的 ShakeDrop 正则化
  9. 准确率可提升50%以上,Facebook用迁移学习改进代码自动补全
  10. 如何将全景分割用到养猪场?