一、单例模式
1、饿汉
(1)饿汉-静态变量
class SingletonTest {
private static SingletonTest instance = new SingletonTest();
private SingletonTest() {
}
public static SingletonTest getInstance() {
return instance;
}
}
(2)饿汉-静态代码块
class SingletonTest {
private static SingletonTest instance;
static {
instance = new SingletonTest();
}
private SingletonTest() {
}
public static SingletonTest getInstance() {
return instance;
}
}
2、懒汉
(1)懒汉-同步方法(不推荐使用)
class SingletonTest {
private static SingletonTest instance;
private SingletonTest() {
}
public static synchronized SingletonTest getInstance() {
if (instance == null) {
instance = new SingletonTest();
}
return instance;
}
}
(2)懒汉-双重检查(推荐使用)
class SingletonTest {
private static volatile SingletonTest instance;
private SingletonTest() {
}
public static SingletonTest getInstance() {
if (instance == null) {
synchronized (SingletonTest.class) {
if (instance == null) {
instance = new SingletonTest();
}
}
}
return instance;
}
}
volatile 关键字是为了让线程可见和防止指令重排。
3、单例模式在jdk中的使用
public class Runtime {
private static Runtime currentRuntime = new Runtime();
private Runtime(){
}
public static Runtime getRuntime(){
return currentRuntime;
}
}
4、单例模式的好处
(1)避免频繁创建销毁对象
(2)垃圾回收
二、工厂模式
1、简单工厂模式(静态工厂模式)
(1)包含三个角色
1)抽象产品(抽象类或者接口)
2)具体产品(子类实现类)
3)工厂角色(提供静态获取方法)
(2)获取图标的例子
- 抽象产品类(使用接口来充当)
public interface Chart {
void dispaly();
}
- 具体产品类(柱状图)
public class HistoChart implements Chart {
public HistoChart() {
sout ("创建柱状图!");
}
public void display() {
sout ("显示柱状图!");
}
}
- 具体产品类(折线图)
public class LineChart implements Chart {
public LineChart() {
sout ("创建折线图!");
}
public void display() {
sout ("显示折线图!");
}
}
- 工厂角色
public class ChartFactory {
// 静态工厂方法
public static Chart getChart(String type) {
if ("histo".equals(type)) {
return new HistoChart();
}
if ("line".equals(type)) {
return new LineChart();
}
return null;
}
}
2、工厂方法模式
(1)包含四个角色
1)抽象产品
2)具体产品
3)抽象工厂角色
4)具体工厂角色
(2)获取日志记录器的例子
- 抽象产品类
public interface Logger {
public void writeLog();
}
- 具体产品类(数据库日志记录器)
public class DataBaseLogger implements Logger {
public void writeLog(){
sout("数据库日志记录!");
}
}
- 具体产品类(文件日志日志记录器)
public class FileLogger implements Logger {
public void writeLog(){
sout("文件日志记录!");
}
}
- 抽象工厂角色
public interface LoggerFactory{
// 抽象工厂方法
public Logger createLogger();
}
- 具体工厂角色(数据库工厂)
public class DataBaseLoggerFactory implements LoggerFactory {
public Logger createLogger() {
return new DataBaseLogger();
}
}
- 具体工厂角色(文件工厂)
public class FileLoggerFactory implements LoggerFactory {
public Logger createLogger() {
return new FileLogger();
}
}
3、抽象工厂模式
(1)包含四个角色
1)抽象产品(m个类,产品继承结构的父类)
2)具体产品(n*m个类,n:产品族,m:产品继承结构)
3)抽象工厂角色(m个类,1个类/接口声明创建一族产品的方法)
4)具体工厂角色(n个类,一个类对应一个产品族。如海尔一个工厂、TCL一个工厂)
(2)电器的例子(电视、冰箱、洗衣机……)(海尔、美的、TCL……)
- 抽象产品类(电视)
public interface TV {
public void run();
}
- 抽象产品类(冰箱)
public interface BingXiang {
public void run();
}
- 具体产品类(海尔电视)
public class HairTV implements TV{
public void run(){
sout("hairTV");
}
}
- 具体产品类(海尔冰箱)
public class HairBingXiang implements BingXiang{
public void run(){
sout("HairBingXiang");
}
}
- 具体产品类(TCL电视)
public class TCLTV implements TV{
public void run(){
sout("TCLTV");
}
}
- 具体产品类(TCL冰箱)
public class TCLBingXiang implements BingXiang{
public void run(){
sout("TCLBingXiang");
}
}
- 抽象工厂类(电器)
public class DianQiFactory implements BingXiang{
TV getTV ();
BingXiang getBingXiang ();
}
- 具体工厂类(海尔工厂)
public class HairFactory implements DianQiFactory{
public TV getTV (){
return new HairTV();
}
public BingXiang getBingXiang (){
return new HairBingXiang();
}
}
- 具体工厂类(TCL工厂)
public class TCLFactory implements DianQiFactory{
public TV getTV (){
return new TCLTV();
}
public BingXiang getBingXiang (){
return new TCLBingXiang();
}
}
三、原型模式
1、原型模式通过复制一个已有对象来获取更多相同或相似的对象
2、包含三个角色
(1)抽象原型
(2)具体原型类
(3)客户类
3、深拷贝和浅拷贝
(1)浅拷贝(clone方法)
(2)深拷贝(序列化和反序列化)
3.1、浅拷贝
(1)实现Cloneable接口
(2)重写clone()方法
3.2、深拷贝
要拷贝的对象需要实现Serializable接口
package com.hjp.test;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hjp.DO.Person;
import org.junit.Test;
public class Json {
@Test
public void test01() {
// 创建对象(嵌套两层)
Person person = new Person("hjp", 20000, 22, "男", "area", new Person("lcr", 20000, 22, "男", "area"));
// 将对象转为json字符串方法
String jsonString = JSONObject.toJSONString(person);
System.out.println("jsonString = " + jsonString);
// 将json字符串转化为对象
Person parseObject = JSON.parseObject(jsonString, Person.class);
// 验证:嵌套格式的json字符串被全部转为对象格式
String name = parseObject.getPerson().getName();
System.out.println("name = " + name);
}
}
四、代理模式
1、包含三个角色
(1)抽象主题类
(2)具体主题类
(3)代理主题类
具体主题类和代理类都继承自抽象主题类。
2、公共验证的例子
比如用户需要调用具体主题类的功能,但是调用之前需要做一些公共验证,这时候可使用代理模式,用户请求代理类,代理类中加一些公共验证,通过后请求具体主题类。
(1)抽象主题类
public abstract class Subject {
public abstract void request();
}
(2)具体主题类
public class RealSubject extend Subject {
public void request(){
XXX
}
}
(3)代理主题类
public class ProxySubject extend Subject {
private RealSubject realSubject = new RealSubject();
public void request(){
XXX
realSubject.request();
XXX
}
}
(4)客户端使用
main (){
Subject sub = new ProxySubject();
sub.request();
}