1.设计模式六大原则
开闭原则:对扩展开放,对修改关闭;
里氏替换原则:任何父类出现的地方子类都可以出现,父类的可扩展性
依赖倒置原则:依赖接口而不依赖于类
接口隔离原则:一个类能多实现就多实现,降低依赖,降低耦合
最少知道原则:一个实例尽量不要和别的实例产生联系,将实体功能独立
合成复用原则:多使用合成,聚合的方式,少使用继承
2.设计模式分为三类
创建型模式:解耦对象实例化的过程
单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式
结构型模式:把对象或类结合到一起形成一个更大的结构
行为型模式:类和对象如何交互以及责任划分的算法
3.创造型模式
3.1 单例模式
程序从始至终只创建一个实例
3.1.1 饿汉模式
在类初始化时创建对象,不加锁也线程安全执行效率高,但是不顾类是否被调用都会创建对象,浪费内存
public class Person {
// 定义全局变量person,在类初始化时就创建实例对象
private static Person person = new Person();
// 构造方法私有化,不允许其他方法初始化该实例
private Person() {}
// 提供公有的对外调用方法
public static Person getInstance() {
return person;
}
}
测试:对Person对象实例化会报错
获取多次为同一个对象
3.1.2 懒汉模式
调用时实例化,线程不安全,算不上真正的单例模式
public class LazySingleton {
private static LazySingleton lazySingleton;
private LazySingleton(){}
public static LazySingleton getIntance() {
if(lazySingleton == null) {
// 加延时是为了测试线程安全,一般不需要
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
测试
用callable测试线程安全
3.1.3 加同步锁懒汉模式
懒汉模式线程不安全,加上同步锁则线程安全,但其实除了第一次初始化,之后调用其实不需要加锁,这样的模式,影响了执行的速度。
public class LazySyncSingleton {
private static LazySyncSingleton lazySyncSingleton;
private LazySyncSingleton(){}
// 只比懒汉模式多了synchronized同步锁
public static synchronized LazySyncSingleton getIntance() {
if(lazySyncSingleton == null) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lazySyncSingleton = new LazySyncSingleton();
}
return lazySyncSingleton;
}
}
测试线程安全:
3.1.4 双重检验加锁饿汉模式
public class LazyCheckSycnSingleton {
private static LazyCheckSycnSingleton lazyCheckSycnSingleton;
private LazyCheckSycnSingleton(){}
public static LazyCheckSycnSingleton getIntance() {
if(lazyCheckSycnSingleton == null) {
synchronized (LazyCheckSycnSingleton.class) {
if(lazyCheckSycnSingleton == null) {
lazyCheckSycnSingleton = new LazyCheckSycnSingleton();
}
}
}
return lazyCheckSycnSingleton;
}
}
3.1.5静态内部类
public class StaticSingleton {
private static StaticSingleton staticSingleton;
private StaticSingleton(){}
// 静态内部类,调用时才会执行初始化,并且虚拟机会保证多线程时加锁执行,所以是线程安全的
private static class SingletonHonder {
private static final StaticSingleton INSTANCE = new StaticSingleton();
}
public static StaticSingleton getIntance() {
return SingletonHonder.INSTANCE;
}
}
3.2 工厂模式
一个根据不同用户返回不同图表的接口:
public class Chart {
private String type;
public Chart(String type) {
this.type = type;
if("histogram".equalsIgnoreCase(type)) {
// 初始化柱状图
System.out.println("柱状图被初始化啦~");
} else if("pie".equalsIgnoreCase(type)) {
// 初始化饼状图
System.out.println("饼状图被初始化啦~");
} else if("line".equalsIgnoreCase(type)) {
// 初始化折线图
System.out.println("折线图被初始化啦~");
}
}
public void display() {
if("histogram".equalsIgnoreCase(type)) {
System.out.println("柱状图被显示啦~");
} else if("pie".equalsIgnoreCase(type)) {
System.out.println("饼状图被显示啦~");
} else if("line".equalsIgnoreCase(type)) {
System.out.println("折线图被显示啦~");
}
}
}
调试结果:
3.2.1 简单工厂模式
角色:抽象产品,具体产品,工厂
只是把产品抽象出来,而工厂需要通过if else判断来区分实现哪个产品
/**
* 抽象产品
*/
public interface SimpleCharm {
void display();
}
/**
* 具体产品--柱状图
* @Author gpy
* @CreateTime 2022-08-09 14:22
* @Version 1.0
*/
public class HistogramCharm implements SimpleCharm {
public HistogramCharm() {
System.out.println("柱状图被初始化啦~");
}
@Override
public void display() {
System.out.println("柱状图被显示啦~");
}
}
/**
* 具体产品--折线图
* @Author gpy
* @CreateTime 2022-08-09 14:22
* @Version 1.0
*/
public class LineCharm implements SimpleCharm {
public LineCharm() {
System.out.println("折线图被初始化啦~");
}
@Override
public void display() {
System.out.println("折线图被显示啦~");
}
}
/**
*
* 具体产品--饼图
* @Author gpy
* @CreateTime 2022-08-09 14:22
* @Version 1.0
*/
public class PieCharm implements SimpleCharm {
public PieCharm() {
System.out.println("饼状图被初始化啦~");
}
@Override
public void display() {
System.out.println("饼状图被显示啦~");
}
}
/**
*
* 工厂方法
* @Author gpy
* @CreateTime 2022-08-09 14:28
* @Version 1.0
*/
public class SimpleFactory {
public static SimpleCharm getCharm(String type) {
SimpleCharm charm = null;
if("histogram".equalsIgnoreCase(type)) {
charm = new HistogramCharm();
System.out.println("柱状图被生产啦~");
} else if("pie".equalsIgnoreCase(type)) {
charm = new PieCharm();
System.out.println("饼状图被生产啦~");
} else if("line".equalsIgnoreCase(type)) {
charm = new LineCharm();
System.out.println("折线图被生产啦~");
}
return charm;
}
}
调试结果:
3.2.2 工厂方法模式
分为四个角色:抽象产品,具体产品,抽象工厂,具体工厂
主要用于生成复杂对象,一个工厂只生产一个产品,符合开闭原则和单一职责原则,但是每增加一个产品就要增加一个工厂,系统复杂度增加。
/**
* 抽象产品类
* @Author gpy
* @CreateTime 2022-08-09 11:24
* @Version 1.0
*/
public abstract class ProductCharm {
public abstract void display();
}
/**
* 具体产品类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public class ProductH extends ProductCharm {
public ProductH() {
System.out.println("折线图被初始化啦~");
}
@Override
public void display() {
System.out.println("柱状图被显示啦~");
}
}
/**
* 具体产品类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public class ProductLine extends ProductCharm {
public ProductLine() {
System.out.println("折线图被初始化啦~");
}
@Override
public void display() {
System.out.println("折线图被显示啦~");
}
}
/**
* 具体产品类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public class ProductPie extends ProductCharm {
public ProductPie() {
System.out.println("饼图被初始化啦~");
}
@Override
public void display() {
System.out.println("饼图被显示啦~");
}
}
/**
* 抽象工厂类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public abstract class FactoryMethod {
public abstract ProductCharm create();
}
/**
* 具体工厂类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public class FactoryH extends FactoryMethod{
@Override
public ProductCharm create() {
ProductCharm charm = new ProductH();
System.out.println("柱状图被生产啦~");
return charm;
}
}
/**
* 具体工厂类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public class FactoryLine extends FactoryMethod {
@Override
public ProductCharm create() {
ProductCharm charm = new ProductLine();
System.out.println("折线图被生产啦~");
return charm;
}
}
/**
* 具体工厂类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public class FactoryPie extends FactoryMethod {
@Override
public ProductCharm create() {
ProductCharm charm = new ProductPie();
System.out.println("饼图被生产啦~");
return charm;
}
}
调试:
3.2.3 抽象工厂模式
工厂方法模式稍微修改了一下,适用于一个工厂需要生产多种产品的场景
/**
* 另一种产品
* @Author gpy
* @CreateTime 2022-08-09 15:24
* @Version 1.0
*/
public abstract class ProductCharmTable {
public abstract void create();
}
/**
* @Author gpy
* @CreateTime 2022-08-09 15:26
* @Version 1.0
*/
public class ProductCharmTableA extends ProductCharmTable {
@Override
public void create() {
System.out.println("另一种产品创建了~");
}
}
/**
* 抽象工厂类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public abstract class FactoryMethod {
public abstract ProductCharm create();
public abstract ProductCharmTable createTable();
}
/**
* 具体工厂类
* @Author gpy
* @CreateTime 2022-08-09 11:25
* @Version 1.0
*/
public class FactoryPie extends FactoryMethod {
@Override
public ProductCharm create() {
ProductCharm charm = new ProductPie();
System.out.println("饼图被生产啦~");
return charm;
}
@Override
public ProductCharmTable createTable() {
ProductCharmTable charm = new ProductCharmTableA();
System.out.println("另一种产品生产啦~");
return charm;
}
}
调试结果: