一、设计模式
1.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
2.JAVA23种设计模式
在软件工程当中,设计原则和设计模式是不同的.
3.设计原则
设计原则是为了更好的设计软件的高层指导方针.
它不提供具体的实现方式也不会绑定任何一种编程语言.
最常用的原则是SOLID(SRP, OCP, LSP, ISP, DIP)原则
4.设计模式
设计模式对关于面向对象问题的具体解决方案.
比如说, 如果你想创建一个类而且它在任何时刻只会有一个对象,那么你就应该使用单例类模式.
设计模式是经过大量检测的安全的做法.
4.1 工厂模式(factory)
案例:
INoodles:
package com.ztt.test;
public interface INoodles {
public void noodleType();
}
LanZhouLaMianImp:
package com.ztt.test;
public class LanZhouLaMianImp implements INoodles{
@Override
public void noodleType() {
System.out.println("========来一碗兰州拉面========");
}
}
ReGanMianNoodleImp:
package com.ztt.test;
public class ReGanMianNoodleImp implements INoodles{
@Override
public void noodleType() {
System.out.println("========来一碗武汉热干面========");
}
}
YouPoMianNoodleImp:
package com.ztt.test;
public class YouPoMianNoodleImp implements INoodles{
@Override
public void noodleType() {
System.out.println("========来一碗油泼面========");
}
}
NoodleFactory:
package com.ztt.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 LanZhouLaMianImp();
}
return null;
}
}
package com.ztt.test;
public class Test01 {
public static void main(String[] args) {
NoodleFactory.getNoodle(NoodleFactory.NOODLE_LANZHOULA).noodleType();
NoodleFactory.getNoodle(3).noodleType();
}
}
4.2 单列设计模式(singlton)
饿汉式:
package com.ztt.hungrytest;
/**
* 饿汉式
* */
public class Student {
//3.创建static修饰的成员变量
private static Student stu = new Student();
//1.设计私有构造方法
private Student(){
super();
}
//2.提供共有的方法
public static synchronized Student getInstance(){
return stu;
}
}
package com.ztt.hungrytest;
import com.ztt.lazytest.Student;
public class Test03 {
public static void main(String[] args) {
com.ztt.lazytest.Student stu1 = com.ztt.lazytest.Student.getInstance();
Student stu2 = Student.getInstance();
System.out.println(stu1== stu2);
}
}
懒汉式:
package com.ztt.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;
}
}
package com.ztt.lazytest;
public class Test02 {
public static void main(String[] args) {
Student stu1 = Student.getInstance();
Student stu2 = Student.getInstance();
System.out.println(stu1== stu2);
}
}
六、代理模式
1.什么是代理模式?
- 代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
- 通俗的来讲代理模式就是我们生活中常见的中介。
- 举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源,
- 做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。
- 我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介
- 公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择
- 自己喜欢的车,然后付钱就可以了。
2.为什么要用代理模式?
2.1 中介隔离作用:
在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
2.2 开闭原则,增加功能:
代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。
3.有哪几种代理模式?
我们有多种不同的方式来实现代理。如果按照代理创建的时期来进行分类的话可以分为两种:
3.1 静态代理:
静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。
在程序员运行之前,代理类.class文件就已经被创建了。
静态代理案例:
package com.ztt.statictest;
public interface IWonman {
public void makeEyeWithMan();
}
package com.ztt.statictest;
public class PanJinLianImp implements IWonman{
@Override
public void makeEyeWithMan() {
System.out.println("回眸一笑,抛个媚眼~");
}
}
package com.ztt.statictest;
//代理
public class WangPoImp implements IWonman{
//被代理对象
IWonman obj;
public WangPoImp(IWonman obj) {
this.obj = obj;
}
@Override
public void makeEyeWithMan() {
System.out.println("镇一壶酒,搞搞气氛~");
obj.makeEyeWithMan();
}
}
package com.ztt.statictest;
public class XiMenQingTest {
public static void main(String[] args) {
//1.创建被代理对象
IWonman pan = new PanJinLianImp();
//2.创建代理
IWonman wang = new WangPoImp(pan);
wang.makeEyeWithMan();
}
}
3.2 动态代理:
动态代理是在程序运行时通过反射机制动态创建的。
动态代理分为:
基于接口的动态代理(jdk自带)
基于子类的动态代理(第三方)
3.2.1 动态代理jdk自带的案例:
package com.ztt.jdktest;
/**
* @author 甜甜
* @version 1.0
* @since 2024/8/8
*/
public interface ISinger {
public void sing();
public int dance(int num);
}
package com.ztt.jdktest;
/**
* @author 甜甜
* @version 1.0
* @since 2024/8/8
*/
public class XuezhiqianImp implements ISinger{
@Override
public void sing() {
System.out.println("唱歌");
}
@Override
public int dance(int num) {
System.out.println("跳舞");
return 0;
}
}
package com.ztt.jdktest;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author 甜甜
* @version 1.0
* @since 2024/8/8
*/
public class Test01 {
public static void main(String[] args) {
//1.创建被代理对象
final ISinger xue = new XuezhiqianImp();
//2.创建代理对象
ISinger jingJiRen = (ISinger) Proxy.newProxyInstance(xue.getClass().getClassLoader(), xue.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("===做个自我介绍===");
Object obj = method.invoke(xue,args);
return obj;
}
});
jingJiRen.sing();
//jingJiRen.dance(6);
}
}
3.2.2 动态代理第三方案例:
① 导入坐标
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
② 代码展示:
package com.ztt.cglibtest;
/**
* @author 甜甜
* @version 1.0
* @since 2024/8/8
*/
public interface ISinger {
public void sing();
}
package com.ztt.cglibtest;
/**
* @author 甜甜
* @version 1.0
* @since 2024/8/8
*/
public class TengGeErImp implements ISinger{
@Override
public void sing() {
System.out.println("听了赵雷的成都去了成都,听了汪峰的北京去了北京,至今不敢听腾格尔的天堂~");
}
}
package com.ztt.cglibtest;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author 甜甜
* @version 1.0
* @since 2024/8/8
*/
public class Test02 {
public static void main(String[] args) {
//创建被代理对象
final ISinger teng = new TengGeErImp();
//创建代理对象
ISinger jing=(ISinger) Enhancer.create(teng.getClass(), teng.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
Object object = method.invoke(teng,objects);
return object;
}
});
jing.sing();
}
}