设计模式之工厂模式、建造者模式
2015-01-14 22:01
399 查看
准备找工作那会看到了一本神书,《Head First 设计模式》,从此对设计模式有了很深的亲睐,但是因为自己的项目经验少的可怜,所以也基本没有用过这些神一样的方法,时间一长也就都忘干净了。现在工作了,师兄给了一个500M的代码,让我吃透它。这期间真的有很多问题,很迷惑。忽然想起了我之前看的书,于是重新拿出来温习。
如果说设计模式是圣经,那么这本书就是小人漫画版的启蒙圣经。入门看真的很好,但因为工作需要没有这么多时间,快餐式的是最合适的。于是在网上看到了一个网址,介绍23种设计模式很是靠谱。http://zz563143188.iteye.com/blog/1847029 这是这位大牛的网址。
以前看书的时候,感觉工厂模式种类繁多,根本就分不清楚,但是看了他的博客之后,有种拨云见月的感觉。于是乎就自己写下了这几个工厂模式的例子来练习,实现实例没有自己设计是参照网上的。
写完之后就感觉自己分清并掌握了这几个模式,下面就总结一下。
工厂模式是三类设计模式中的创建式模式,工厂模式分为三种,简单工厂方法,复杂工厂,还有抽象工厂
下面先看一下他们的实现
一,简单工厂模式
首先定义一个Isend接口
看一下测试
因为这个工厂相当于单个生产线,所以每种产品都会从这条生产线中产出,所以如果输入是本来生产线中没有的,那么就只能报错了。根据这种情况,于是就想可以再多出几条生产线啊。就是下面的复杂工厂该出场了。
二、复杂工厂:
其他的都一样,就是在工厂中多加几条生产线,所以直接看SenderFactory类就可以了
1,工厂方法里不需要创建实例,直接调用就行,那好办就把它设置为静态工厂,就实现了不需要实例化,直接创建。
2,设计模式崇尚的是对扩展开放,对修改关闭。当有新的需求有新的产品设计出来需要生产的时候,那么就只能更改SenderFactory这个类了,那么不就是违背这个设计原则了吗。可以设想,把工厂也做成多个,当有新的产品时,就建一座工厂,这样原来的工厂就不需要更改了,就实现了工厂之间的松耦合。
于是抽象工厂就这么产生了
抽象工厂:
抽象工厂就是把处理工厂的方法和处理生产线的方法一样
首先看一下IFactory接口
每一种发送器都是由不同的工厂生产出来的,当然也可以一个工厂生产多种产品,你可以试着改一下,当练手。
下面看一下测试
在这个例子中,新加的qq发送器是由qq工厂new出来的,不影响Mail 和 Phone工厂,实现了对扩展开放,对修改关闭的原则。
至此工厂模式就算是总结完了,还留了一个小题,就是在抽象工厂中,让一个工厂生产多个产品。
这里有一个坑,也同时给我自己挖了一个,下面晒一下我的答案:
首先我新建了一个WeiSender,想让QQSenderFactory也同时能生产WeiSender
于是在测试的时候,我就想直接用
所以如果还想执行其他的方法,那就得:
使用这种方法来new一个qqFactory就可以执行QQSenderFactory中的所哟方法了。
看一下测试
建造者模式
看完了工厂模式,是不是觉得意犹未尽,还差点啥?
对了,工厂模式创建的是单个类的模式,工厂可是可以根据订货单来大批量生产的。
于是建造者模式就诞生了。
下面看一下他的代码,相信一看代码就很明确了
不用多说了吧,我想应该一看就能明白
建造者模式是可以创造出很多复杂的东西,所以以后在用的时候可以考虑清楚,那种模式更适合
如果说设计模式是圣经,那么这本书就是小人漫画版的启蒙圣经。入门看真的很好,但因为工作需要没有这么多时间,快餐式的是最合适的。于是在网上看到了一个网址,介绍23种设计模式很是靠谱。http://zz563143188.iteye.com/blog/1847029 这是这位大牛的网址。
以前看书的时候,感觉工厂模式种类繁多,根本就分不清楚,但是看了他的博客之后,有种拨云见月的感觉。于是乎就自己写下了这几个工厂模式的例子来练习,实现实例没有自己设计是参照网上的。
写完之后就感觉自己分清并掌握了这几个模式,下面就总结一下。
工厂模式是三类设计模式中的创建式模式,工厂模式分为三种,简单工厂方法,复杂工厂,还有抽象工厂
下面先看一下他们的实现
一,简单工厂模式
首先定义一个Isend接口
public interface Isend { public void sendMessage(); }然后new几个sender,实现Isend接口
public class MailSender implements Isend { public void sendMessage() { // TODO Auto-generated method stub System.out.println("Use MailSender send the message!"); } }
public class PhoneSender implements Isend{ public void sendMessage() { // TODO Auto-generated method stub System.out.println("Use PhoneSender send the message!"); } }然后就是做一个工厂,让工厂来生产这几个sender
public class SenderFactory { public Isend productSender(String type) { if("Mail".equals(type)) { return new MailSender(); }else if("Phone".equals(type)) { return new PhoneSender(); }else <span style="color:#ff0000;">return new NullSender();</span> } }其中红色部分,就是暴露出了简单工厂的缺点,就是当type的类型和系统定义的步一样时,有可能是输入错误等,返回的就是一个空类型了,这是简单工厂的天生缺点
看一下测试
public class Test { public static void main(String[] args) { SenderFactory factory = new SenderFactory(); Isend mailSender = factory.productSender("Mail"); mailSender.sendMessage(); Isend phoneSender = factory.productSender("Phone"); phoneSender.sendMessage(); Isend errorySender = factory.productSender("123"); errorySender.sendMessage(); } }测试结果:
Use MailSender send the message! Use PhoneSender send the message! No SenderFactory product sender!
因为这个工厂相当于单个生产线,所以每种产品都会从这条生产线中产出,所以如果输入是本来生产线中没有的,那么就只能报错了。根据这种情况,于是就想可以再多出几条生产线啊。就是下面的复杂工厂该出场了。
二、复杂工厂:
其他的都一样,就是在工厂中多加几条生产线,所以直接看SenderFactory类就可以了
package com.designpattern.complexfactory.factory; import com.designpattern.complexfactory.isend.Isend; import com.designpattern.complexfactory.sender.MailSender; import com.designpattern.complexfactory.sender.PhoneSender; public class SenderFactory { public Isend productMailSender() { return new MailSender(); } public Isend productPhoneSender() { return new PhoneSender(); } }在这里,我做了两条生产线,每条生产线只负责生产一种产品,所以,这样就没有输入错误的情况了,看看测试
public class Test { public static void main(String[] args) { SenderFactory factory = new SenderFactory(); Isend mailSender = factory.productMailSender(); mailSender.sendMessage(); Isend phoneSender = factory.productPhoneSender(); phoneSender.sendMessage(); } }解决了?好像发现了两个问题。
1,工厂方法里不需要创建实例,直接调用就行,那好办就把它设置为静态工厂,就实现了不需要实例化,直接创建。
public class SenderFactory { public <span style="color:#ff0000;">static</span> Isend productMailSender() { return new MailSender(); } public <span style="color:#ff0000;">static</span> Isend productPhoneSender() { return new PhoneSender(); } }下面看一下测试
public static void main(String[] args) { Isend mailSender = SenderFactory.productMailSender(); mailSender.sendMessage(); Isend phoneSender = SenderFactory.productPhoneSender(); phoneSender.sendMessage(); }
2,设计模式崇尚的是对扩展开放,对修改关闭。当有新的需求有新的产品设计出来需要生产的时候,那么就只能更改SenderFactory这个类了,那么不就是违背这个设计原则了吗。可以设想,把工厂也做成多个,当有新的产品时,就建一座工厂,这样原来的工厂就不需要更改了,就实现了工厂之间的松耦合。
于是抽象工厂就这么产生了
抽象工厂:
抽象工厂就是把处理工厂的方法和处理生产线的方法一样
首先看一下IFactory接口
public interface IFactory { public Isend productSender(); }所有的工厂都实现此接口,也就意味着所有的工厂都可以生产产品,看一下这几个工厂
public class MailSender implements Isend{ public void SendMessage() { // TODO Auto-generated method stub System.out.println("Use MailSender send the message!"); } }
public class PhoneSender implements Isend { public void SendMessage() { // TODO Auto-generated method stub System.out.println("Use PhoneSender send the message!"); } }这里我又新建了一个qq工厂,来发送qq消息
public class QQSender implements Isend { public void SendMessage() { // TODO Auto-generated method stub System.out.println("User QQSender send the message!"); } }工厂看完了,看一下消息发送器
public class MailSender implements Isend{ public void SendMessage() { // TODO Auto-generated method stub System.out.println("Use MailSender send the message!"); } }
public class PhoneSender implements Isend { public void SendMessage() { // TODO Auto-generated method stub System.out.println("Use PhoneSender send the message!"); } }
public class QQSender implements Isend { public void SendMessage() { // TODO Auto-generated method stub System.out.println("User QQSender send the message!"); } }
每一种发送器都是由不同的工厂生产出来的,当然也可以一个工厂生产多种产品,你可以试着改一下,当练手。
下面看一下测试
public class Test { public static void main(String[] args) { IFactory mailFactory = new MailSenderFactory(); Isend mailSend = mailFactory.productSender(); mailSend.SendMessage(); IFactory phoneFactory = new PhoneSenderFactory(); Isend phoneSend = phoneFactory.productSender(); phoneSend.SendMessage(); IFactory qqFactory = new QQSenderFactory(); Isend qqSend = qqFactory.productSender(); qqSend.SendMessage(); } }
在这个例子中,新加的qq发送器是由qq工厂new出来的,不影响Mail 和 Phone工厂,实现了对扩展开放,对修改关闭的原则。
至此工厂模式就算是总结完了,还留了一个小题,就是在抽象工厂中,让一个工厂生产多个产品。
这里有一个坑,也同时给我自己挖了一个,下面晒一下我的答案:
首先我新建了一个WeiSender,想让QQSenderFactory也同时能生产WeiSender
public class WeiSender implements Isend { public void SendMessage() { // TODO Auto-generated method stub System.out.println("Use WeiSender send the message!"); } }把QQSenderFactory类做了一下调整
public class QQSenderFactory implements IFactory{ public Isend productSender() { // TODO Auto-generated method stub return new QQSender(); } <span style="color:#ff0000;">public Isend productWeiSender() { return new WeiSender(); }</span> }其中红色部分是我加的方法
于是在测试的时候,我就想直接用
IFactory qqFactory = new QQSenderFactory();生产出来的qqFactory来执行productWeiSender()方法,但是发现是错误的,这里就是个坑,回头看qqFactory是怎么来的,是由IFactory来的,那么就只能执行IFactory接口中带有的方法啦。
所以如果还想执行其他的方法,那就得:
<span style="color:#ff0000;">QQSenderFactory qqf = new QQSenderFactory();</span> Isend qqs = qqf.productWeiSender(); qqs.SendMessage();
使用这种方法来new一个qqFactory就可以执行QQSenderFactory中的所哟方法了。
看一下测试
Use MailSender send the message! Use PhoneSender send the message! User QQSender send the message! Use WeiSender send the message!
建造者模式
看完了工厂模式,是不是觉得意犹未尽,还差点啥?
对了,工厂模式创建的是单个类的模式,工厂可是可以根据订货单来大批量生产的。
于是建造者模式就诞生了。
下面看一下他的代码,相信一看代码就很明确了
public interface ISend { public void Send() ; }
public class MailSender implements ISend { public void Send() { // TODO Auto-generated method stub System.out.println("Use MailSender send the message!"); } }
public interface IFactory { public List<ISend> productSender(int count) ; }
public class MailSenderFactory implements IFactory { private List<ISend> list ; public MailSenderFactory() { list = new ArrayList(); } public List<ISend> productSender(int count) { for(int i = 0; i < count; i++) { list.add(new MailSender()); } return list; } }
public class Test { public static void main(String[] args) { MailSenderFactory mailFactory = new MailSenderFactory(); List list = mailFactory.productSender(3); for(int i = 0; i < list.size(); i++) { ISend sender = (ISend) list.get(i); sender.Send(); } } }
不用多说了吧,我想应该一看就能明白
建造者模式是可以创造出很多复杂的东西,所以以后在用的时候可以考虑清楚,那种模式更适合
相关文章推荐
- 【转】设计模式——创建型设计模式总结(简单工厂、普通工厂、抽象工厂、建造者、原型和单例)
- 设计模式——创建型设计模式总结(简单工厂、普通工厂、抽象工厂、建造者、原型和单例)
- 设计模式 -- 建造者模式和工厂(类)模式的区别
- 设计模式——创建型设计模式总结(简单工厂、普通工厂、抽象工厂、建造者、原型和单例)
- C++设计模式新解二 建造者模式+工厂模式
- 跟我学设计模式视频教程——单例模式,建造者VS工厂方法
- 编程经常使用设计模式具体解释--(上篇)(工厂、单例、建造者、原型)
- java设计模式-每天三个设计模式之工厂、单例、建造者
- 编程常用设计模式详解--(上篇)(工厂、单例、建造者、原型)
- 设计模式之建造者模式(与工厂模式的区别以及JDK中StringBuilder类的应用)
- 设计模式——创建型设计模式总结(简单工厂、普通工厂、抽象工厂、建造者、原型和单例)
- 【设计模式】 模式PK:工厂模式VS建造者模式
- Java设计模式, 单例模式,工厂模式,建造者模式和观察者模式
- 设计模式之 工厂方法(Factory)------对象创建型模式
- zt:工厂模式-简单工厂(设计模式的入门级模式—初级)
- .NET设计模式(4):建造者模式(Builder Pattern)
- .NET实用设计模式:工厂模式(Factory)
- 设计模式[2]-旧话重提之工厂模式
- 设计模式:工厂
- C#设计模式之简单工厂篇