java设计模式

1 创建型模式

1.1单例模式

某个类只能有一个实例,提供一个全局的访问点。

1.1.1单例模式结构

1、单例类
2、访问类

1.1.2 实现

分两种:
饿汉式:类加载就会导致该单实例对象被创建 浪费内存
懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建

1.1.2.1饿汉式(静态变量方式)
/**
*饿汉式
*静态变量创建类的对象
*/
public class Singleton{
	private static boolean flag = false;
	//私有构造方法
	private Singleton(){
	//解决反射破解单例的问题
		synchronized(Singleton.class){
			if(flag){
				throw new RuntimeException("不能创建多个对象");
			}
			flag = true;
		}
	}
	//解决序列化破坏单例的问题,当进行反序列化时,自动调用该方法
	public Object readResolve(){
		return instance;
	}
	//在成员位置创建该类的对象
	private static Singleton instance = new Singleton();
	//对外提供静态静态方法获取该对象
	public static Singleton getInstance(){
		return instance;
	}
}
public class Client{
	public static void main(String[] args){
		Singleton instance = Singleton.getInstance();
	}
}
1.1.2.2饿汉式(静态代码块方式)
/**
*饿汉式
*静态代码块创建类的对象
*/
public class Singleton{
	private static boolean flag = false;
	//私有构造方法
	private Singleton(){
	//解决反射破解单例的问题
		synchronized(Singleton.class){
			if(flag){
				throw new RuntimeException("不能创建多个对象");
			}
			flag = true;
		}
	}
	//解决序列化破坏单例的问题,当进行反序列化时,自动调用该方法
	public Object readResolve(){
		return instance;
	}
	//在成员位置创建该类的对象
	private static Singleton instance;
	static{
		instance = new Singleton();
	}
	//对外提供静态静态方法获取该对象
	public static Singleton getInstance(){
		return instance;
	}
}
public class Client{
	public static void main(String[] args){
		Singleton instance = Singleton.getInstance();
	}
}
1.1.2.3懒汉式 方式1(线程不安全)
/**
*懒汉式
*线程不安全
*/
public class Singleton{
	private static boolean flag = false;
	//私有构造方法
	private Singleton(){
	//解决反射破解单例的问题
		synchronized(Singleton.class){
			if(flag){
				throw new RuntimeException("不能创建多个对象");
			}
			flag = true;
		}
	}
	//解决序列化破坏单例的问题,当进行反序列化时,自动调用该方法
	public Object readResolve(){
		return instance;
	}
	//在成员位置创建该类的对象
	private static Singleton instance;
	
	//对外提供静态静态方法获取该对象
	public static Singleton getInstance(){
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}
}
public class Client{
	public static void main(String[] args){
		Singleton instance = Singleton.getInstance();
	}
}
1.1.2.4枚举实现方式
/**
*饿汉式
*推荐三
*线程安全
*不会被破坏
*不考虑空间的情况下
*/
public enum Singleton{
	INSTANCE;
}
public class Client{
	public static void main(String[] args){
		Singleton instance = Singleton.INSTANCE();
	}
}
1.1.2.5懒汉式 方式2(线程安全 加同步锁)
/**
*懒汉式
*线程不安全
*/
public class Singleton{
	private static boolean flag = false;
	//私有构造方法
	private Singleton(){
	//解决反射破解单例的问题
		synchronized(Singleton.class){
			if(flag){
				throw new RuntimeException("不能创建多个对象");
			}
			flag = true;
		}
	}
	//解决序列化破坏单例的问题,当进行反序列化时,自动调用该方法
	public Object readResolve(){
		return instance;
	}
	//在成员位置创建该类的对象
	private static Singleton instance;
	
	//对外提供静态静态方法获取该对象
	//同步锁
	public static synchronized Singleton getInstance(){
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}
}
public class Client{
	public static void main(String[] args){
		Singleton instance = Singleton.getInstance();
	}
}
1.1.2.6懒汉式 方式3(线程安全 双重检查锁)
/**
*推荐二
*懒汉式
*线程安全
*/
public class Singleton{
	private static boolean flag = false;
	//私有构造方法
	private Singleton(){
	//解决反射破解单例的问题
		synchronized(Singleton.class){
			if(flag){
				throw new RuntimeException("不能创建多个对象");
			}
			flag = true;
		}
	}
	//解决序列化破坏单例的问题,当进行反序列化时,自动调用该方法
	public Object readResolve(){
		return instance;
	}
	//在成员位置创建该类的对象
	private static Singleton instance;
	
	//对外提供静态静态方法获取该对象
	//同步锁 synchronized
	//volatile 保证可见性和有序性
	public static volatile Singleton getInstance(){
	//第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象
		if(instance == null){
			synchronized(Singelton.class){
			//第二次判断
				if(instance == null){
					instance = new Singleton();
				}
			}
			
		}
		return instance;
	}
}
public class Client{
	public static void main(String[] args){
		Singleton instance = Singleton.getInstance();
	}
}
1.1.2.7懒汉式 方式4(静态内部类)
/**
*推荐一
*线程安全
*是开源项目中比较常用的一种单例模式,在没有加任何锁的情况下,保证了多线程下的安全,并且没有任何性能影响和空间的浪费
*/
public class Singleton{
	private static boolean flag = false;
	//私有构造方法
	private Singleton(){
	//解决反射破解单例的问题
		synchronized(Singleton.class){
			if(flag){
				throw new RuntimeException("不能创建多个对象");
			}
			flag = true;
		}
	}
	//解决序列化破坏单例的问题,当进行反序列化时,自动调用该方法
	public Object readResolve(){
		return SingletonHoler.INSTANCE;
	}
	private static class SingletonHolder{
		private static final Singleton INSTANCE = new Singleton();
	}
	
	public static  Singleton getInstance(){
		return SingletonHolder.INSTANCE;
	}
}
public class Client{
	public static void main(String[] args){
		Singleton instance = Singleton.getInstance();
	}
}
1.1.3存在的问题

有两种方式会破坏单例模式
1、序列化反序列化
2、反射

1.2 简单工厂

1.2.1概念

一个工厂类根据传入的参量决定创建出那一种产品类的实例。

/**
*咖啡类
*/
public abstract  class Coffee{
	public abstract String getName();
	
	public void addSuger(){
		System.out.println("加糖")
	}
	public void addMilk(){
		System.out.println("加糖")
	}
}
/**
*美式咖啡类
*/
public class AmericanCoffee extends Coffee{
	public String getName(){
		System.out.println("美式咖啡")
	}
}
/**
*美式咖啡类
*/
public class LatteCoffee extends Coffee{
	public String getName(){
		System.out.println("拿铁咖啡")
	}
}
/**
*咖啡店
*/
public class CoffeeStore {
	public Coffee orderCoffee(String type){
		SimpleCoffeeFactory factory = new SimpleCoffeeFactory();
		Coffee coffee = factory.createCoffee(type);
		coffee.addMilk();
		coffee.addSugar();
		return coffee;
	}
}
/**
*咖啡工厂
*/
public class SimpleCoffeeFactory{
	public Coffee createCoffee(String type){
		Coffee coffee = null;
		if(type.equals("American")){
			coffee = new AmericanCoffee()
		}else if(type.equals("Latte")){
			coffee = new LatteCoffee ()
		}else{
			throw new RuntimeException("异常");
		}
		return coffee;
	}
}
public class Client{
	public static void main(String[] args){
		CoffeeStore  coffeeStore = new CoffeeStore();
		Coffee coffee = coffeeStore.orderCoffee("American");
	}
}

1.2.2 优缺点

缺点:违背开闭原则

1.3 工厂方法

1.3.1概念

定义一个创建对象的接口,让子类决定实例化那个类。

public interface CoffeeFactory{
	public Coffee createCoffee();
}
public class AmericanCoffeeFactory implements CoffeeFactory{
	public Coffee createCoffee(){
	 	return new AmericanCoffee();
	}
}
public class LatterCoffeeFactory implements CoffeeFactory{
	public Coffee createCoffee(){
	 	return new LatterCoffee();
	}
}
/**
*咖啡类
*/
public abstract  class Coffee{
	public abstract String getName();
	
	public void addSuger(){
		System.out.println("加糖")
	}
	public void addMilk(){
		System.out.println("加糖")
	}
}
/**
*美式咖啡类
*/
public class AmericanCoffee extends Coffee{
	public String getName(){
		System.out.println("美式咖啡")
	}
}
/**
*美式咖啡类
*/
public class LatteCoffee extends Coffee{
	public String getName(){
		System.out.println("拿铁咖啡")
	}
}
/**
*咖啡店
*/
public class CoffeeStore {
	private CoffeeFactory factory;
	public void setFactory(CoffeeFactory factory){
		this.factory = factory;
	}
	public Coffee orderCoffee(){
		Coffee coffee = factory.createCoffee();
		coffee.addMilk();
		coffee.addSugar();
		return coffee;
	}
}
public class Client{
	public static void main(String[] args){
		CoffeeFactory factory = new AmericanCoffeeFactory();
		CoffeeStore  store = new CoffeeStore();
		store.setFactory(factory)
		Coffee coffee = store.orderCoffee();
	}
}

1.3.2 优缺点

优点:无需对原工厂进行修改,符合开闭原则
缺点:每增加一个产品就要增加一个具体产品类和对应的具体工厂类,增加了系统的复杂度

1.4 抽象工厂

1.4.1概念

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

/**
*咖啡类
*/
public abstract  class Coffee{
	public abstract String getName();
	
	public void addSuger(){
		System.out.println("加糖")
	}
	public void addMilk(){
		System.out.println("加糖")
	}
}
/**
*美式咖啡类
*/
public class AmericanCoffee extends Coffee{
	public String getName(){
		System.out.println("美式咖啡")
	}
}
/**
*美式咖啡类
*/
public class LatteCoffee extends Coffee{
	public String getName(){
		System.out.println("拿铁咖啡")
	}
}
/**
*甜品抽象类
*/
public abstract class Dessert{
	public abstract void show();
}
/**
*提拉米苏
*/
public class Trimisu extends Dessert{
	public abstract void show(){
	System.out.println("提拉米苏")
	}
}
/**
*抹茶慕斯
*/
public class MatchaMousse extends Dessert{
	public abstract void show(){
	System.out.println("抹茶慕斯")
	}
}
/**
*工厂接口
*/
public interface Factory{
	public Coffee createCoffee();
	public Dessert createDessert();
}
/**
*美式风味工厂接口
*/
public class AmericanFactory implements Factory{
	public Coffee createCoffee(){
	 	return new AmericanCoffee();
	}
	public Dessert createDessert(){
		return new MatchaMousse ();
	}
}
/**
*意大利风味工厂接口
*/
public class ItalyFactory implements Factory{
	public Coffee createCoffee(){
	 	return new LatterCoffee();
	}
	public Dessert createDessert(){
		return new Trimisu ();
	}
}
public class Client{
	public static void main(String[] args){
		ItalyFactory factory = new ItalyFactory ();
		Coffee coffee = factory.createCoffee();
		Dessert dessert = factory.createDessert();
	}
}

1.4.2 优缺点

优点:当一个产品族中的多个对象被设计在一起工作时,它能保证客户端始终只使用同一个产品族中的对象
缺点:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改

1.4.3 使用场景

  • 当需要创建的对象是一系列相互关联或依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等
  • 系统中有多个产品族,但每次只使用其中一个族产品,如有人只喜欢穿一个牌子的衣服和鞋
  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实列的创建细节和内部结构,如输入法皮肤,一整套一起换

1.5 建造者模式

1.5.1概念

封装一个复杂对象的构建过程,并可以按步骤构造。

1.6 原型模式

1.6.1 概念

通过复制现有的实例来创建新的实例。

1.6.2 结构

1.6.2 实现

浅克隆:对于非基本类型属性,仍指向原有属性所指向得对象的内存地址
深克隆:对于非基本类型属性,不再指向原有属性所指向得对象的内存地址

/**
*java中的Object类中提供了clone()方法来实现浅克隆
*/
public class Realizetype implents Cloneable{
	public Realizetype(){
		System.out.pringln("具体的原型对象创建完成");
	}
	@Override
	protected Realizetype  clone() throw cloneNotSupportedException{
		return (Realizetype) super.clone();
	}
}

1.6.2 使用场景

  • 对象的创建非常复杂,可以使用原型模式快捷的创建对象
  • 性能和安全性要求比较高

1.6.2 扩展(深克隆)

public class Citation implements Cloneable,Serializable{
	private Student st;
	public Student getStu(){
		return stu;
	}
	public void setStu(Student stu){
		this,stu = stu;
	}
	void show(){
		System.out.println(stu.getName())
	}
	@Override
	protected Citation clone() throw cloneNotSupportedException{
		return (Citation ) super.clone();
	}
}
public class Client{
	public static void main(String[] args) throw CloneNotSupportedException {
		Citation citation = new Citation ();
		Student stu= new Student();
		stu.setName("张三");
		citation.setStu(stu); 
		//创建对象输出流
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/robin/a.txt"));
		//写对象
		oos.writeObject(citation);
		//释放资源
		oos.close();
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/robin/a.txt"));
		Citation citation1=(Citation) ois.readObject();
		//释放资源
		ois.close();
		Student stu1 = citation1.getStu();
		stu1.setName("李四");
		citation.show();
		citation1.show();
	}
}

2 结构型模式

2.1 适配器模式

2.1.1概念

将一个类的方法接口转换成客户希望的另外一个接口。

2.2 组合模式

2.2.1概念

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

2.3 装饰模式

2.3.1概念

动态的给对象添加新的功能。

2.4 代理模式

2.4.1概念

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

2.5 亨元(蝇量)模式

2.5.1概念

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

2.6 外观模式

2.6.1概念

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

2.7 桥接模式

2.7.1概念

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

3 行为型模式

3.1 模板模式

3.1.1概念

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

3.2 解释器模式

3.2.1概念

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

3.3 策略模式

3.3.1概念

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

3.4 状态模式

3.4.1概念

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

3.5 观察者模式

3.5.1概念

对象间的一对多的依赖关系。

3.6 备忘录模式

3.6.1概念

在不破坏封装的前提下,保持对象的内部状态。

3.7 中介者模式

3.7.1概念

用一个中介对象来封装一系列的对象交互。

3.8 命令模式

3.8.1概念

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

3.9 访问者模式

3.9.1概念

在不改变数据结构的前提下,增加作用于一组对象元素的新功能。

3.10 责任链模式

3.10.1概念

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

3.11 迭代器模式

3.11.1概念

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xx1433251330

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值