设计模式
1,什么是设计模式:(GoF23)
设计模式是前辈们对代码开发经验的总结,是解决一系列问题特定的套路,是一套用来提高代码可复用性,可维护性,可读性,稳健性以及安全性的解决方案。
-
创建型模式(如何创建一个对象,让对象的创建和使用分离)
单例模式,工厂模式,抽象工厂模式,建造模式,原型模式 -
结构型模式(将类和对象按照某种布局组成更大的结构)
适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式 -
行为型模式(描述类和对象之间如何相互协作)
模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式,访问者模式
2,面向对象(oop)七大原则
-
开闭原则:对扩展开放,对修改关闭
-
里氏替换原则:继承必须确保父类所拥有的性质在子类中仍然成立
-
依赖倒置原则:要面向接口编程,不要面向实现编程
-
单一职责原则:控制类的力度大小,将对象解耦,提高其内聚性(一个方法尽量只做一件事)
-
接口隔离原则:要为个各类建立它们需要的专用接口
-
迪米特原则:只与你的直接朋友交谈,不跟“陌生人”说话(Class:A->B->C)
-
合成复用原则:先使用组合或者聚合等观看关系来实现,其次才考虑使用继承关系实现(is a,has a)
3,设计模式
1.单例模式
单例模式,一般用于比较大,复杂的对象,只初始化一次,应该还有一个private的构造函数,使得不能用new来实例化对象,只能调用getInstance方法来得到对象,而getInstance保证了每次调用都返回相同的对象。
- 饿汉式
package com.kuan.single;
//饿汉式单例(一上来就加载)
public class Hungry {
//可能会浪费空间
private Byte[] data1=new Byte[1024*1024*1024];
private Byte[] data2=new Byte[1024*1024*1024];
private Byte[] data3=new Byte[1024*1024*1024];
//构造器单有
private Hungry(){
}
private static final Hungry HUNGRY=new Hungry();
public static Hungry getInstance(){
return HUNGRY;
}
}
- DCL懒汉式
package com.kuan.single;
import java.lang.reflect.Constructor;
//懒汉式单例
public class LazyMan {
private static boolean light=false;
//构造器私有
private LazyMan(){
synchronized (LazyMan.class){
if(light==false){
light=true;
}else {
throw new RuntimeException("不要试图使用反射破坏异常");
}
}
System.out.println(Thread.currentThread().getName());
}
private volatile static LazyMan lazyMan;
//双重检测锁的懒汉式单例+原子性操作,避免指令重排 DCL懒汉式
public static LazyMan getInstance(){
//LazyMan为空再去创建(懒汉式)
if(lazyMan==null){
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan();//不是一个原子性操作
/*
* 1,分配内存空间
* 2,执行构造方法,初始化对象
* 3,把这个对象只指向这个空间
*
* 指令重排
* 123
* 132
* */
}
}
}
return lazyMan;
}
//反射,破坏单例
public static void main(String[] args) throws Exception {
// LazyMan instance=LazyMan.getInstance();
//获得构造器
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
//无视私有构造器,破坏私有权限
declaredConstructor.setAccessible(true);
//通过反射创建对象
LazyMan instance = declaredConstructor.newInstance();
LazyMan instance2 = declaredConstructor.newInstance();
//若instance1和instance2都通过newInstance创建,单例模式又被破坏(红绿灯)
System.out.println(instance);
System.out.println(instance2);
}
}
- 静态内部类
package com.kuan.single;
//静态内部类单例
public class Holder {
private Holder(){
}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass{
private static final Holder HOLDER=new Holder();
}
}
- 以上单例不安全,因为有反射
- 枚举 enum
package com.kuan.single;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
// enum本身也是一个class
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
class Test{
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);
System.out.println(instance2);
}
}
枚举类型的最终反编译源码构造器:有参构造(String.class,int.class)!
2.工厂模式
作用:实现了创建者和调用者分离,满足开闭原则,依赖倒转原则,迪米特法则
核心本质:
1.实例化对象不使用new,用工厂方法代替,
2.将选择实现类,创建对象同意管理和控制,将调用者和实现类解耦
- 简单工厂模式(新增产品,需要扩展已有代码)

创建car接口
package com.kuan.factory.simple;
public interface Car {
void name();
}
创建CarFactory工厂
package com.kuan.factory.methodfactory;
//工厂方法模式
public interface CarFactory {
Car getCar();
}
Car对象
package com.kuan.factory.simple;
public class TesiLa implements Car {
@Override
public void name() {
System.out.println("特斯拉");
}
}
package com.kuan.factory.simple;
public class WuLin implements Car {
@Override
public void name() {
System.out.println("五菱");
}
}
测试
package com.kuan.factory.simple;
public class Consumer {
public static void main(String[] args) {
// TesiLa tesiLa = new TesiLa();
// WuLin wuLin = new WuLin();
//使用工厂创建
Car car = CarFactory.getCar("五菱");
Car car1 = CarFactory.getCar("特斯拉");
car.name();
car1.name();
}
}
- 工厂方法模式

Car接口
package com.kuan.factory.methodfactory;
public interface Car {
void name();
}
CarFactory接口
package com.kuan.factory.methodfactory;
//工厂方法模式
public interface CarFactory {
Car getCar();
}
car对象
package com.kuan.factory.methodfactory;
public class TesiLa implements Car {
@Override
public void name() {
System.out.println("特斯拉");
}
}
car对象的Factory
package com.kuan.factory.methodfactory;
public class TesiLaFactory implements CarFactory {
@Override
public Car getCar() {
return new TesiLa();
}
}
car对象1
package com.kuan.factory.methodfactory;
public class WuLin implements Car {
@Override
public void name() {
System.out.println("五菱");
}
}
car对象Factory
package com.kuan.factory.methodfactory;
public class WuLinFactory implements CarFactory {
@Override
public Car getCar() {
return new WuLin();
}
}
测试
package com.kuan.factory.methodfactory;
public class Consumer {
public static void main(String[] args) {
//从对应的carFactory中拿到相应的car
Car car = new WuLinFactory().getCar();
Car car1 = new TesiLaFactory().getCar();
Car car2 = new DaZhongFactory().getCar();
car.name();
car1.name();
car2.name();
}
}
- 抽象工厂模式(围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂)

创建手机工厂接口
package com.kuan.factory.abstract1;
//手机接口
public interface IPhoneProduct {
void star();
void shutDown();
void sendSms();
void setting();
}
创建路由工厂接口
package com.kuan.factory.abstract1;
//路由接口
public interface IRouterProduct {
void star();
void shutDown();
void openWifi();
void setting();
}
小米手机实现
package com.kuan.factory.abstract1;
//小米手机
public class XiaomiPhone implements IPhoneProduct {
@Override
public void star() {
System.out.println("开启小米手机");
}
@Override
public void shutDown() {
System.out.println("关闭小米手机");
}
@Override
public void sendSms() {
System.out.println("小米发短信");
}
@Override
public void setting() {
System.out.println("小米设置");
}
}
小米路由实现
package com.kuan.factory.abstract1;
//小米路由器
public class XiaomiRouter implements IRouterProduct {
@Override
public void star() {
System.out.println("开启小米路由器");
}
@Override
public void shutDown() {
System.out.println("关闭小米路由器");
}
@Override
public void openWifi() {
System.out.println("开启小米wifi");
}
@Override
public void setting() {
System.out.println("小米wifi设置");
}
}
华为手机实现
package com.kuan.factory.abstract1;
//华为手机
public class HuaweiPhone implements IPhoneProduct {
@Override
public void star() {
System.out.println("开启华为手机");
}
@Override
public void shutDown() {
System.out.println("关闭华为手机");
}
@Override
public void sendSms() {
System.out.println("华为手机发短信");
}
@Override
public void setting() {
System.out.println("华为手机设置");
}
}
华为路由实现
package com.kuan.factory.abstract1;
//华为路由器
public class HuaweiRouter implements IRouterProduct {
@Override
public void star() {
System.out.println("开启华为路由器");
}
@Override
public void shutDown() {
System.out.println("关闭华为路由器");
}
@Override
public void openWifi() {
System.out.println("开启华为wifi");
}
@Override
public void setting() {
System.out.println("华为wifi设置");
}
}
创建抽象产品工厂(超级工厂)
package com.kuan.factory.abstract1;
//抽象产品工厂(超级工厂)
public interface IProductFactory {
//生产手机
IPhoneProduct iPhoneProduct();
//生产路由器
IRouterProduct iRouterProduct();
}
测试
package com.kuan.factory.abstract1;
public class Cilent {
public static void main(String[] args) {
System.out.println("=======小米系列产品========");
//小米工厂
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IPhoneProduct iPhoneProduct = xiaomiFactory.iPhoneProduct();
iPhoneProduct.sendSms();
iPhoneProduct.setting();
IRouterProduct iRouterProduct = xiaomiFactory.iRouterProduct();
iRouterProduct.openWifi();
iRouterProduct.setting();
System.out.println("=======华为系列产品========");
//华为工厂
HuaweiFactory huaweiFactory = new HuaweiFactory();
IPhoneProduct iPhoneProduct1 = huaweiFactory.iPhoneProduct();
iPhoneProduct1.sendSms();
iPhoneProduct1.setting();
IRouterProduct iRouterProduct1 = huaweiFactory.iRouterProduct();
iRouterProduct1.openWifi();
iRouterProduct1.setting();
}
}
3.建造者模式
- 常规的Builder模式,导演类Director在Builder模式中有重要作用,用于指导具体的构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,某些情况下需要简化系统结构,将Director和抽象建造者进行结合

创建抽象建造者
package com.kuan.factory.builder;
//抽象的建造者
public abstract class Builder {
abstract void buildA();//地基
abstract void buildB();//钢筋水泥
abstract void buildC();//铺电线
abstract void buildD();//粉刷
//完工:得到产品
abstract Product getProduct();
}
创建产品
package com.kuan.factory.builder;
//产品:房子
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
创建具体的建造者
package com.kuan.factory.builder;
//具体的建造者
public class Worker extends Builder {
private Product product;
public Worker() {
product = new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基");
}
@Override
void buildB() {
product.setBuildA("钢筋水泥");
System.out.println("钢筋水泥");
}
@Override
void buildC() {
product.setBuildA("铺电线");
System.out.println("铺电线");
}
@Override
void buildD() {
product.setBuildA("粉刷");
System.out.println("粉刷");
}
@Override
Product getProduct() {
return product;
}
}
创建Director指挥类,指导工人构建一个工程并返回一个完整的工程
package com.kuan.factory.builder;
//指挥:核心,负责指挥构建一个工程,工程如何构建,由他决定
public class Director {
//指挥工人按照一定顺序建造
public Product build(Builder builder){
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
测试
package com.kuan.factory.builder;
public class Test {
public static void main(String[] args) {
Director director = new Director();
Product product = director.build(new Worker());
product.toString();
}
}
- 通过静态内部类实现零件的无需装配构造,这种方式更加灵活,更符合定义,
4.原型模式
Clone()
- 实现一个接口 Cloneable
- 重写一个方法 clone()
浅克隆,深克隆,详见上一篇java基础。
结构型模式:
5.适配器模式(usb网线转换接口)
角色分析:
1.目标接口(Usb):客户所期待的接口,目标可以是具体的或抽象的类,也可以是接口
2.需要适配的类(网线):需要适配的类或适配者类
3.适配器(usb转换器):通过包装一个需要适配的对象,把原接口转换成目标接口
浙公网安备 33010602011771号