设计模式中的第一类是创建型模式, 共5种:
工厂方法、 抽象工厂、单例、原型、构建者(生成器)
1、工厂方法含简单工厂、工厂方法、静态工厂,通常而言我们所说的工厂模式,如无特别说明,均指工厂方法模式。
其中简单工厂模式是工厂方法模式的一种最简单存在形式。 废话不多说,直接看代码最直接。
简单工厂模式:
首先是有3个产品其中一个是抽象产品,另2个产品实现抽象产品。
package com.jelly.mypattern.simpleFactory;
/**
* 抽象发送器
* 如 可以表示邮件、短信 等发送器
* @author jelly
*
*/
public interface ISender {
public void send(String content);//发送的方法
}
package com.jelly.mypattern.simpleFactory;
/**
* 邮件发送器 产品
* @author jelly
*
*/
public class MailSender implements ISender{
@Override
public void send(String content) {
//邮件发送器 , 发送一封邮件
System.out.println("send a mail:"+content);
}
}
package com.jelly.mypattern.simpleFactory;
/**
* 短信发送器 产品
* @author jelly
*
*/
public class SmsSender implements ISender{
@Override
public void send(String content) {
//短信发送器 发送 方法:发送一条短信
System.out.println("send a sms:"+content);
}
}工厂类,生产发送器产品
package com.jelly.mypattern.simpleFactory;
/**
* 简单 工厂
* 生产发送器
* @author jelly
*
*/
public class SenderFactory {
public ISender getSender(String senderType){
ISender sender=null;
if(senderType.equals("sms")){
sender=new SmsSender();
}
else if(senderType.equals("mail")){
sender=new MailSender();
}
return sender;
}
}测试程序代码
package com.jelly.mypattern.simpleFactory;
/**
* 客户端 测试类
* @author jelly
*
*/
public class SimpleFactoryTest {
/**
* Simple Factory
* 简单工厂模式总结:
* 1、 工厂只有一个,且工厂中创建产品的方法也只有一个。
* 2、客户端代码中要得到产品,只能调用通过工厂中的这个方法,传入不同的产品类型,得到具体的某个产品。
* 3、每新增一种新的产品都需要在工厂方法中新增一种产品类型。
*/
public static void main(String[] args) {
SenderFactory senderFactory=new SenderFactory();
ISender sender= senderFactory.getSender("sms");
sender.send("你好 world");
ISender sender2= senderFactory.getSender("mail");
sender2.send("你好 world");
}
}工厂方法模式:
与简单工厂不同,工厂方法模式中每新增生产一个产品,就需要新加一个工厂方法,而简单工厂中需要新加一个产品类型的参数值即可。
改写工厂类
/**
* 工厂
* 生产发送器
* @author jelly
*
*/
public class SenderFactory {
public ISender getSmsSender(){
return new SmsSender();
}
public ISender getMailSender(){
return new MailSender();
}
}测试程序代码
package com.jelly.mypattern.factoryMethod;
/**
* 客户端 调用测试 类
* @author jelly
*
*/
public class FactoryMethodTest {
/**
* Factory Method
* 工厂 方法模式总结:
* 1 此模式中工厂有一个,工厂中的方法有多个。
* 2 每新增一种产品就需要在工厂中新加一个生产方法
*/
public static void main(String[] args) {
SenderFactory senderFactory=new SenderFactory();
ISender sender= senderFactory.getMailSender();
sender.send("你好 world");
ISender sender2= senderFactory.getSmsSender();
sender2.send("你好 world");
}
}静态工厂模式(属于工厂模式的静态变体),与工厂模式使用基本相同,静态工厂模式不用创建工厂对象。
还是改写工厂类,把类中的实例方法改为静态方法即可。
package com.jelly.mypattern.staticFactory;
/**
* 发送器 静态工厂
* @author jelly
*
*/
public class SenderFactory {
/**
* 生产 smsSender
* @return
*/
public static ISender getSmsSender(){
return new SmsSender();
}
/**
* 生产 MailSender
* @return
*/
public static ISender getMailSender(){
return new MailSender();
}
}
测试代码
package com.jelly.mypattern.staticFactory;
/**
* 静态工厂 客户端测试类
* @author jelly
*
*/
public class StaticFactoryTest {
/**
* 静态工厂模式:
* 也称为静态工厂方法模式,属于工厂方法模式的静态变体。
* 与工厂方法模式的使用相同,只是无须创建工厂对象。
*
*/
public static void main(String[] args) {
ISender sender= SenderFactory.getMailSender();
sender.send("你好 world");
ISender sender2= SenderFactory.getSmsSender();
sender2.send("你好 world");
}
}
与工厂方法模式不同,抽象工厂模式中不仅仅产品是抽象的,工厂也是抽象的。 不同的工厂才会生成具体的产品。
改写工厂类的层次结构,最上层有一个抽象工厂,下面有2个具体的子工厂去实现它。
package com.jelly.mypattern.abstractFactory;
/**
* 抽象工厂
* @author jelly
*
*/
public interface ISenderFactory {
/**
* 生产发送器
* @return
*/
public ISender getSender();
}package com.jelly.mypattern.abstractFactory;
public class MailSenderFactory implements ISenderFactory {
/**
* 生产邮件发送器
*/
@Override
public ISender getSender() {
return new MailSender();
}
}
package com.jelly.mypattern.abstractFactory;
/**
* 短信发送器 工厂
* @author jelly
*
*/
public class SmsSenderFactory implements ISenderFactory{
/**
* 生产短信发送器
*/
@Override
public ISender getSender() {
return new SmsSender();
}
}测试代码
package com.jelly.mypattern.abstractFactory;
/**
* 抽象工厂模式 客户端调用测试类
* @author jelly
*
*/
public class AbstractFactoryTest {
/**
* 抽象工厂模式总结:
* 1 在工厂类层次接口中的顶层有一个抽象的工厂,生产抽象的产品
* 2 抽象工厂派生出具体的工厂类,在具体的工厂类中生产具体的产品
* 3 如需要新增一种生产产品,则需要新增一个工厂类
*/
public static void main(String[] args) {
//得到工厂
ISenderFactory senderFactory=new SmsSenderFactory();
//工厂生产产品
ISender sender =senderFactory.getSender();
//使用产品
sender.send("你好 world");
ISenderFactory senderFactory2=new MailSenderFactory();
ISender sender2 =senderFactory2.getSender();
sender2.send("你好 world");
}
}
3 单例模式 ,在整个应用中此类只有一个实例对象。
单例模式中的懒人模式比较复杂,涉及多线程并发的问题,这里不做讨论,有兴趣的可以自行研究。
一般而言,单例模式可以采用以下方式直接创建,当类加载到jvm中时即创建了一个此类的实例对象。
package com.jelly.mypattern.singleton;
/**
* 单例模式
* @author jelly
*
*/
public class SingleClass {
private static SingleClass instance=new SingleClass();
/**
* 私有化构造方法
*/
private SingleClass(){
}
/**
* 暴露公有的静态方法 得到一个实例对象
* @return
*/
public static SingleClass getInstance(){
return instance;
}
//实例方法
public void aMethod(){
System.out.println("execute aMethod 方法");
}
//实例方法
public void bMethod(){
System.out.println("execute bMethod 方法");
}
}package com.jelly.mypattern.singleton;
/**
* 单例模式 客户端调用测试类
* @author jelly
*
*/
public class SingleClassTest {
/**单例模式:
*1 保证在整个应用程序中此类只有一个实例对象。
*2 采用单实例对象承担此类的所有职责。
* @param args
*/
public static void main(String[] args) {
SingleClass single=SingleClass.getInstance();
single.aMethod();//调用实例对象的a方法
single.bMethod();//调用实例对象的b方法
}
}
4、原型模式 Prototype
原型模式:
1 以一个对象为原型,复制克隆出一个新对象。
2 当创建新对象的代价很高、很费时,可以通过原型对象克隆新对象。
3 克隆对象必须实现序列化接口(标记接口)
4 克隆对象必须使用到深克隆。
package com.jelly.mypattern.prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* 业务类
* @author jelly
*
*/
public class MyClass implements Serializable{
private static final long serialVersionUID = 6468810466201374898L;
private String name;
public MyClass() {
super();
}
public MyClass(String name) {
super();
this.name = name;
}
public void aMethod(){
System.out.println("执行 aMethod 方法: "+name);
}
public void bMethod(){
System.out.println("执行 bMethod 方法: "+name);
}
/**
* 深克隆
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public MyClass deepClone() throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (MyClass) ois.readObject();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}package com.jelly.mypattern.prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* 克隆工具类
* @author jelly
*
*/
public class CloneUtil {
/**
* 对实现Serializable 接口的对象进行 完全的克隆
* @param obj
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static Serializable deepClone(Serializable obj)throws IOException, ClassNotFoundException{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Serializable) ois.readObject();
}
}测试代码
package com.jelly.mypattern.prototype;
/**
* 原型模式 客户端测试类
* @author jelly
*
*/
public class PrototypeTest {
/**
* Prototype 模式
* 原型模式
* 1 通过某个对象为原型(模型),克隆出一个新对象的方式创建新对象。
* 2 克隆对象必须实现序列化接口(标记接口)
* 3 克隆对象必须使用到深克隆。
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception{
MyClass obj1=new MyClass("张三");
MyClass obj2= obj1.deepClone();
obj2.setName("李四");
obj2.aMethod();
obj2.bMethod();
obj1.aMethod();
obj1.bMethod();
MyClass obj3=(MyClass) CloneUtil.deepClone(obj2);
obj3.setName("王五");
obj3.aMethod();
obj3.bMethod();
}
}
5 构造者(生成器) 模式
Builder
构建者模式 ,也称作生成器模式
1 将类对象的构建过程单独抽取出来封装,使对象的业务逻辑和对象的构建逻辑分离开。
2 当构建对象的逻辑较复杂,且容易发生变动时最好使用构建者模式。
3 通常用于读取配置文件、xml文件构建一个对象。
package com.jelly.mypattern.builder;
/**
*
* 邀请函(某活动)
* @author jelly
*
*/
public class Invitation {
private String subject;//邀请的主题
private String holder;//活动举办者 举办方 举办机构
private String holderTime;//举办时间
private String holderPlace ;//举办地点
private String invitName;//被邀请人姓名
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getHolder() {
return holder;
}
public void setHolder(String holder) {
this.holder = holder;
}
public String getHolderTime() {
return holderTime;
}
public void setHolderTime(String holderTime) {
this.holderTime = holderTime;
}
public String getHolderPlace() {
return holderPlace;
}
public void setHolderPlace(String holderPlace) {
this.holderPlace = holderPlace;
}
public String getInvitName() {
return invitName;
}
public void setInvitName(String invitName) {
this.invitName = invitName;
}
@Override
public String toString() {
return "Invitation [subject=" + subject + ", holder=" + holder
+ ", holderTime=" + holderTime + ", holderPlace=" + holderPlace
+ ", invitName=" + invitName + "]";
}
}
package com.jelly.mypattern.builder;
import java.io.BufferedReader;
import java.io.FileReader;
/**
* 邀请函的构建者 (生成器) 类
* @author jelly
*
*/
public class InvitationBuilder {
/**
* 根据配置文件,构造出一个邀请函对象
* @param path
* @return
* @throws Exception
*/
public Invitation build(String path) throws Exception{
Invitation invitation=null;
BufferedReader reader=null;
try {
reader=new BufferedReader(new FileReader(path));
String line= reader.readLine();
String[] ss= line.split(",");
invitation=new Invitation();
invitation.setSubject(ss[0]);
invitation.setHolder(ss[1]);
invitation.setHolderTime(ss[2]);
invitation.setHolderPlace(ss[3]);
invitation.setInvitName(ss[4]);
return invitation;
} finally {
reader.close();
}
}
}
第十七届武汉国际汽车展览会,武汉市人民政府和中国国际贸易促进委员会,2016年10月12-17日,武汉国际博览中心,张晓明
#邀请函内容由活动主题 、举办机构/单位、 活动时间、活动地点和被邀请人姓名5个部分组成,各部分间以逗号隔开。
测试代码
package com.jelly.mypattern.builder;
/**
* 构建者模式 测试类
* @author jelly
*
*/
public class BuilderTest {
/**
* Builder
* 构建者模式:
* 1 将类对象的构建过程单独抽取出来封装,使对象的业务逻辑和对象的构建逻辑分离开。
* 2 当构建对象的逻辑较复杂,且容易发生变动时最好使用构建者模式。
* 3 通用用于读取配置文件、xml文件构建一个对象。
*
*/
public static void main(String[] args) throws Exception {
InvitationBuilder builder=new InvitationBuilder();
String path=BuilderTest.class.getResource("invitation.txt").getPath();
Invitation invitation= builder.build(path);//构建出Invitation类的一个实例
System.out.println(invitation);
}
}。。。。。。

被折叠的 条评论
为什么被折叠?



