创建型模式
概述:创建型模式一般来讲是指通过这种模式来生成对象。那么生成的对象也不是想生成什么对象就生成什么对象,如果是这样的话那就乱套了,也不符合面向对象的设计原则。不论是什么样的工厂模式他创建的对象都是某一个类别的对象,也就是实现了相同接口的对象。
1. 简单工厂模式
简单工厂模式通俗的讲就是:你告诉我你要什么东西,然后我就给你返回什么。如果我没有你要的东西,那么就返回一个null。
如何实现呢?用判断语句判断你传入的参数,然后根据参数的不同创建不同的对象返回。
例子:
/**
* 汽车类接口,工厂所创建的产品都必须实现这个接口
*
* @author Administrator
*
*/
public interface ICar {
public void run();
}
/**
* QQ汽车
* @author Administrator
*
*/
public class QQCar implements ICar {
@Override
public void run() {
System.out.println("QQ车");
}
}
/**
* 宝马汽车
*
* @author Administrator
*
*/
public class BaoMaCar implements ICar {
@Override
public void run() {
System.out.println("宝马车");
}
}
/**
* 汽车工厂
* @author Administrator
*
*/
public class CarFactory {
/**
* 这个方法也可以写成静态的,这样在调用的时候就不行需要创建CarFactory对象了
* @param type 汽车类型
* @return
*/
public ICar NewCar(CarType type) {
ICar car = null;
switch (type) {
case QQ:
car = new QQCar();
break;
case BaoMa:
car = new BaoMaCar();
break;
//这里还可以添加其他的情况
}
return car;
}
/**
* 汽车的类型
*
* @author Administrator
*
*/
public enum CarType {
QQ, BaoMa
}
}
/**
* 使用工厂
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) {
CarFactory factory=new CarFactory();
ICar QQ=factory.NewCar(CarFactory.CarType.QQ);
QQ.run();
}
}
缺点分析:当有新的汽车需要添加到工厂中去的时候还要修改工厂类。
2. 工厂方法模式
这种模式其实和上面的模式类似。只不过工厂方法模式不使用switch作判断,而是将每一种情况单独写成一个方法,这样就不用传递参数了。例如,它内部的方法有getQQCar(),getBaoMaCar()...等。
缺点分析:当有新的汽车需要添加到工厂中去的时候还要修改工厂类。
3. 抽象工厂模式
将工厂类也抽象化,每个工厂的实现只负责生产一种汽车。当有新类型的汽车需要添加到工厂中时,不需要修改原有的工厂,而是再实现一个工厂来创建这种新型的汽车。这样的设计符合开闭原则。
例子:
/**
* 汽车类接口,工厂所创建的产品都必须实现这个接口
*
* @author Administrator
*
*/
public interface ICar {
public void run();
}
/**
* 抽象的工厂
*
* @author Administrator
*
*/
public interface IFactory {
public ICar NewCar();
}
/**
* QQ汽车工厂
* @author Administrator
*
*/
public class QQCarFactory implements IFactory{
@Override
public ICar NewCar() {
return new QQCar();
}
}
/**
* 宝马汽车工厂
* @author Administrator
*
*/
public class BaoMaFactory implements IFactory{
@Override
public ICar NewCar() {
return new BaoMaCar();
}
}
/**
* 使用工厂
* @author Administrator
*/
public class Client {
public static void main(String[] args) {
IFactory factory = new QQCarFactory();
ICar qq = factory.NewCar();
qq.run();
}
}
优点:符合开闭原则。扩展性高。
缺点:类比较多。粒度细。
4 单例模式
由于单例模式比较容易理解,这里不多说。
/**
* 使用单例模式保证创建的对象只有一个
*/
public class Singleton {
/**
* 构造方法私有化
*/
private Singleton() {
}
/**
* 在保证线程安全的情况下,实现单例模式
*/
public Singleton GetInstance() {
return SingletonFactory.singleton;
}
/**
* 使用内部类维护一个单例,保证线程安全
*/
private static class SingletonFactory {
public static Singleton singleton = new Singleton();
}
}
5 建造者模式
工厂模式注重的是生产产品的结果,而这里的建造者模式注重的是产品的生产过程。使用建造者模式可以在对象创建完成以前对对象进行一些可选的设置。
下面以一个邮件系统为例介绍建造者模式的使用:
import java.util.Date;
/**
* 假如有一个自动发送邮件的系统,在你注册邮件的时候会发送欢迎邮件,取消注册的时候会有
* 欢送邮件。
* 这里给出欢迎和欢送邮件的基类
*/
public abstract class AutoMessage {
//收件人地址
private String to;
//发件人地址
private String from;
//标题
private String subject;
//内容
private String body;
//发送日期
private Date sendDate;
public void send(){
System.out.println("收件人地址:" + to);
System.out.println("发件人地址:" + from);
System.out.println("标题:" + subject);
System.out.println("内容:" + body);
System.out.println("发送日期:" + sendDate);
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public Date getSendDate() {
return sendDate;
}
public void setSendDate(Date sendDate) {
this.sendDate = sendDate;
}
}
/**
* 欢迎邮件
* @author Administrator
*
*/
public class WelcomMessage extends AutoMessage{
public WelcomMessage(){
System.out.println("欢迎邮件");
}
}
/**
* 欢送邮件
*
* @author Administrator
*
*/
public class GoodbyeMessage extends AutoMessage {
public GoodbyeMessage() {
System.out.println("欢送邮件");
}
}
import java.util.Date;
/**
* 建造者给出一个产品的部件如何建造
*/
public abstract class Builder {
protected AutoMessage msg;
// 标题零件的建造方法
public abstract void buildSubject();
// 内容零件的建造方法
public abstract void buildBody();
// 收件人零件的建造方法
public void buildTo(String to) {
msg.setTo(to);
}
// 发件人零件的建造方法
public void buildFrom(String from) {
msg.setFrom(from);
}
// 发送时间零件的建造方法
public void buildSendDate() {
msg.setSendDate(new Date());
}
/**
* 邮件产品完成后,用此方法发送邮件 此方法相当于产品返还方法
*/
public void sendMessage() {
msg.send();
}
/**
* 返回最终的产品
*
* @return
*/
public AutoMessage getMes() {
return msg;
}
}
/**
* 具体的建造者:欢迎邮件的建造者
* @author Administrator
*
*/
public class WelcomeBuilder extends Builder {
public WelcomeBuilder(){
msg=new WelcomMessage();
}
@Override
public void buildSubject() {
msg.setSubject("欢迎邮件");
}
@Override
public void buildBody() {
msg.setSubject("欢迎body");
}
}
/**
* 具体的建造者:欢送邮件建造者
* @author Administrator
*/
public class GoodByeBuilder extends Builder {
public GoodByeBuilder() {
msg = new GoodbyeMessage();
}
@Override
public void buildSubject() {
msg.setSubject(" 欢送邮件");
}
@Override
public void buildBody() {
msg.setSubject(" 欢送body");
}
}
/**
* 导演者
* 导演着负责使用建造者,决定这些部件如何使用。
* 如果一个产品的建造过程固定了,那么这里的导演着可以这样按照固定的操作来使用建造者生成产品.
* 当然,客户端也可以自己直接调用Builder来生成对象
* @author Administrator
*/
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
/**
* 产品构造方法,负责调用各部件的建造方法
*/
public AutoMessage construct(String toAddress, String fromAddress) {
this.builder.buildTo(toAddress);
this.builder.buildFrom(fromAddress);
this.builder.buildSubject();
this.builder.buildBody();
this.builder.buildSendDate();
return this.builder.getMes();
}
}
/**
* 客户端
* @author Administrator
*/
public class Client {
public static void main(String[] args) {
//建造者给出每一个部件的生产方式
Builder builder = new WelcomeBuilder();
//导演者给出部件的组装方式
Director director = new Director(builder);
//导演者按照给定的部件进行构建
AutoMessage message=director.construct("toAddress@126.com", "fromAddress@126.com");
//发送邮件
message.send();
}
}