84669 person learning
152542 person learning
20005 person learning
5487 person learning
7821 person learning
359900 person learning
3350 person learning
180660 person learning
48569 person learning
18603 person learning
40936 person learning
1549 person learning
1183 person learning
32909 person learning
工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
工厂模式
简单工厂模式
抽象工厂模式
请问实际开发中哪些情况下会用到它?为什么我感觉我现在开发很少会用到这些设计模式啊。。。
人生最曼妙的风景,竟是内心的淡定与从容!
我先说下 我目前看到用到了工厂模式的例子:
一般的MVC框架中,都有一个基本的DB数据库基本操作类我叫它DB class,有一个baseModel class 去继承 db classbaseModel 是所有框架model的基类,需要继承baseModelbaseModel已经有db类的 增删查改的方法了,baseModel其实就是数据库工厂,不同的模型继承baseModel,就有操作不同数据表的对象实例了,这样就用一个基础的class 完成了实例化各个不同数据表的对象,就好像是工厂一样,传不同的表名字就返回给你不同的对象。我的理解就是这样的,如有误,还请包涵和斧正。
想理解工厂模式的话就不能不知道简单工厂模式了。
switch ($type) { case '存款职员': $man = new Depositer; break; case '销售': $man = new Marketer; break; case '接待': $man = new Receiver; break; default: echo '传输参数有误,不属于任何一个职位'; break; }
诺,这就是简单工厂模式,是不是很常见,简单工厂模式有一个不足,他虽然遵循了单一职责原则,但它违反了另一条很重要的原则:开放封闭原则。如果新增一个文员职位,那么我们还要修改对应代码,增加一个case,这是很可怕的,因为写好的代码如果我们再去修改可能会造成未知的效果。
而工厂模式就是对简单工厂的一次升级,这里以MVC里的DB class来说明,外部调用的时候只需选择自己所需的表名,该工厂会去调用真实数据库处理方法,然后返回你想要的结果。
不论是工厂模式还是其它创建型模式,都是一个目的——为了初始化一个对象。或者说,为了构建一个数据结构模型(类和对象本身就是一种自定义的数据结构)。
那么,问题来了,为什么有 new 这样方式可以创建一个对象,还要使用设计模式。本质上就是一个原因,不想让上层使用者直接使用 new 来初始化对象。
new
这样的原因有很多,绝大多数原因就是对上层的使用者隔离对象创建的过程;或者是对象创建的过程复杂,使用者不容易掌握;或者是对象创建要满足某种条件,这些条件是业务的需求也好,是系统约束也好,没有必要让上层使用者掌握,增加别人开发的难度。
所以,到这时我们应该清楚了,无论是工厂模式,还是上面的战友说的开闭原则,都是为了隔离一些复杂的过程,使得这些复杂的过程不向外暴露,如果暴露了这些过程,会对使用者增加麻烦,这也就是所谓的团队合作。
面向对象封装的本身也就是为了使得对外的 API 尽可能的简化。
API
例如,你定义了一个 Status字段,但这个字段因为某些业务原因,需要使用整数来表示状态。那么,如果数字少了还好办,如果数字多了,上层使用者就不一定能记清楚每个数字代表的状态(比如你要做语音通信系统,那么,语音设备是有很多状态数字的)。这时,如果使用 new来创建对象,然后再对 Status 进行赋值,不可避免的,可能要查阅开发文档,或者会不小心给出一个错误的值。这时,你就不妨使用工厂模式,或者其它合适的设计模式,来进行代码的建设。
Status
比如,这样:
public static class Factory { public static Ixxxxxx CreateWithOpen() { var obj = new Obj(); obj.Status = 1; return obj; } public static Ixxxxxx CreateWithClose() { var obj = new Obj(); obj.Status = 2; return obj; } }
当然,使用枚举也行,这个说白了,就是看设计者的意愿了。
所以,设计模式没有说必需在哪个场景中使用,更确切的说,应该是,当你使用了设计模式,能不能为你的团队成员带来方便,或者提升代码质量,避免一些错误。如果是,就用,如果仅仅带来了复杂,并没有益处,那还是算了。
一句话,没有该不该用,也没有哪些需要不需要用,用就要带来效益,无论是对团队还是产品质量或产品的可维护性。用不用,要以团队配合和产品为导向,这才是对一个软件设计师的基本要求。
工厂模式是一个用于实例化对象的模式,是用工厂方法代替new操作的一种方式。工厂模式在Java项目中到处都是,因为工厂模式就相当于创建实例对象的new,如在我们的系统中经常需要记日志,如果创建logger实例时所做的初始化工作可能是很长一段代码,可能要初始化、赋值、查询数据等等,则会导致代码臃肿而难看。
private static Logger logger = LoggerFactory.getLogger(MyBusinessRPC.class); public static Logger getLogger(String name) { ILoggerFactory iLoggerFactory = getILoggerFactory(); return iLoggerFactory.getLogger(name); } public static ILoggerFactory getILoggerFactory() { if (INITIALIZATION_STATE == UNINITIALIZED) { INITIALIZATION_STATE = ONGOING_INITIALIZATION; performInitialization(); } switch (INITIALIZATION_STATE) { case SUCCESSFUL_INITIALIZATION: return StaticLoggerBinder.getSingleton().getLoggerFactory(); case NOP_FALLBACK_INITIALIZATION: return NOP_FALLBACK_FACTORY; case FAILED_INITIALIZATION: throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG); case ONGOING_INITIALIZATION: // support re-entrant behavior. // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106 return TEMP_FACTORY; } throw new IllegalStateException("Unreachable code"); }
在java web项目开发过程中,经常会看到如下配置文件:
bean的name属性sqlSessionFactory,我们知道Sqlsession对应着一次数据库会话。由于数据库回话不是永久的,因此Sqlsession的生命周期也不应该是永久的,相反,在你每次访问数据库时都需要创建它(当然并不是说在Sqlsession里只能执行一次sql,你可以执行多次,当一旦关闭了Sqlsession就需要重新创建它)。创建Sqlsession的地方只有一个,那就是SqlsessionFactory的openSession方法,这里也用到了工厂模式。
工厂的职能就是你给它一个模型或者具体的样品需求,它给你一个成品。工厂模式也是这样的道理,比如,你入参是a,它就给你一个A对象,你入参b,它就给你生产一个B对象,这里a,b就是你让工厂生产的商品具体需求,如长宽高等。
工厂你可以理解为隐藏了内部细节,你调用工厂的生产API ,直接获得所描述的物体,具体怎么生产的,你不用去关注细节,因为有的东西简单,直接new出来就可以了,但有的很复杂,比如spring的注入链。要理解工厂模式,建议看看spring实现的factory。
设计模式的根本目的是减少项目变化所造成的影响,这一点要牢牢记住!工厂模式是把项目当中的变化点抽取封装出来.至于哪些是变化点,哪些该抽象需要开发者自行观察和预测.
举个不恰当的例子比如我的网站有多个页面每个页面都有css文件
//样式路径获取工厂类 public class MyStyleFactory { public string Page1Css(){return cssPath;} public string Page2Css(){return cssPath;} //....... }
假设项目中html的link链接就是通过代码生成的.那么显然每个页面都会要求获得css的路径.且css路径也是非常有可能变化的,那么这就是变化点,于是我可以把获取路径的这些变化点封装到MyStyleFactory中.这样以后修改只要改MyStyleFactory,而不是切换到各个页面修改.
这就是简单工厂.
但是一个网站可能有多种主题的样式,而MyStyleFactory仅能获取一个主题的样式,如果我想切换样式呢?于是切换样式就成了变化点,因封装他.换句话说我的系统是会切换Factory的.
为了适应Factory的切换,使用Factory的地方应该依赖于抽象,于是要有个抽象的工厂.
abstract class AbstractFactory { public abstract string Page1Css(); public abstract string Page2Css(); //....... }
写多个实现AbstractFactory的样式工厂
在使用的时候
Client(){ AbstractFactory factory=new MyStyleFactory(); }
你会发现只有一个地方要变化这就是抽象工厂
上面说到这个例子是不恰当的.如果页面数量确定下来还好说,但实际项目中变化的不仅仅是页面的样式(变化页面主题),页面的数量也是变化的,于是AbstractFactory中的Page数字Css方法的数量是不确定的,每添加一个页面就要加一个方法,并且每个继承类都要修改,这种变化用抽象工厂是不适合的,所以这时候使用抽象工厂反而是错的.
所以一定要弄清楚项目需求以及设计模式的应用场景
我先说下 我目前看到用到了工厂模式的例子:
一般的MVC框架中,都有一个基本的DB数据库基本操作类
我叫它DB class,有一个baseModel class 去继承 db class
baseModel 是所有框架model的基类,需要继承baseModel
baseModel已经有db类的 增删查改的方法了,baseModel其实就是数据库工厂,不同的模型继承baseModel,就有操作不同数据表的对象实例了,这样就用一个基础的class 完成了实例化各个不同数据表的对象,就好像是工厂一样,传不同的表名字就返回给你不同的对象。
我的理解就是这样的,如有误,还请包涵和斧正。
想理解工厂模式的话就不能不知道简单工厂模式了。
诺,这就是简单工厂模式,是不是很常见,简单工厂模式有一个不足,他虽然遵循了单一职责原则,但它违反了另一条很重要的原则:开放封闭原则。如果新增一个文员职位,那么我们还要修改对应代码,增加一个case,这是很可怕的,因为写好的代码如果我们再去修改可能会造成未知的效果。
而工厂模式就是对简单工厂的一次升级,这里以MVC里的DB class来说明,外部调用的时候只需选择自己所需的表名,该工厂会去调用真实数据库处理方法,然后返回你想要的结果。
不论是工厂模式还是其它创建型模式,都是一个目的——为了初始化一个对象。或者说,为了构建一个数据结构模型(类和对象本身就是一种自定义的数据结构)。
那么,问题来了,为什么有
new
这样方式可以创建一个对象,还要使用设计模式。本质上就是一个原因,不想让上层使用者直接使用 new 来初始化对象。这样的原因有很多,绝大多数原因就是对上层的使用者隔离对象创建的过程;或者是对象创建的过程复杂,使用者不容易掌握;或者是对象创建要满足某种条件,这些条件是业务的需求也好,是系统约束也好,没有必要让上层使用者掌握,增加别人开发的难度。
所以,到这时我们应该清楚了,无论是工厂模式,还是上面的战友说的开闭原则,都是为了隔离一些复杂的过程,使得这些复杂的过程不向外暴露,如果暴露了这些过程,会对使用者增加麻烦,这也就是所谓的团队合作。
面向对象封装的本身也就是为了使得对外的
API
尽可能的简化。例如,你定义了一个
Status
字段,但这个字段因为某些业务原因,需要使用整数来表示状态。那么,如果数字少了还好办,如果数字多了,上层使用者就不一定能记清楚每个数字代表的状态(比如你要做语音通信系统,那么,语音设备是有很多状态数字的)。这时,如果使用new
来创建对象,然后再对Status
进行赋值,不可避免的,可能要查阅开发文档,或者会不小心给出一个错误的值。这时,你就不妨使用工厂模式,或者其它合适的设计模式,来进行代码的建设。比如,这样:
当然,使用枚举也行,这个说白了,就是看设计者的意愿了。
所以,设计模式没有说必需在哪个场景中使用,更确切的说,应该是,当你使用了设计模式,能不能为你的团队成员带来方便,或者提升代码质量,避免一些错误。如果是,就用,如果仅仅带来了复杂,并没有益处,那还是算了。
一句话,没有该不该用,也没有哪些需要不需要用,用就要带来效益,无论是对团队还是产品质量或产品的可维护性。用不用,要以团队配合和产品为导向,这才是对一个软件设计师的基本要求。
工厂模式是一个用于实例化对象的模式,是用工厂方法代替new操作的一种方式。工厂模式在Java项目中到处都是,因为工厂模式就相当于创建实例对象的new,如在我们的系统中经常需要记日志,如果创建logger实例时所做的初始化工作可能是很长一段代码,可能要初始化、赋值、查询数据等等,则会导致代码臃肿而难看。
在java web项目开发过程中,经常会看到如下配置文件:
bean的name属性sqlSessionFactory,我们知道Sqlsession对应着一次数据库会话。由于数据库回话不是永久的,因此Sqlsession的生命周期也不应该是永久的,相反,在你每次访问数据库时都需要创建它(当然并不是说在Sqlsession里只能执行一次sql,你可以执行多次,当一旦关闭了Sqlsession就需要重新创建它)。创建Sqlsession的地方只有一个,那就是SqlsessionFactory的openSession方法,这里也用到了工厂模式。
工厂的职能就是你给它一个模型或者具体的样品需求,它给你一个成品。工厂模式也是这样的道理,比如,你入参是a,它就给你一个A对象,你入参b,它就给你生产一个B对象,这里a,b就是你让工厂生产的商品具体需求,如长宽高等。
工厂你可以理解为隐藏了内部细节,你调用工厂的生产API ,直接获得所描述的物体,具体怎么生产的,你不用去关注细节,因为有的东西简单,直接new出来就可以了,但有的很复杂,比如spring的注入链。要理解工厂模式,建议看看spring实现的factory。
设计模式的根本目的是减少项目变化所造成的影响,这一点要牢牢记住!
工厂模式是把项目当中的变化点抽取封装出来.至于哪些是变化点,哪些该抽象需要开发者自行观察和预测.
举个不恰当的例子
比如我的网站有多个页面每个页面都有css文件
假设项目中html的link链接就是通过代码生成的.
那么显然每个页面都会要求获得css的路径.
且css路径也是非常有可能变化的,那么这就是变化点,于是我可以把获取路径的这些变化点封装到MyStyleFactory中.这样以后修改只要改MyStyleFactory,而不是切换到各个页面修改.
这就是简单工厂.
但是一个网站可能有多种主题的样式,而MyStyleFactory仅能获取一个主题的样式,如果我想切换样式呢?
于是切换样式就成了变化点,因封装他.换句话说我的系统是会切换Factory的.
为了适应Factory的切换,使用Factory的地方应该依赖于抽象,于是要有个抽象的工厂.
写多个实现AbstractFactory的样式工厂
在使用的时候
你会发现只有一个地方要变化
这就是抽象工厂
上面说到这个例子是不恰当的.如果页面数量确定下来还好说,但实际项目中变化的不仅仅是页面的样式(变化页面主题),页面的数量也是变化的,于是AbstractFactory中的Page数字Css方法的数量是不确定的,每添加一个页面就要加一个方法,并且每个继承类都要修改,这种变化用抽象工厂是不适合的,所以这时候使用抽象工厂反而是错的.
所以一定要弄清楚项目需求以及设计模式的应用场景