JAVA六大设计原则
JAVA设计模式提供六个基本原则,分别是:
开闭原则(OCP) - The Open-Closed Principle
单一职责原则(SRP) - Single Responsibility Principle
里氏替换原则(LSP) - Liskov Substitution Principle
依赖倒置原则(DIP) - Dependency Inversion Principle
接口隔离原则(ISP) - Interface Segregation Principle
迪米特法则(DP) - Demeter Principle
JAVA23种设计模式
在软件工程当中,设计原则和设计模式是不同的.
# 设计原则
设计原则是为了更好的设计软件的高层指导方针.
它不提供具体的实现方式也不会绑定任何一种编程语言.
最常用的原则是SOLID(SRP, OCP, LSP, ISP, DIP)原则
设计模式
设计模式对关于面向对象问题的具体解决方案.
比如说, 如果你想创建一个类而且它在任何时刻只会有一个对象,那么你就应该使用单例类模式.
设计模式是经过大量检测的安全的做法.
单例设计模式
懒汉式:
java
package com.apesource.lazytest;
public class Test02 {
public static void main(String[] args) {
Student stu1=Student.getInstance();
Student stu2=Student.getInstance();
System.out.println(stu1==stu2);
}
}
java
package com.apesource.lazytest;
public class Student {
//3。创建static修饰的成员变量
private static Student stu;
//1。设计私有构造方法
private Student(){
super();
}
//2.提供共有的方法
public static synchronized Student getInstance(){
if(stu==null){
stu=new Student();
}
return stu;
}
}
饿汉式:
java
package com.apesource.hungrytest;
/**
* 饿汉式
*/
public class Student {
//创建static修饰的成员变量
private static Student stu=new Student();
//1.设计私有构造方法
private Student(){
super();
}
//2.提供共有方法
public static synchronized Student getInstance(){
return stu;
}
}
java
package com.apesource.hungrytest;
import com.apesource.lazytest.Student;
public class Test03 {
public static void main(String[] args) {
com.apesource.lazytest.Student stu1=com.apesource.lazytest.Student.getInstance();
com.apesource.lazytest.Student stu2= Student.getInstance();
System.out.println(stu1==stu2);
}
}
代理模式
静态代理:
java
package com.apesource.statictest;
public interface ISinger {
public void sing();
}
java
package com.apesource.statictest;
public class luhanImp implements ISinger{
@Override
public void sing() {
System.out.println("我们的明天");
}
}
java
package com.apesource.statictest;
public class DailirenImp implements ISinger{
//注入一个代理对象
ISinger singer;
public void setSinger(ISinger singer) {
this.singer = singer;
}
@Override
public void sing() {
System.out.println("===跳舞==");
singer.sing();
}
}
java
package com.apesource.statictest;
public class Test01 {
public static void main(String[] args) {
//1.创建鹿晗(被代理)
luhanImp luhanImp=new luhanImp();
//2.创建经纪人(代理)
DailirenImp dailirenImp=new DailirenImp();
dailirenImp.setSinger(luhanImp);
//3.调用经纪人的唱歌
dailirenImp.sing();
}
}
动态代理(proxy):
-
动态生成代理对象 :
客户端通过
Proxy.newProxyInstance()
请求生成代理对象时,JVM 会在内存中动态创建一个类(代理类),该类实现了目标对象的所有接口(如IStar
),并生成对应的方法(sing())。 -
方法调用转发 :
当客户端调用代理对象的任何方法(如
proxyStar.sing()
),动态生成的代理类会将调用转发 给InvocationHandler
的invoke()
方法,并传入三个参数:- 代理对象本身(
proxy
); - 当前调用的方法(
method
,如sing()
对应的 Method 对象); - 方法参数(
args
)。
- 代理对象本身(
-
增强逻辑执行 :
在
invoke()
方法中,我们可以自由定义增强逻辑:- 先执行前置操作(如经纪人的准备工作);
- 通过
method.invoke(target, args)
调用目标对象的实际方法(核心业务); - 再执行后置操作(如经纪人的收尾工作)。
-
返回结果 :
目标方法的返回值通过
invoke()
方法返回给客户端,整个过程对客户端透明。
java
package com.apesource.proxy;
public interface ISinger {
public void sing();
}
java
package com.apesource.proxy;
public class CaiYiImp implements ISinger{
@Override
public void sing() {
System.out.println("===日不落===");
}
}
java
package com.apesource.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test01 {
public static void main(String[] args) {
//1.创建被代理对象
final ISinger cai=new CaiYiImp();
//2.创建代理对象
// cai.getClass().getInterfaces(), // 被代理对象实现的接口
// new InvocationHandler() // 调用处理器
ISinger proxy=(ISinger) Proxy.newProxyInstance(cai.getClass().getClassLoader(),// 类加载器
cai.getClass().getInterfaces(), new InvocationHandler() {
// :实现调用处理器逻辑
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object object=null;
try {
//执行被代理对象内的方法
object=method.invoke(cai,args);
return object;
} catch (Exception e) {
return object;
}
}
});
// 这里通过代理对象 proxy 调用 sing() 方法,实际会触发调用处理器的 invoke 方法,最终执行被代理对象 cai 的 sing() 方法。
proxy.sing();
}
}
动态代理(cglib)
java
package com.apesource.cglibtest;
public interface ISinger {
public void sing();
}
java
package com.apesource.cglibtest;
public class TengGeErImp implements ISinger{
@Override
public void sing() {
System.out.println("听了赵雷的成都去了成都,听了王峰的北京去了北京,至今不敢听腾格尔的天堂~");
}
}
java
package com.apesource.cglibtest;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test02 {
public static void main(String[] args) {
//1。创建被代理对象
final ISinger teng = new TengGeErImp();
//2.代理对象
ISinger proxy = (ISinger) Enhancer.create(teng.getClass(), new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
Object obj;
try {
obj = method.invoke(teng, objects);
return obj;
} catch (IllegalAccessException e) {
return null;
}
}
});
proxy.sing();
}
}
动态代理 vs 静态代理(核心区别)
对比维度 | 静态代理 | 动态代理(JDK) |
---|---|---|
代理类创建方式 | 手动编写,编译期确定 | JVM 运行时动态生成,无需手动编写 |
灵活性 | 代理类与接口绑定(如 Agent 只能代理 IStar) | 可代理任意接口的对象,一个处理器可通用 |
接口方法变更 | 需修改代理类(如新增 greet () 需同步实现) | 无需修改,自动适配接口所有方法 |
适用场景 | 接口固定、方法少的简单场景 | 接口多变、需要通用代理逻辑的场景(如 Spri |
工厂模式
java
package com.apesource.test;
public interface INoodles {
public void noodleType();
}
java
package com.apesource.test;
public class LanZhouLaMian implements INoodles{
@Override
public void noodleType() {
System.out.println("========来一碗兰州拉面=====");
}
}
java
package com.apesource.test;
public class ReGanMianNoodleImp implements INoodles{
@Override
public void noodleType() {
System.out.println("======来一碗热干面==========");
}
}
java
package com.apesource.test;
public class YouPoMianNoodleImp implements INoodles{
@Override
public void noodleType() {
System.out.println("========来一碗油泼面========");
}
}
java
package com.apesource.test;
/**
* 面长
*/
public class NoodleFactory {
/**
* 规范下面条类型
*/
public static final int NOODLE_YOUPO=1;
public static final int NOODLE_REGAN=2;
public static final int NOODLE_LANZHOULA=3;
/**
* 创建面条
*
*/
public static INoodles getNoodle(int type){
if(type==1){
return new YouPoMianNoodleImp();
}else if(type==2){
return new ReGanMianNoodleImp();
}else if(type==3){
return new LanZhouLaMian();
}
return null;
}
}
java
package com.apesource.test;
public class Test01 {
public static void main(String[] args) {
NoodleFactory.getNoodle(NoodleFactory.NOODLE_LANZHOULA).noodleType();;
NoodleFactory.getNoodle(3).noodleType();
}
}
模板模式:
所谓模板板式,就是在父类中定义算法的主要流程,而把一些个性化的步骤延迟到子类中去实现,父类始终控制着整个流程的主动权,子类只是辅助父类实现某些可定制的步骤
java
public abstract class FatherClass {
public final void time(){
study();
work();
aiqing();
}
public abstract void aiqing();
public void work() {
System.out.println("努力工作");
}
public void study() {
System.out.println("好好学习 天天向上");
}
}
java
public class SonClass extends FatherClass{
@Override
public void aiqing() {
System.out.println("真诚是唯一的必杀技");
}
@Override
public void study() {
System.out.println("学到很晚才回家睡觉");
}
@Override
public void work() {
System.out.println("以后会努力的工作");
}
}
java
public class Test {
public static void main(String[] args) {
FatherClass fatherClass=new SonClass();
fatherClass.time();
}
}