设计模式总结:
1、单例模式:饿汉模式;懒汉模式;
懒汉模式中:
双重检测机制,判断为null,锁定对象,再判断为null,生成对象
防止指令重排,给对象增加一个修饰符 volatile
利用枚举,可以防止反射破坏单例模式
2、工厂模式:在一个类中,根据参数得不同值,去生成不同得对象,类似于一个工厂
静态工厂模式:生产同一种产品
抽象工厂模式:
在一个抽象类工厂中,实现多种产品的生产方法;
factory工厂类继承抽象工厂,实现工厂的多个产品的生产方法;
调用factory工厂的不同产品的生产方法,生产不同的产品
3、装饰者模式:就是在原有接口方法的基础上,增加新的功能 ;类似于代理模式
4、适配器模式:加一层接口适配,实现其他类的方法;类似于代理模式
5、代理模式:
静态代理:
代理人与被代理人实现同一个接口,
代理人添加接口一个私有属性并生成该含该属性的构造方法,或者是set方法
通过新建代理对象,构造方法(set方法)传入被代理对象,实现代理
动态代理:代理人与被代理人实现的接口变为动态
6、观察者模式:发布订阅模式
7、外观模式:将很多次的接口调用,用一个更高级的接口进行封装,使得系统更容易使用;封装底层
8、状态模式:根据内部状态的变化,改变这个对象的行为
9、策略模式:封装不同的算法
设计模式
1、单例模式
保证一个类只有一个实例,并且全局提供一个全局访问点
1. 构造方法私有化,保证外界不能新建实例
2. 设置一个静态变量接收实例对象
3. 提供一个全局访问点,可以访问到这个实例,静态方法获取该实例对象
场景:重量级对象,不需要多个实例,比如线程池,数据库连接池
饿汉模式:上来就初始化加载实例
public class Hungry {
//饿汉式会造成空间浪费
//单例模式的核心就是私有化构造
private Hungry(){
}
private final static Hungry HUNGRY = new Hungry();
public static Hungry getInstance(){
return HUNGRY;
}
}
懒汉模式:需要的时候再初始化
//单例模式的特征就是构造器私有化
public class LazyMan {
private LazyMan() {
}
// volatile 避免指令重排的标识符
private volatile static LazyMan instance;
private static LazyMan getInstance(){
//双重监测锁模式的 懒汉式单例 DCL 懒汉式
if(instance==null){
//锁住这个对象 多线程模式下如果不锁柱对象,会使单例模式失效,产生多个实例
synchronized (LazyMan.class){
if(instance==null){
LazyMan instance = LazyMan.getInstance();//不是原子性操作
/*
* 1、分配内存空间
* 2、执行构造方法,初始化对象
* 3、把这个对象指向这个空间
* 正常情况下走1、2、3没有问题,如果指令重排走了1、3、2的步骤,
* 可能就会造成已经给这个对象指向空间了,
* 另外一个线程判断这个空间是由对象的,就会直接返回实例,
* 实际上这个实例还没有完成2步骤的操作,没有实例化,就会造成返回null值对象
* 因此需要再这个对象上面加上避免指令重排的标识符 volatile
*/
}
}
}
return instance;
}
//反射破坏单例模式
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
LazyMan instance1 = LazyMan.getInstance();
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan instance2 = declaredConstructor.newInstance();
System.out.println(instance1);
System.out.println(instance2);
}
}
枚举实现单例
单例模式会被反射获取实例进行破坏,实例可能会生成多个
枚举:也是一个class,只是集成了一个枚举类
//枚举是什么?本身也是一个class
public enum EnumSingle {
INSTANCE;
private static EnumSingle getInstance(){
return INSTANCE;
}
//枚举类型可以防止使用反射构造对象
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
EnumSingle instance1 = EnumSingle.INSTANCE;
Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
EnumSingle instance2 = declaredConstructor.newInstance();
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
}
}
==枚举下的单例模式,无法使用反射进行对象的实例化 ==
2、工厂模式
简单工厂模式:又称静态工厂方法模式,它属于类创建型模式。
-在简单工厂模式中,可以根据参数的不同返回不同类的实例。
-简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都有共同的父类
public class SimpleFactory {
public Product creatProduct(String type){
if("A".equals(type))
return new A();
else
return new B();
}
public static void main(String[] args) {
Product product = new SimpleFactory().creatProduct("A");
product.print();
}
}
abstract class Product{
public abstract void print();
}
class A extends Product{
@Override
public void print() {
System.out.println("产品A");
}
}
class B extends Product{
@Override
public void print() {
System.out.println("产品B");
}
}
工厂模式:生产不同参数的Product,但还是生产同一种产品
例如
1、Collection接口就是一个大的工厂,ArraryList和LinkedList就是两个小工厂,迭代器Iterator就是产品
2、Collection在有一个获取迭代器Iterator的抽象方法
3、两个小工厂继承Collection,实现Iterator的抽象方法,通过不同的工厂去生产不同的迭代器Iterator
抽象工厂模式,即一个工厂可以生产很多种不一样的产品
public interface AbstractFactory {
Phone creatPhone(String params);
Mask createMask(String params);
}
class SuperFactory implements AbstractFactory {
@Override
public Phone creatPhone(String params) {
return new IPhone();
}
@Override
public Mask createMask(String params) {
return new N95();
}
}
interface Mask {}
class N95 implements Mask{ }
interface Phone { }
class IPhone implements Phone{ }
3、装饰者模式
动态的给一个对象添加一些额外的功能。
就增加功能来说,装饰模式比生成子类更灵活。
public class DecoratorPattern {
public static void main(String[] args) {
RobotDecorate robotDecorate = new RobotDecorate(new FirstRobot());
robotDecorate.doMoreThing();
}
}
interface Robot{
void doSomeThing();
}
class FirstRobot implements Robot{
@Override
public void doSomeThing() {
System.out.println("唱歌");
}
}
class RobotDecorate implements Robot{
private Robot robot;
public RobotDecorate(Robot robot){
this.robot = robot;
}
@Override
public void doSomeThing() {
robot.doSomeThing();
}
public void doMoreThing(){
System.out.println("跳舞");
}
}
总结:装饰者模式就是实现原有的接口,并在此基础上添加新的功能
4、适配器模式
将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能在一起工作
public class AdapterPattern {
public static void main(String[] args) {
String result = new Adapter(new Speaker()).translate();
}
}
class Speaker {
public String speak() {
return "主持人播报新闻";
}
}
interface Translator {
String translate();
}
class Adapter implements Translator {
private Speaker speaker;
public Adapter(Speaker speaker) {
this.speaker = speaker;
}
@Override
public String translate() {
String result = speaker.speak();
return result;
}
}
与装饰者模式的区别在于,装饰者模式事扩展功能,适配器模式是使用想要的接口功能,不涉及到扩展
5、观察者模式
就是发布订阅模式;
public class ObservePattern {
public static void main(String[] args) {
X x = new X();
x.borrow(new A());
x.borrow(new B());
x.borrow(new C());
x.notice();
}
}
interface debt{
void borrow(Credit credit);
void notice();
}
interface Credit{
void takemoney();
}
class X implements debt{
List<Credit> list =new ArrayList<>();
@Override
public void borrow(Credit credit) {
list.add(credit);
}
@Override
public void notice() {
for (Credit credit : list) {
credit.takemoney();
}
}
}
class A implements Credit{
@Override
public void takemoney() {
System.out.println("A来要钱");
}
}
class B implements Credit{
@Override
public void takemoney() {
System.out.println("B来要钱");
}
}
class C implements Credit{
@Override
public void takemoney() {
System.out.println("C来要钱");
}
}
6、外观模式
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供了一个高层次的接口,使得子系统更容易使用
通俗点理解:即一个系统需要经过很多次的接口调用,用一个更高级的接口进行封装,使之调用这个接口即可一步完成
7、状态模式
允许一个对象在其内部状态改变时改变他的行为
public class StatePattern {
public static void main(String[] args) {
Context zhangsan = new Context();
zhangsan.changeState(new Happy());
zhangsan.doSomething();
zhangsan.changeState(new Sad());
zhangsan.doSomething();
}
}
interface State {
void doWork();
}
class Happy implements State {
@Override
public void doWork() {
System.out.println("高兴的工作");
}
}
class Sad implements State {
@Override
public void doWork() {
System.out.println("悲伤的工作");
}
}
class Context {
private State state;
public void changeState(State state) {
this.state = state;
}
public void doSomething(){
state.doWork();
}
}
8、策略模式
定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。策略模式让算法独立于他使用 他的客户而变化。
类似于状态模式