主頁 > 軟體設計 > SSH框架之Spring第三篇

SSH框架之Spring第三篇

2020-09-10 18:34:25 軟體設計

1.1 AOP概述        1.1.1 什么是AOP?            AOP : 全稱是Aspect Oriented Progamming既 : 面向切面編程.通過預編譯方式和運行期動態代理實作程式功能的統一維護的一種技術.            簡單的說它就是把我們程式重復的代碼抽取出來,在需要執行的時候,使用動態代理的技術,在不修改原始碼的基礎上,對我們的已有方法進行增強.        1.1.2 AOP的作用及優勢            作用 :                 在程式運行期間,不修改原始碼對已有方法進行增強.            優勢 :                減少重復代碼,提高開發效率,維護方便.        1.1.3 AOP的實作方式 : 使用動態代理技術        1.2.2.1 動態代理的特點 :            位元組碼隨用隨創建,隨用隨加載.            它與靜態代理的區別也在于此.因為靜態代理是位元組碼一上來就創建好,并完成加載.            裝飾著模式就是靜態代理的一種體現.        1.2.2.2 動態代理常用的有兩種方式                基于介面的動態代理                提供者 : JDK官方的Proxy類.                要求   : 被代理來最少實作一個介面.            基于子類的動態代理                提供者 : 第三方的CGLib,如果報asmxxxx例外,需要匯入asm.jar.                要求   : 被代理類不能用final修飾的類(最終類).    1.3 Spring中的AOP        1.3.1 關于代理的選擇            在Spring中,框架根據目標類實作了介面決定采用哪種動態代理的方式.        1.3.2 AOP相關術語            Joinpoint(連接點) : 所謂連接點是指那些被攔截到的點.在Spring中,這些點值得是方法,因為spring只支持方法型別的連接點.            Pointcut(切入點) : 所謂切入點是指我們要對那些Joinpoint進行攔截的定義.            Advice(通知/增強) : 所謂通知是指攔截到Joinpoint之后所要做的事情就是通知.                通知的型別 : 前置通知,后置通知,例外通知,最終通知,環繞通知.            Introduction(引介) : 是一種特殊的通知在不修改類代碼的前提下,Introduction可以在運行期為類動態地添加一些方法或Field.            Target(目的物件) :                 代理的目標物件.            Weaving(織入) :                 是值把增強應用到目標物件來創建新的代理物件的程序.                spring采用動態代理織入,而AspectJ采用編譯器織入和類轉載期織入.            Proxy (代理) :                 一個類被AOP織入增強后,就是產生一個結果代理類.            Aspect(切面) :                 是切入點和通知(引介) 的結合.    1.4 基于XML的AOP配置        1.4.1 匯入包        1.4.2 準備介面        1.4.3 創建組態檔匯入約束            <?xml version="1.0" encoding="UTF-8"?>            <beans xmlns="http://www.springframework.org/schema/beans"                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                   xmlns:aop="http://www.springframework.org/schema/aop"                   xsi:schemaLocation="http://www.springframework.org/schema/beans                                http://www.springframework.org/schema/beans/spring-beans.xsd                               http://www.springframework.org/schema/aop                                http://www.springframework.org/schema/aop/spring-aop.xsd">            </beans>                2.1.4第四步:把客戶的業務層配置到spring容器中            <!-- 把資源交給spring來管理 -->            <bean id="customerService" class="com.baidu.service.impl.CustomerServiceImpl"/>        2.1.5第五步:制作通知(增強的類)            /**             * 一個記錄日志的工具類            */            public class Logger {                /**                 * 期望:此方法在業務核心方法執行之前,就記錄日志                 */                public void beforePrintLog(){                    System.out.println("Logger類中的printLog方法開始記錄日志了,,,,");                }            }        2.2配置步驟            2.2.1第一步:把通知類用bean標簽配置起來            <!-- 把有公共代碼的類也讓spring來管理(把通知類也交給spring來管理) -->            <bean id="logger" class="com.baidu.util.Logger"></bean>            2.2.2第二步:使用aop:config宣告aop配置            <!-- aop的配置 -->            <aop:config>                <!-- 配置的代碼都寫在此處 -->                </aop:config>            2.2.3第三步:使用aop:aspect配置切面            <!-- 配置切面 :此標簽要出現在aop:config內部                id:給切面提供一個唯一標識                ref:參考的是通知類的bean的id            -->            <aop:aspect id="logAdvice" ref="logger">                    <!--配置通知的型別要寫在此處-->            </aop:aspect>            2.2.4第四步:使用aop:before配置前置通知            <!-- 用于配置前置通知:指定增強的方法在切入點方法之前執行                     method:用于指定通知類中的增強方法名稱                    ponitcut-ref:用于指定切入點的運算式的參考                -->            <aop:before method="beforePrintLog" pointcut-ref="pt1"/>            2.2.5第五步:使用aop:pointcut配置切入點運算式            <aop:pointcut expression="execution(public void com.baidu.service.impl.CustomerServiceImpl.saveCustomer())"             id="pt1"/>            2.3切入點運算式說明            execution:                    匹配方法的執行(常用)                            execution(運算式)            運算式語法:execution([修飾符] 回傳值型別 包名.類名.方法名(引數))            寫法說明:                全匹配方式:                    public void com.baidu.service.impl.CustomerServiceImpl.saveCustomer()                訪問修飾符可以省略                        void com.baidu.service.impl.CustomerServiceImpl.saveCustomer()                回傳值可以使用*號,表示任意回傳值                    * com.baidu.service.impl.CustomerServiceImpl.saveCustomer()                包名可以使用*號,表示任意包,但是有幾級包,需要寫幾個*                    * *.*.*.*.CustomerServiceImpl.saveCustomer()                使用..來表示當前包,及其子包                    * com..CustomerServiceImpl.saveCustomer()                類名可以使用*號,表示任意類                    * com..*.saveCustomer()                方法名可以使用*號,表示任意方法                    * com..*.*()                引數串列可以使用*,表示引數可以是任意資料型別,但是必須有引數                    * com..*.*(*)                引數串列可以使用..表示有無引數均可,有引數可以是任意型別                    * com..*.*(..)                全通配方式:                    * *..*.*(..)            2.4常用標簽            2.4.1<aop:config>            作用:                用于宣告開始aop的配置            2.4.2<aop:aspect>            作用:                用于配置切面,            屬性:                id:給切面提供一個唯一標識,                ref:參考配置好的通知類bean的id,            2.4.3<aop:pointcut>            作用:                用于配置切入點運算式            屬性:                expression:用于定義切入點運算式,                id:用于給切入點運算式提供一個唯一標識,            2.4.4<aop:before>            作用:                用于配置前置通知            屬性:                method:指定通知中方法的名稱,                pointct:定義切入點運算式                pointcut-ref:指定切入點運算式的參考            2.4.5<aop:after-returning>            作用:                用于配置后置通知            屬性:                method:指定通知中方法的名稱,                pointct:定義切入點運算式                pointcut-ref:指定切入點運算式的參考            2.4.6<aop:after-throwing>            作用:                用于配置例外通知            屬性:                method:指定通知中方法的名稱,                pointct:定義切入點運算式                pointcut-ref:指定切入點運算式的參考            2.4.7<aop:after>            作用:                用于配置最終通知            屬性:                method:指定通知中方法的名稱,                pointct:定義切入點運算式                pointcut-ref:指定切入點運算式的參考            2.4.8<aop:around>            作用:                用于配置環繞通知            屬性:                method:指定通知中方法的名稱,                pointct:定義切入點運算式                pointcut-ref:指定切入點運算式的參考            2.5通知的型別            2.5.1型別說明            <!-- 配置通知的型別                aop:before:                    用于配置前置通知,前置通知的執行時間點:切入點方法執行之前執行                aop:after-returning:                    用于配置后置通知,后置通知的執行時間點:切入點方法正常執行之后,它和例外通知只能有一個執行                aop:after-throwing                    用于配置例外通知,例外通知的執行時間點:切入點方法執行產生例外后執行,它和后置通知只能執行一個,                aop:after                    用于配置最終通知,最終通知的執行時間點:無論切入點方法執行時是否有例外,它都會在其后面執行,                aop:around                    用于配置環繞通知,他和前面四個不一樣,他不是用于指定通知方法何時執行的,            -->                        <aop:before method="beforePrintLog" pointcut-ref="pt1"/>            <aop:after-returning method="afterReturningPrintLog"  pointcut-ref="pt1"/>            <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"/>            <aop:after method="afterPrintLog" pointcut-ref="pt1"/>            <aop:around method="aroundPringLog" pointcut-ref="pt1"/>            2.5.2環繞通知的特殊說明            /**                 * 環繞通知                 *     它是spring框架為我們提供的一種可以在代碼中手動控制增強部分什么時候執行的方式,                 * 問題:                 *     當我們配置了環繞通知之后,增強的代碼執行了,業務核心方法沒有執行,                 * 分析:                 *     通過動態代理我們知道在invoke方法中,有明確呼叫業務核心方法:method.invoke(),                 *     我們配置的環繞通知中,沒有明確呼叫業務核心方法,                 * 解決:                 *     spring框架為我們提供了一個介面:ProceedingJoinPoint,它可以作為環繞通知的方法引數                 *     在環繞通知執行時,spring框架會為我們提供該介面的實作類物件,我們直接使用就行,                 *     該介面中有一個方法proceed(),此方法就相當于method.invoke()                 */                public void aroundPringLog(ProceedingJoinPoint pjp){                    try {                        System.out.println("前置通知:Logger類的aroundPringLog方法記錄日志");                        pjp.proceed();                        System.out.println("后置通知:Logger類的aroundPringLog方法記錄日志");                    } catch (Throwable e) {                        System.out.println("例外通知:Logger類的aroundPringLog方法記錄日志");                        e.printStackTrace();                    }finally{                        System.out.println("最終通知:Logger類的aroundPringLog方法記錄日志");                    }                }        3.1 基于注解的AOP配置            3.1.1 環境搭建 準備業務層和介面并用注解配置            3.1.2 匯入jar包            3.1.3 創建spring的組態檔并匯入約束            3.1.4 第四步:把資源使用注解讓spring來管理            3.1.5 第五步 : 在組態檔中指定spring要掃描的包                <-- 告知spring,在創建容器時要掃描的包-->                <context:component-scan base-package="com.baidu"></context:component-scan>                        3.2 配置步驟            3.2.1第一步:把通知類也使用注解配置            /**             * 一個記錄日志的工具類             */            @Component("logger")            public class Logger {                /**                 * 期望:此方法在業務核心方法執行之前,就記錄日志                 * 前置通知                 */                public void beforePrintLog(){                    System.out.println("前置通知:Logger類中的printLog方法開始記錄日志了");                }            }            3.2.2第二步:在通知類上使用@Aspect注解宣告為切面            /**             * 一個記錄日志的工具類             */            @Component("logger")            @Aspect//表明當前類是一個切面類            public class Logger {                /**                 * 期望:此方法在業務核心方法執行之前,就記錄日志                 * 前置通知                 */                public void beforePrintLog(){                    System.out.println("前置通知:Logger類中的printLog方法開始記錄日志了");                }            }            3.2.3第三步:在增強的方法上使用@Before注解配置前置通知                /**                 * 期望:此方法在業務核心方法執行之前,就記錄日志                 * 前置通知                 */                @Before("execution(* com.baidu.service.impl.*.*(..))")//表示前置通知                public void beforePrintLog(){                    System.out.println("前置通知:Logger類中的printLog方法開始記錄日志了");                }            3.2.4第四步:在spring組態檔中開啟spring對注解AOP的支持            <!-- 開啟spring對注解AOP的支持 -->            <aop:aspectj-autoproxy/>            3.3常用注解            3.3.1@Aspect:            作用:                把當前類宣告為切面類,            3.3.2@Before:            作用:                把當前方法看成是前置通知,            屬性:                value:用于指定切入點運算式,還可以指定切入點運算式的參考,            3.3.3@AfterReturning            作用:                把當前方法看成是后置通知,            屬性:                value:用于指定切入點運算式,還可以指定切入點運算式的參考,            3.3.4@AfterThrowing            作用:                把當前方法看成是例外通知,            屬性:                value:用于指定切入點運算式,還可以指定切入點運算式的參考,            3.3.5@After            作用:                把當前方法看成是最終通知,            屬性:                value:用于指定切入點運算式,還可以指定切入點運算式的參考,            3.3.6@Around            作用:                把當前方法看成是環繞通知,            屬性:                value:用于指定切入點運算式,還可以指定切入點運算式的參考,            3.3.7@Pointcut            作用:                指定切入點運算式            屬性:                value:指定運算式的內容            3.4不使用XML的配置方式            @Configuration            @ComponentScan(basePackages="com.baidu")            @EnableAspectJAutoProxy            public class SpringConfiguration {            }    總結 :        方法稱為連接點.        切入點 : 具體對那個方法做增強.切入點的運算式.        Advice(通知/增強) : 對save方法做增強,撰寫程式增強要做的事情.        通知型別 : 前置通知,后置通知,最終通知,例外通知和環繞通知.        Target(目標物件) : UserServiceImpl物件        Proxy (代理) : 生成的代理物件        Aspect(切面) : 抽象的概念            切面 = 切入點 + 通知.        Weaving(織入) : 是指把增強應用到目標物件來創建新的代理物件的程序.    AOP組態檔開發步驟 :        1 : 匯入jar包        2 : 撰寫切面類,撰寫通知的方法(自己來撰寫的)        3 : 配置切面類,進行IOC的管理        4 : 撰寫AOP的增強.    <aop:config>        <!--配置切面 = 切入點(運算式) + 通知 -->        <aop:aspect ref="myXmlAspect">            <!--選擇通知的型別,前置通知-->            <aop:before method="log" pointcut="execution(public void com.baidu.demo1.UserServiceImpl.save())"/>        </aop:aspect>    </aop:config>    <!-- 開啟注解掃描 -->    <context:component-scan base-package="com.baidu.demo1"/>        <!-- 開啟注解AOP -->    <aop:aspectj-autoproxy/>        package com.baidu.demo1;        import org.aspectj.lang.ProceedingJoinPoint;        import org.aspectj.lang.annotation.After;        import org.aspectj.lang.annotation.AfterReturning;        import org.aspectj.lang.annotation.AfterThrowing;        import org.aspectj.lang.annotation.Around;        import org.aspectj.lang.annotation.Aspect;        import org.aspectj.lang.annotation.Before;        import org.aspectj.lang.annotation.Pointcut;        import org.springframework.stereotype.Component;        /**         * 注解方式的切面類         * 宣告當前類是切面類         * @author Administrator         */        @Component("myAnnoAspect")        @Aspect        // 宣告當前類是切面類 = 切入點運算式 + 通知型別        public class MyAnnoAspect {                        /**             * 通知方法             * 配置通知型別,注解的屬性撰寫的是切入點的運算式             * 通知型別全部采用注解方式             *         @Before                    前置通知             *         @AfterReturning            后置通知,目標物件方法執行成功             *         @AfterThrowing            例外通知             *         @After                    最終通知             */            // @Before(value="https://www.cnblogs.com/haizai/p/execution(public * com.baidu.demo1.*.save(..))")            // @AfterReturning(value="https://www.cnblogs.com/haizai/p/execution(public * com.baidu.demo1.*.save(..))")            // @AfterThrowing(value="https://www.cnblogs.com/haizai/p/execution(public * com.baidu.demo1.*.save(..))")            // @After(value="https://www.cnblogs.com/haizai/p/execution(public * com.baidu.demo1.*.save(..))")            public void log(){                System.out.println("記錄日志...");            }                        /**             * 環繞通知             */            // @Around(value="https://www.cnblogs.com/haizai/p/execution(public * com.baidu.demo1.*.save(..))")            @Around(value="https://www.cnblogs.com/haizai/p/MyAnnoAspect.fn()")            public void arond(ProceedingJoinPoint pp){                try {                    System.out.println("記錄日志...");                    // 讓目標物件方法執行                    pp.proceed();                    System.out.println("記錄日志...");                } catch (Throwable e) {                    e.printStackTrace();                }            }                        /**             * 定義切入點的運算式             */            @Pointcut(value="execution(public * com.baidu.demo1.*.save(..))")            public void fn(){}                    }        基于子類的動態代理:        package com.baidu.demo2;        import java.lang.reflect.Method;        import org.springframework.cglib.proxy.Enhancer;        import org.springframework.cglib.proxy.MethodInterceptor;        import org.springframework.cglib.proxy.MethodProxy;        /**         * 使用cglib方式生成代理物件         * 不用實作介面         * @author Administrator         */        public class MyCglibProxy {                        /**             * 獲取到代理物件             * @return             */            public static RoleServiceImpl getProxy(final RoleServiceImpl role){                Enhancer e = new Enhancer();                // 設定父類                e.setSuperclass(role.getClass());                // 設定回呼函式                e.setCallback(new MethodInterceptor() {                                        // 呼叫代理物件的方法,那么intercept方法就會執行                    public Object intercept(Object arg0, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {                        // 讓目標物件方法執行                        Object invoke = methodProxy.invoke(role, args);                        // 增強                        System.out.println("記錄日志...");                        return invoke;                    }                });                // 創建代理物件                Object proxy = e.create();                // 把代理物件回傳                return (RoleServiceImpl) proxy;            }        }    <?xml version="1.0" encoding="UTF-8"?>        <beans xmlns="http://www.springframework.org/schema/beans"            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"            xmlns:context="http://www.springframework.org/schema/context"            xmlns:aop="http://www.springframework.org/schema/aop"            xmlns:tx="http://www.springframework.org/schema/tx"            xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans.xsd            http://www.springframework.org/schema/context            http://www.springframework.org/schema/context/spring-context.xsd            http://www.springframework.org/schema/aop            http://www.springframework.org/schema/aop/spring-aop.xsd            http://www.springframework.org/schema/tx             http://www.springframework.org/schema/tx/spring-tx.xsd">                        <!-- 管理service -->            <bean id="userService" class="com.baidu.demo1.UserServiceImpl"/>                        <!-- 先配置切面類 -->            <bean id="myXmlAspect" class="com.baidu.demo1.MyXmlAspect"/>                        <!-- 配置AOP的增強             <aop:config>            -->                <!-- 配置切面 = 切入點 (運算式)+ 通知                 <aop:aspect ref="myXmlAspect">                -->                    <!-- 選擇通知的型別,前置通知                     <aop:before method="log" pointcut="execution(public void com.baidu.demo1.UserServiceImpl.save())"/>                </aop:aspect>            </aop:config>            -->                        <!-- 配置AOP的增強 -->            <aop:config>                <!-- 撰寫切入點的運算式 -->                <aop:pointcut expression="execution(public void com.baidu.demo1.UserServiceImpl.save())" id="pt"/>                <aop:aspect ref="myXmlAspect">                    <aop:before method="log" pointcut-ref="pt"/>                </aop:aspect>            </aop:config>                            <!--                  切入點的運算式:                    execution()            固定寫法                    public                可以省略不寫                    void                方法的回傳值,可以寫 * 號                    包結構                也可以 * 號,不能省略不寫                    UserServiceImpl        類,可以撰寫 * 號,常見的撰寫的寫法:*ServiceImpl                    方法                    可以撰寫*號  save*  saveUser  saveDept                    引數串列                撰寫..    指的可變引數                                需求:對專案中的service的save方法進行增強                    execution(public * com.baidu.*.*ServiceImpl.3save*(..))            -->            <aop:config>                <!-- <aop:pointcut expression="execution(public void com.baidu.demo1.UserServiceImpl.update())" id="pt"/> -->                <!-- <aop:pointcut expression="execution(void com.baidu.demo1.UserServiceImpl.save())" id="pt"/> -->                <!-- <aop:pointcut expression="execution(* com.baidu.demo1.UserServiceImpl.save())" id="pt"/> -->                <!-- <aop:pointcut expression="execution(* com.baidu.*.UserServiceImpl.save())" id="pt"/> -->                <!-- <aop:pointcut expression="execution(* com.baidu.*.*ServiceImpl.save())" id="pt"/> -->                <!-- <aop:pointcut expression="execution(* com.baidu.*.*ServiceImpl.save*())" id="pt"/> -->                <aop:pointcut expression="execution(* com.baidu.*.*ServiceImpl.save*(..))" id="pt"/>                <aop:aspect ref="myXmlAspect">                    <aop:before method="log" pointcut-ref="pt"/>                </aop:aspect>            </aop:config>                        <!-- 配置AOP的增強 -->            <aop:config>                <!-- 撰寫切入點的運算式 -->                <aop:pointcut expression="execution(public void com.baidu.demo1.UserServiceImpl.save())" id="pt"/>                <aop:aspect ref="myXmlAspect">                    <!-- 前置通知                     <aop:before method="log" pointcut-ref="pt"/>                    -->                    <!-- 后置通知:目標物件方法執行成功后,通知方法才執行                     <aop:after-returning method="log" pointcut-ref="pt"/>                    -->                    <!-- 例外通知:目標物件方法出現例外后,通知執行                     <aop:after-throwing method="log" pointcut-ref="pt"/>                    -->                    <!-- 最終通知:目標物件方法執行成功或失敗,都會執行                     <aop:after method="log" pointcut-ref="pt"/>                    -->                    <!-- 環繞通知:在目標物件方法執行前后去增強,問題,默認捕獲目標物件的方法,手動讓目標物件的方法執行 -->                    <aop:around method="around" pointcut-ref="pt"/>                </aop:aspect>            </aop:config>                    </beans>    import javax.annotation.Resource;    import org.junit.Test;    import org.junit.runner.RunWith;    import org.springframework.test.context.ContextConfiguration;    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;    @RunWith(value=SpringJUnit4ClassRunner.class)    // @ContextConfiguration(value="https://www.cnblogs.com/haizai/p/classpath:applicationContext.xml")    //入門案例    // @ContextConfiguration(value="https://www.cnblogs.com/haizai/p/classpath:applicationContext2.xml")    // 切入點的運算式    @ContextConfiguration(value="https://www.cnblogs.com/haizai/p/classpath:applicationContext3.xml")   // 通知型別    public class Demo1 {                @Resource(name="userService")        private UserService userService;                /**         * AOP的入門程式         */        @Test        public void run1(){            userService.save();        }    }

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/3075.html

標籤:面向對象

上一篇:uml統一建模語言學習筆記(一)

下一篇:十分鐘教條與經驗,輕松搞定系統分析師的案例分析

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more