设计模式
[toc]
零、资料
一、创建型 1、单例模式 单例模式(Singleton)是一种非常简单且容易理解的设计模式。
顾名思义,单例即单一的实例 ,确切地讲就是指在某个系统中只存在一个实例,同时提供集中、统一的访问接口,以使系统行为保持协调一致。
1.1、饿汉式 注意事项:
private
单例类的无参构造器。
单例类 的内部定义一个单例类类型的静态常量 作为成员变量。
提供一个public
的静态获取单例的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class HungrySingletonTest { public static void main (String[] args) { HungrySingleton instance1 = HungrySingleton.getInstance(); HungrySingleton instance2 = HungrySingleton.getInstance(); System.out.println(instance1==instance2); } } class HungrySingleton { private static final HungrySingleton singleton = new HungrySingleton(); private HungrySingleton () {} public static HungrySingleton getInstance () { return singleton; } }
1.2、懒汉式 注意事项:
private
无参构造器
单例类 的内部定义一个单例类类型的静态 成员变量,并且使用volatile
关键字来修饰,保证多线程时给成员变量的同步性、唯一性 。
提供一个public
的静态获取单例的方法。该方法内需要先判断实例是否为空 ,若不为空,则直接返回;若为空,则对该实例的Class对象加锁,加锁后如果仍然为空,则new一个实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class LazySingletonTest { public static void main (String[] args) { LazySingleton instance1 = LazySingleton.getInstance(); LazySingleton instance2 = LazySingleton.getInstance(); System.out.println(instance1 == instance2); } } class LazySingleton { private volatile static LazySingleton singleton; private LazySingleton () {} public static LazySingleton getInstance () { if (singleton==null ){ synchronized (LazySingleton.class){ if (singleton==null ){ singleton = new LazySingleton(); } } } return singleton; } }
2、工厂方法模式 一个工厂,生产多种产品。
步骤:
(1)产品接口-Car:
1 2 3 public interface Car { public void driver () ; }
(2-1)产品实现类-BMWCar:
1 2 3 4 5 6 public class BMWCar implements Car { @Override public void driver () { System.out.println("BMWCar。。。。驾驶" ); } }
(2-2)产品实现类-AudiCar:
1 2 3 4 5 6 public class AudiCar implements Car { @Override public void driver () { System.out.println("AudiCar。。。。驾驶" ); } }
(3)工厂:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class CarFactory2 { public static Car produceCar (String brand) { Car car = null ; switch (brand){ case "bmw" :{ car = new BMWCar(); break ; } case "audi" :{ car = new AudiCar(); break ; } } return car; } }
(4)调用:
1 2 3 4 5 6 7 8 9 10 public class Test { public static void main (String[] args) { Car car1 = CarFactory2.produceCar("bmw" ); Car car2 = CarFactory2.produceCar("audi" ); car1.driver(); car2.driver(); } }
静态工厂方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class CarFactory2 { public static Car produceCar (String brand) { Car car = null ; switch (brand){ case "bmw" :{ car = new BMWCar(); break ; } case "audi" :{ car = new AudiCar(); break ; } default :{ car = new BydCar(); break ; } } return car; } }
3、抽象工厂模式 多个工厂,生产多种产品。
四个主要的涉及的代码:
工厂接口
工厂接口的实现类
产品接口
产品接口的实现类
步骤:
产品接口,定义 产品接口的抽象方法
产品接口的实现类,实现 产品接口的抽象方法
工厂接口,定义 工厂接口(用于生产产品)的抽象方法
工厂接口的实现类,实现 工厂(用于生产产品)的抽象方法
工厂接口,new 一个实现类,赋值给一个static
的工厂类型 的成员变量
工厂接口,编写一个static
的提供工厂实现类 的方法。
(1)产品接口:
1 2 3 public interface Car { public void driver () ; }
(2)产品实现类:
1 2 3 4 5 6 public class BMWCar implements Car { @Override public void driver () { System.out.println("BMWCar。。。。驾驶" ); } }
(3)工厂接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public interface CarFactory { public Car produceCar () ; public static CarFactory factory = new CarFactoryImpl(); public static CarFactory getFactory () { return factory; } }
(4)工厂实现类:
1 2 3 4 5 6 7 public class CarFactoryImpl implements CarFactory { @Override public Car produceCar () { return new BMWCar(); } }
4、原型模式 原型模式,即Prototype
,是指创建新对象的时候,根据现有的一个类来创建。
步骤:
实现Cloneable接口
,重写Object
类的 clone()
方法。
复制 数据,返回 对象。
获取并强转 新对象。
初始版本:(缺点:获取新的对象后,需要强转数据类型)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class Student implements Cloneable { private int id; private String name; private int score; public Object clone () { Student std = new Student(); std.id = this .id; std.name = this .name; std.score = this .score; return std; } }
优化版本:(直接定义一个复制方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Student { private int id; private String name; private int score; public Student copy () { Student std = new Student(); std.id = this .id; std.name = this .name; std.score = this .score; return std; } }
5、生成器模式 生成器模式(Builder)是使用多个“小型”工厂来最终创建出一个完整对象。
1 2 3 4 5 6 7 8 String url = URLBuilder.builder() .setDomain("www.liaoxuefeng.com" ) .setScheme("https" ) .setPath("/" ) .setQuery(Map.of("a" , "123" , "q" , "K&R" )) .build();
二、结构型 1、适配器模式 适配器 - 廖雪峰
适配器模式是Adapter,也称Wrapper,是指如果一个接口待传入的对象是A接口,但是却需要B接口,这种情况下的接口转换。
List<T> Arrays.asList(T[])
方法就相当于一个转换器,它可以把数组转换为List
。
Adapter模式可以将一个A接口转换为B接口,使得新的对象符合B接口规范。
编写Adapter实际上就是编写一个实现了B接口,并且内部持有A接口的类:
1 2 3 4 5 6 7 8 9 public BAdapter implements B { private A a; public BAdapter (A a) { this .a = a; } public void b () { a.a(); } }
Adapter内部将B接口的调用“转换”为对A接口的调用。
只有A、B接口均为抽象接口 时,才能非常简单地实现Adapter模式。
2、桥接模式 桥接模式就是为了避免直接继承带来的子类数量大量增加。
桥接模式实现比较复杂,实际应用也非常少,但它提供的设计思想值得借鉴,即不要过度使用继承,而是优先拆分某些部件,使用组合的方式来扩展功能。
五个部分:
一个抽象类
一个接口
抽象类的修正类(作用:与接口产生关联)
接口的实现类
修正类的实现类
例子:
Enigne 接口
:
1 2 3 public interface Engine { void start () ; }
Car 抽象类
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package car;import engine.Engine;public abstract class Car { protected Engine engine; public Car (Engine engine) { this .engine = engine; } public abstract void drive () ; }
RefinedCar 抽象类
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package car;import engine.Engine;public abstract class RefinedCar extends Car { public RefinedCar (Engine engine) { super (engine); } public abstract String getBrand () ; @Override public void drive () { this .engine.start(); System.out.println("Drive " + getBrand() + " car..." ); } }
AudiCar
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package car;import engine.Engine;public class AudiCar extends RefinedCar { public AudiCar (Engine engine) { super (engine); } @Override public String getBrand () { return "audi" ; } }
HybridEngine
:
1 2 3 4 5 6 7 8 package engine;public class HybridEngine implements Engine { @Override public void start () { System.out.println("Start Hybrid Engine..." ); } }
测试
:
1 2 3 4 5 6 7 8 9 10 11 import car.AudiCar;import car.RefinedCar;import engine.HybridEngine;public class Test { public static void main (String[] args) { RefinedCar audiCar = new AudiCar(new HybridEngine()); audiCar.drive(); } }
三、行为型