java常用设计模式总结

设计模式了解

什么是设计模式?

设计模式(Design pattern)是一套被反复使用的代码设计经验的总结。

为什么使用设计模式

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性以及代码的结构更加清晰.

设计模式的7大原则

1、单一职责原则
一个类只负责一项职责。
2、接口隔离原则
一个类对另一个类的依赖应该建立在最小接口上。
在这里插入图片描述
在这里插入图片描述
3、依赖倒转原则
①高层模块不应该依赖底层模块,二者都应该依赖其抽象
②抽象不应该依赖细节(实现类),细节应该依赖抽象
③依赖倒置的中心思想是面向接口编程,使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

依赖传递的方式:
接口传递
构造方法传递
setter方法传递

  • [ ] 详细说明

4、里氏代换原则(Liskov Substitution Principle
子类中尽量不要重写父类的方法。如果重写,可以将父类中要重写的方法提取到新的类,两个类同时继承新的类,这样做可以降低耦合性。
5、开闭原则(Open Close Principle)
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个优化的效果。对扩展开放,对修改关闭。
6、迪米特法则(最少知道原则)(Demeter Principle)
一个类对自己依赖的类知道的越少越好。被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供public方法之外,不对外泄露任何信息。
7.合成复用原则
原则是尽量使用合成/聚合的方式,而不是使用继承。

设计模式分类

有23种,三大类设计模式。

创建型模式(用于解耦对象的实例化过程): (5种)
单例模式抽象工厂模式、建造者模式、工厂模式、原型模式。

行为型模式(对象的功能): (7种) 把。
适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式

结构型模式(对象的组成): (11种)
模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

设计模式详细介绍

创建型

1、单例模式

这个类只能有一个实例,提供全局访问
私有构造方法,私有静态对象,提供公有静态getInstance()方法获取实例。

饿汉:不管需不需要都先创建好(浪费空间)

静态常量
public class Student {
	private Student() {}
	private static Student s = new Student();
	public static  Student getInstance() {
			return s;
	}
}
静态代码块
public class Student{
	private Student(){};
	private statice Student s;
	static{
		s=new Student();
	}
	public static Student getInstance() {
			return s;
	}
}

懒汉:需要的时候再创建实例

线程不安全
public class Student {
	private Student() {}
	private static Student s =null ;
	public static  Student getInstance() {
		if(s==null) {
			s = new Student();
		}
		return s;
	}
}
同步方法(不管是否实例化都加锁,会影响效率)
public class Student {
	private Student() {}
	private static Student s =null ;
	public static  synchronized  Student getInstance() {
		if(s==null) {
			s = new Student();
		}
		return s;
	}
}
同步代码块(不能绝对单例,多线程进入if判断则有问题)
public class Student {
	private Student() {}
	private static Student s =null ;
	public static   Student getInstance() {
		if(s==null) {
			synchronized(Student.class){
				s = new Student();
			}
		}
		return s;
	}
}
双重检查(DCL) 再加一个if判断
public class Student {
	private Student() {}
	private static Student s =null ;
	public static   Student getInstance() {
		if(s==null) {
			synchronized(Student.class){
				if(s==null) {
					s = new Student();
				}
			}
		}
		return s;
	}
}
JDK < 1.5 的时候不可用,由于volatile关键字会屏蔽Java虚拟机
所做的一些代码优化,可能会导致系统运行效率降低,
而JDK 1.5 以及之后的版本都修复了这个问题。

静态内部类,最推荐!

在Student类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载静态内部类,从而完成Student的实例化。 类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。

public class Student {
	private Student() {}
	private static class InnerStudent{
		private static final Student s = new Student();
	}
	public static  Student getInstance() {
		return InnerStudent.s;
	}
}

枚举

不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

public enum Student{
	STUDENT;
}

总结:
在这里插入图片描述

2、工厂模式:

一个工厂类根据传入的参量决定创建出哪一种产品类的实例。
简单工厂(静态工厂)
把创建对象的事情交给工厂来做。
缺点:有新的对象的时候要不断的修改工厂类,不利于后期的维护。

1.创建一个工厂类。
public class Factory {
	/*
	 *  获取对象的静态方法
	 */
	public static Object getInstance(String objectName) {
		if("person".equals(objectName)) {
			return new Person();
		}else if("student".equals(objectName)) {
			return new Student();
		}
	return null;	
	}
}
2.创建运行类main方法
public class Case1 {
	public static void main(String[] args) {
		// 获取一个对象  - 工厂模式 (创建对象) 
	Object instance = Factory.getInstance("person");
		Factory.getInstance("student");
	}
}

3、抽象工厂模式:

创建相关或依赖对象的家族,而无需明确指定具体类。

4、建造者模式:
封装一个复杂对象的创建过程,并可以按步骤构造。

5、原型模式:
通过复制现有的实例来创建新的实例。

结构型

1、装饰模式:

动态的给对象添加新的功能。
比如房子装修,那房子还是那个房子,只是在房子墙壁上做粉刷,贴墙纸,挂饰品等。java里面的io流,我们经常如下使用

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)))
1.创建一个电话接口
public interface PhoneOpration {
	/*打电话*/
	void  call();
}
2.创建电话类实现电话接口
public class Phone implements  PhoneOpration{
	@Override
	public void call() {
		System.out.println("通话。。。");
	}
}
3.创建一个电话装饰类实现电话接口
/*手机被装饰类*/
public class PhoneDecorate implements  PhoneOpration{
	/*手机对象引用*/
	private PhoneOpration phone;
	public PhoneDecorate(PhoneOpration phone) {
		super();
		this.phone = phone;
	}
	@Override
	public void call() {
		phone.call();
	}
}
4.创建音乐手机继承手机装饰类,就可以打电话之前听音乐
public class MusicPhone extends PhoneDecorate{
	public MusicPhone(PhoneOpration phone) {
		super(phone);
	}
	@Override
	public void call() {
		music();
		super.call();
	}
	public void music() {
		System.out.println("听歌曲");
	}
}
4.创建电影手机,就可以打电话之后看电影
public class MoviePhone extends PhoneDecorate{
	public MoviePhone(PhoneOpration phone) {
		super(phone);
	}
	@Override
	public void call() {
		super.call();
		movie();
	}
	public void movie() {
		System.out.println("看电影");
	}
}
创建测试类
public class TestPhone {
	public static void main(String[] args) {
		/*构建手机*/
		PhoneOpration op = new Phone();
		PhoneOpration opx = new PhoneDecorate(op)opx.call();/*打电话*/
		System.out.println("----------------------");
		PhoneOpration opz = new MusicPhone(opx);
		opz.call();/*听歌,打电话*/
		System.out.println("---------------------");
		PhoneOpration m = new MoviePhone(opz);
		m.call();/*听歌,打电话,看电影*/
	}
}

2、代理模式:

为其它对象提供一个代理以便控制这个对象的访问。
静态代理


动态代理

jdk动态代理
cglib动态代理

桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。

适配器模式:将一个类的方法接口转换成客户希望的另一个接口。

组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。

外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。

享元模式:通过共享技术来有效的支持大量细粒度的对象。

行为型

模板模式:

定义一个算法结构,而将一些步骤延迟到子类实现。

定义一个模板类
public  abstract class Template {
	/*实现任意业务逻辑*/
	public abstract  void  a();
	/*模板方法:计算任意方法运行花费的时间*/
	public  void getTime() {
		long start  = System.currentTimeMillis();
		a();
		long end  = System.currentTimeMillis();
		System.out.println("耗时:"+(end-start)/1000+"s");
	}	
}
子类继承模板类,并将具体方法延迟到子类
public class Case3 extends  Template{
	@Override
	public void a() {
		for(int i=0;i<10;i++) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("i="+i);
		}
	}
	public static void main(String[] args) {
		Case3 case3 = new Case3();
		//计算for循环耗时
		case3.getTime();
	}
}

策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。

命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。

迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

观察者模式:对象间的一对多的依赖关系。

仲裁者模式:用一个中介对象来封装一系列的对象交互。

备忘录模式:在不破坏封装的前提下,保持对象的内部状态。

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。

状态模式:允许一个对象在其对象内部状态改变时改变它的行为。

责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。

访问者模式:不改变数据结构的前提下,增加作用于一组对象元素的新功能。


版权声明:本文为qq_35368503原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。