创建型模式,共五种:
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
这篇博客是看完黑马视频教程,以及查找资料总结的,如有错误,请多指教
创建型模式
单例模式
保证一个类仅有一个实例,首先要私有构造函数,提供一个访问它的方法
有两种方式,
一种是先创建对象 ——饿汉式,
一种是用的时候在第一次调用访问方法时创建对象——懒汉式。
/**
* 饿汉式
* @author chris
*
*/
class Single {
private static final Single single =new Single();
private Single(){}
public Single getInstance(){
return single;
}
}
/**
*懒汉式
* @author chris
*
*/
class Single2{
private static Single2 single=null;
private Single2(){}
public static Single2 getInstance(){
if(single!=null){//两次判断提高性能,避免每次都判断锁
synchronized(Single2.class){
//用该类的字节码对象加锁同步 解决多线程下出问题
if(single!=null){
single=new Single2();
}
}
}
return single;
}
}
普通工厂模式
客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。
/**
* 普通工厂模式
*
* @author chris
*
*/
public class One_FactoryPatterns {
public static void main(String[] args) {
SenderFactory factory = new SenderFactory();
// Sender sender=factory.getSender("sms");
Sender sender = factory.getMailSerder();
sender.send();
Sender staticSender = SenderFactory.getStaticSmsSender();
staticSender.send();
}
}
class SenderFactory {
/**
* 原始方式
*
* @param type
* @return
*/
public Sender getSender(String type) {
if ("sms".equals(type)) {
return new SmsSender();
} else if ("mail".equals(type)) {
return new MailSender();
} else {
System.out.println("input type");
return null;
}
}
/**
* 为了防止类型传入错误
*
* @return
*/
public Sender getSmsSender() {
return new SmsSender();
}
public Sender getMailSerder() {
return new MailSender();
}
/**
* 静态工厂方法模板
*
* @return
*/
public static Sender getStaticSmsSender() {
return new SmsSender();
}
public static Sender getStaticMailSerder() {
return new MailSender();
}
}
class MailSender implements Sender {
@Override
public void send() {
System.out.println("MailSender");
}
}
class SmsSender implements Sender {
@Override
public void send() {
System.out.println("SmsSender");
}
}
interface Sender {
public void send();
}
抽象工厂模式
创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
/**
* 抽象工厂模式(Abstract Factory) 创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
*
*/
public class One_AbstractFactoryPatterns {
public static void main(String[] args) {
Provider provider = new SendSmsFactory();
AbstractSender sender = provider.getSender();
sender.Sender();
}
}
class SendSmsFactory implements Provider {
@Override
public AbstractSender getSender() {
// TODO Auto-generated method stub
return new AbstractMailSender();
}
}
class SendMailFactory implements Provider {
@Override
public AbstractSender getSender() {
// TODO Auto-generated method stub
return new AbstractMailSender();
}
}
/**
* 工厂类共同实现rpovider接口
*
* @author chris
*
*/
interface Provider {
public AbstractSender getSender();
}
class AbstractMailSender implements AbstractSender {
@Override
public void Sender() {
// TODO Auto-generated method stub
System.out.println("MailSender");
}
}
class AbstractSmsSender implements AbstractSender {
@Override
public void Sender() {
// TODO Auto-generated method stub
System.out.println("SmsSender");
}
}
interface AbstractSender {
public void Sender();
}
建造者模式
将对象的内部表象和对象的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。
/**
* 建造者模式
* 基于工厂模式上层
* 批量生产对象
* */
public class One_BuilderPatterns {
private List<Sender> list=new ArrayList<Sender>();
/**
* 批量生产
* @param count
* @return
*/
public List<Sender> produceMailSender(int count){
for(int i=0;i<count;i++){
list.add(new MailSender());
}
return list;
}
public List<Sender> produceSmsSender(int count){
for(int i=0;i<count;i++){
list.add(new SmsSender());
}
return list;
}
public static void main(String[] args) {
One_BuilderPatterns builder=new One_BuilderPatterns();
List<Sender> list=builder.produceMailSender(20);
for (Sender sender : list) {
sender.send();
}
}
}
原型模式
一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可以改成任意的名称,因为Cloneable接口是个空接口,你可以任意定义实现类的方法名,如cloneA或者cloneB,因为此处的重点是super.clone()这句话,super.clone()调用的是Object的clone()方法,而
在Object类中,clone()是native的,具体怎么实现,我会在另一篇文章中,关于解读Java中本地方法的调用,此处不再深究。
- 浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
- 深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了 完全彻底的复制,而浅复制不彻底。
- 缺点是每一个类都必须配备一个克隆方法
/public class One_PrototypePatterns implements Cloneable, Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String string;
private SerializableObject obj;
/**
* 浅复制
*/
public Object clone() throws CloneNotSupportedException {
One_PrototypePatterns other = (One_PrototypePatterns) super.clone();
return other;
}
/**
* 深复制
*
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public Object 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 ois.readObject();
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public SerializableObject getObj() {
return obj;
}
}
class SerializableObject implements Serializable {
private static final long serialVersionUID = 1L;
private String test = "teststring";
}