设计模式总结

策略模式

策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
类图
在这里插入图片描述
代码

package strategy;

public interface Strategy {

	public void draw();

}

package strategy;

public class GreenPen implements Strategy{

	public void draw() {
		System.out.println("use green pen...");
	}

}
package strategy;

public class RedPen implements Strategy {

	public void draw() {
		System.out.println("use red pen...");
	}

}

package strategy;

public class Context {

	private Strategy strategy;

	public Context(Strategy strategy) {
		this.strategy = strategy;
	}

	public void startDraw() {
		strategy.draw();
	}

}

package strategy;

public class Test {

	public static void main(String[] args) {

		Context context = new Context(new RedPen());
		context.startDraw();

	}

}

运行
在这里插入图片描述

观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。
类图
在这里插入图片描述
代码

package observer;

public interface Observer {

	public void update(int state);

}

package observer;

public class BinaryObserver implements Observer {

	@SuppressWarnings("unused")
	private Subject subject;

	public BinaryObserver(Subject subject) {
		this.subject = subject;
		subject.registerObserver(this);
	}

	public void update(int state) {
		System.out.println(Integer.toBinaryString(state));
	}

}

package observer;

public interface Subject {

	public void registerObserver(Observer o);

	public void removeObserver(Observer o);

	public void notifyObservers();

}

package observer;

import java.util.*;

public class ConcreteSubject implements Subject {

	private List<Observer> observers = new ArrayList<>();
	private int state;

	public void registerObserver(Observer o) {
		observers.add(o);
	}

	public void removeObserver(Observer o) {
		observers.remove(o);
	}

	public void notifyObservers() {
		for (Observer o : observers) {
			o.update(state);
		}
	}

	public void setState(int state) {
		this.state = state;
		notifyObservers();
	}

}
package observer;

public class Test {

	public static void main(String[] args) {
		new ConcreteSubject();
		new BinaryObserver(new ConcreteSubject());

		ConcreteSubject subject = new ConcreteSubject();
		@SuppressWarnings("unused")
		Observer observer = new BinaryObserver(subject);
		subject.setState(25);
	}

}

运行
在这里插入图片描述

装饰者模式

装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
类图
在这里插入图片描述
代码

package decorator;

public interface Beverage {

	public void prepare();

}
package decorator;

public class Milk implements Beverage {

	public void prepare() {
		System.out.println("pour milk...");
	}

}

package decorator;

public class Sugar implements Beverage {

	private Beverage beverage;

	public Sugar(Beverage beverage) {
		this.beverage = beverage;
	}

	public void prepare() {
		beverage.prepare();
		System.out.println("add sugar...");
	}

}

package decorator;

public class Test {

	public static void main(String[] args) {
		Milk milk = new Milk();
		Sugar sugarMilk = new Sugar(milk);
		sugarMilk.prepare();
	}

}

运行
在这里插入图片描述

适配器模式

适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
类图
在这里插入图片描述
代码

package adapter;

public interface Duck {

	public void quack();

	public void fly();

}

package adapter;

public interface Turkey {

	public void gobble();

	public void fly();

}

package adapter;

public class WildTurkey implements Turkey {

	public void gobble() {

		System.out.println("gobble,gobble...");

	}

	public void fly() {
		System.out.println("fly a short distance...");
	}

}

package adapter;

public class TurkeyAdapter implements Duck {
	private Turkey turkey;

	public TurkeyAdapter(Turkey turkey) {
		this.turkey = turkey;
	}

	public void quack() {

		turkey.gobble();

	}

	public void fly() {
		for (int i = 0; i < 5; i++) {
			turkey.fly();
		}
	}

}

package adapter;

public class Test {

	public static void main(String[] args) {
		Turkey turkey = new WildTurkey();
		Duck duck = new TurkeyAdapter(turkey);
		duck.quack();
		duck.fly();
	}

}

运行
在这里插入图片描述

模板方法模式

模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
类图
在这里插入图片描述
代码

package templatemethod;

public abstract class Beverage {

	public final void prepare() {
		pour();
		add();
	}

	public final void pour() {
		System.out.println("pour into cup...");
	}

	public abstract void add();

}

package templatemethod;

public class Coffee extends Beverage {
	public void add() {
		System.out.println("add sugar...");
	}
}
package templatemethod;

public class Tea extends Beverage {

	public void add() {
		System.out.println("add lemon...");
	}

}

package templatemethod;

public class Test {

	public static void main(String[] args) {
		Coffee coffee = new Coffee();
		coffee.prepare();
		Tea tea = new Tea();
		tea.prepare();
	}

}

运行
在这里插入图片描述

命令模式

命令模式将“请求”封装成对象,将发出请求的对象和执行请求的对象解耦。
类图
在这里插入图片描述
代码

package command;

public interface Command {

	public void execute();

}

package command;

public class Light {

	public void on() {
		System.out.println("light is on...");
	}

}

package command;

public class LightOnCommand implements Command {

	private Light light;

	public LightOnCommand(Light light) {
		this.light = light;
	}

	public void execute() {
		light.on();
	}

}

package command;

public class RemoteControl {

	private Command slot;

	public void setCommand(Command command) {
		slot = command;
	}

	public void pressed() {
		slot.execute();
	}

}

package command;

public class Test {

	public static void main(String[] args) {

		Light light = new Light();
		LightOnCommand lightOnCommand = new LightOnCommand(light);
		RemoteControl remoteControl = new RemoteControl();
		remoteControl.setCommand(lightOnCommand);
		remoteControl.pressed();

	}

}

运行
在这里插入图片描述

外观模式

外观模式提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。
类图
在这里插入图片描述
代码

package facade;

public class Screen {

	public void down() {
		System.out.println("screen down...");
	}

	public void up() {
		System.out.println("screen up...");
	}

}
package facade;

public class Dvd {

	public void on() {
		System.out.println("turn on the dvd...");
	}

	public void off() {
		System.out.println("turn off the dvd...");
	}

}
package facade;

public class HomeTheater {

	private Screen screen;
	private Dvd dvd;

	public HomeTheater(Screen screen, Dvd dvd) {
		this.screen = screen;
		this.dvd = dvd;
	}

	public void watch() {
		screen.down();
		dvd.on();
	}

	public void end() {
		screen.up();
		dvd.off();
	}

}
package facade;

public class Test {

	public static void main(String[] args) {
		HomeTheater homeTheater = new HomeTheater(new Screen(), new Dvd());
		homeTheater.watch();
		homeTheater.end();
	}

}

运行
在这里插入图片描述

单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点。
类图
在这里插入图片描述
代码

package singleton;

//为什么要使用关键字volatile?

//防止指令重排序,对象的创建分为3步,首先分配内存,然后初始化,然后让引用指向对象的内存地址
//但是经过指令重排序之后,引用可能在初始化之前就指向内存的空间地址,这样有可能出现线程B访问到线程A未初始化的对象的情况
//使用volatile关键字防止指令重排,上述情况将不会发生

public class SingletonD {

	private static volatile SingletonD uniqueInstance;

	private SingletonD() {

	}

	public static SingletonD getInstance() {
		if (uniqueInstance == null) {//位置2
			synchronized (SingletonD.class) {
				if (uniqueInstance == null) {
					uniqueInstance = new SingletonD();//位置1
				}
			}
		}
		return uniqueInstance;
	}

}
package singleton;

public class Test {

	public static void main(String[] args) {
		SingletonD singleton1 = SingletonD.getInstance();
		SingletonD singleton2 = SingletonD.getInstance();
		System.out.println(singleton1);
		System.out.println(singleton2);

	}

}

运行
在这里插入图片描述
这里再解释一下为什么需要用关键字volatile,面试官问:为什么要使用volatile?我:为了防止指令重排序bulabula。面试官问:那如果把synchronize关键字放在整个方法上会存在这个问题吗?我:不会,synchronize关键字可以保证有序性(心虚,那之前也是用的synchronize关键字啊,只不过位置不同而已)。面试官:好了好了,问下一个吧。
我回来再想一想,如果把synchronize关键字放到整个方法上为什么不会出现问题,因为如果只对代码块加锁,当线程1执行到位置1时,有可能引用不为空,而内容(比如成员变量)为空,假设此时线程2执行到位置2,引用不为空,直接返回,那么它就拿到了一个内容为空的对象。如果对整个方法加锁,就不会出现这样的问题,即使在线程1中发生了重排序,中间结果对线程2也是不可见的。看来还是对双重检查加加锁的单例模式理解的不够透彻啊。

使用静态内部类实现单例模式
原理,1)加载一个类时,其静态内部类不会被加载,2)虚拟机保证一个类只能被加载一次。这个方法我觉得和上一个方法相同,都是懒汉模式,都可以实现线程安全,感觉这个方法的优势就是不需要加锁和volatile。

代码

package singleton;

public class SingletonE {

	private SingletonE() {

	}

	public static SingletonE getInstance() {
		return SingletonEHolder.UNIQUE_INSTANCE;
	}

	private static class SingletonEHolder {
		private static final SingletonE UNIQUE_INSTANCE = new SingletonE();
	}

}

package singleton;

public class Test {

	public static void main(String[] args) {
		SingletonE singleton1 = SingletonE.getInstance();
		SingletonE singleton2 = SingletonE.getInstance();
		System.out.println(singleton1);
		System.out.println(singleton2);

	}

}

运行
在这里插入图片描述

迭代器模式

迭代器模式提供一种方法顺序访问一个聚合对象的各个元素,而又不暴露其内部的表示。

组合模式

组合模式将对象组合成树形结构来表现“整体/部分”层次结构,组合能让客户以一致的方式处理对象以及对象组合。

状态模式

状态模式在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

代理模式

代理模式为另一个对象提供一个占位符,以控制对这个对象的访问。

工厂方法模式

工厂方法模式定义了一个创建对象的接口,但由子类来决定要实例化的类是哪一个。工厂方法让类把实例化延迟到子类。

抽象工厂模式

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

注意

适配器将一个对象包装起来以改变其接口,装饰者将一个对象包装起来以增加新的行为和责任,外观将一群对象包装起来以简化其接口。
工厂方法是模板方法的一种特殊版本。
状态模式允许一个对象基于内部状态而拥有不同的行为,策略模式通常会用行为或算法来配置Context类。
代理在结构上类似装饰者,但是目的不同,装饰者为对象加上行为,而代理则是控制访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值