【java初學者】理解,從面向過程 到 面向物件,面向介面,面向切面
本文章適合初學者,主要是整理清楚,java , 從面向過程 到 面向物件,面向介面,面向切面。
假如我們正在建立一棟別墅。
過程:攪拌水泥,拉磚頭,請工人,粉刷牆壁等等,一系列非常 瑣碎的事情,
物件:砌牆!
介面:這裡,建立一個廁所,這裡建立一個客廳!
切面:就這麼理解吧,假如你和女友約會,
週五:女友出門之前需要 洗澡,洗頭,化妝,(吃飯),卸妝,洗澡,睡覺
週六:女友出門之前需要 洗澡,洗頭,化妝,(喝飲料),卸妝,洗澡,睡覺
週日:女友出門之前需要 洗澡,洗頭,化妝,(去遊樂園),卸妝,洗澡,睡覺
你能接觸的,就是很女友 吃喝玩樂,
下面開始上程式碼:
一、第一個包,面向過程,非常簡單
aop001 Test.java
package aop001; /* * 面向過程的寫法,一次性把所有程式碼寫到一起去 */ public class Test { public static void main(String[] args) { System.out.println("第一個女孩子洗澡"); System.out.println("穿衣服"); System.out.println("化妝"); System.out.println("*****************"); System.out.println("周6"+"吃肯德基"); System.out.println("*****************"); System.out.println("卸妝"); System.out.println("洗澡"); System.out.println("睡覺"); System.out.println("第二個女孩子洗澡"); System.out.println("穿衣服"); System.out.println("化妝"); System.out.println("*****************"); System.out.println("周6"+"吃肯德基"); System.out.println("*****************"); System.out.println("卸妝"); System.out.println("洗澡"); System.out.println("睡覺"); System.out.println("第一個女孩子洗澡"); System.out.println("穿衣服"); System.out.println("化妝"); System.out.println("*****************"); System.out.println("週日"+"約會"); System.out.println("*****************"); System.out.println("卸妝"); System.out.println("洗澡"); System.out.println("睡覺"); System.out.println("第二個女孩子洗澡"); System.out.println("穿衣服"); System.out.println("化妝"); System.out.println("*****************"); System.out.println("週日"+"約會"); System.out.println("*****************"); System.out.println("卸妝"); System.out.println("洗澡"); System.out.println("睡覺"); } }
二、aop002 增加了 2個類 Girl1.java,面向物件!
Girl1.java
package aop002; /* * */ public class Girl1 { public void KFC(String datetime){ System.out.println("洗澡"); System.out.println("穿衣服"); System.out.println("化妝"); System.out.println("*****************"); System.out.println("我是第一個女孩"); System.out.println(datetime+"吃肯德基"); System.out.println("*****************"); System.out.println("卸妝"); System.out.println("洗澡"); System.out.println("睡覺"); } public void meet(String datetime){ System.out.println("洗澡"); System.out.println("穿衣服"); System.out.println("化妝"); System.out.println("*****************"); System.out.println("我是第一個女孩"); System.out.println(datetime+"約會"); System.out.println("*****************"); System.out.println("卸妝"); System.out.println("洗澡"); System.out.println("睡覺"); } } </span>
Girl2.java :和1一樣的事情,只是一個約會,一個去肯德基
package aop002;
/*
*
*/
public class Girl2 {
public void KFC(String datetime){
System.out.println("洗澡");
System.out.println("穿衣服");
System.out.println("化妝");
System.out.println("*****************");
System.out.println("我是第二個女孩");
System.out.println(datetime+"吃肯德基");
System.out.println("*****************");
System.out.println("卸妝");
System.out.println("洗澡");
System.out.println("睡覺");
}
public void meet(String datetime){
System.out.println("洗澡");
System.out.println("穿衣服");
System.out.println("化妝");
System.out.println("*****************");
System.out.println("我是第二個女孩");
System.out.println(datetime+"約會");
System.out.println("*****************");
System.out.println("卸妝");
System.out.println("洗澡");
System.out.println("睡覺");
}
}
Test.java
package aop002;
/*
* 面向物件,OOP,抽象成2個女孩的類,以及她的屬性
*
*/
public class Test {
public static void main(String[] args) {
Girl1 g1 = new Girl1();
Girl2 g2 = new Girl2();
g1.KFC("週六");
g1.meet("週日");
g2.KFC("週六");
g2.meet("週日");
}
}
三、aop003 增加了Girl ,面向介面
2個女孩的沒有變動
Girl.java
<span style="font-size:18px;">package aop003;
public interface Girl {
public void KFC(String datetime);
public void meet(String datetime);
}</span>
Test.java 已經發生了改變!new 物件由 Girl1 g1=new Girl1() ; 表位Girl g1=new Girl1();
變化 雖然只是由Girl1 改為Girl ,但是更加清楚!
package aop003;
/*
* 面向介面
* 本例的缺點:
* 1.非業務邏輯的程式碼,跟核心的業務邏輯程式碼,耦合一起
* 2.一旦非業務邏輯的程式碼發生改變,全部實現類都要去改
*/
public class Test {
public static void main(String[] args) {
Girl g1 = new Girl1();
Girl g2 = new Girl2();
g1.KFC("週六");
g1.meet("週日");
g2.KFC("週六");
g2.meet("週日");
}
}
四、aop004 面向切面,增加了GirlProxy.java 可以理解是代理!經紀人!它負責準備大量的事情,而你只需要寫物件。
比如 經紀人,安排了的早餐,汽車出行,會議,拍廣告;你只需要帶入物件即可。
這裡,Girl ,Girl1,Girl2 都沒有改變,
GirlProxy.java
package aop004;
/*
* 1、經紀人和要明星,必須實現同一個介面
* 2、把明星作為一個本類的一個屬性,用於呼叫
*/
public class GirlProxy implements Girl {
private Girl g;
public GirlProxy(String name){
if ("girl1".equals(name)){
g = new Girl1();
}else if ("girl2".equals(name)){
g = new Girl2();
}
}
@Override
public void KFC(String datetime) {
g.KFC(datetime);
}
@Override
public void meet(String datetime) {
g.meet(datetime);
}
}
Test.java
package aop004;
/*
* 增加一個代理類,類似與明星的經紀人
* 把核心的業務邏輯的程式碼 和 非核心的 分離
* 把非核心的程式碼交給經紀人(proxy)去管理,
* 注意:經紀人和要明星,必須實現同一個介面
*/
public class Test {
public static void main(String[] args) {
Girl g1 = new GirlProxy("girl1");
Girl g2 = new GirlProxy("girl2");
g1.KFC("週六");
g1.meet("週日");
g2.KFC("週六");
g2.meet("週日");
}
}
輸出正常:
五、aop005 這個也是面向切面,但是做的事情更少,是4的效率版
Girl 沒有變,Girl1,2得到了簡化。
Girl1.java
package aop005;
/*
*
*/
public class Girl1 implements Girl{
public void KFC(String datetime){
System.out.println("[核心業務邏輯]我是第一個女孩");
System.out.println("[核心業務邏輯]"+datetime+"吃肯德基");
}
public void meet(String datetime){
System.out.println("[核心業務邏輯]我是第一個女孩");
System.out.println("[核心業務邏輯]"+datetime+"約會");
}
}
Girl2.java :和1差不多。
package aop005;
/*
*
*/
public class Girl2 implements Girl {
public void KFC(String datetime){
System.out.println("[核心業務邏輯]我是第二個女孩");
System.out.println("[核心業務邏輯]"+datetime+"吃肯德基");
}
public void meet(String datetime){
System.out.println("[核心業務邏輯]我是第二個女孩");
System.out.println("[核心業務邏輯]"+datetime+"約會");
}
}
GirlProxy.java
package aop005;
/*
* 1、經紀人和要明星,必須實現同一個介面
* 2、把明星作為一個本類的一個屬性,用於呼叫
*/
public class GirlProxy implements Girl {
private Girl g;
public GirlProxy(String name){
if ("girl1".equals(name)){
g = new Girl1();
}else if ("girl2".equals(name)){
g = new Girl2();
}
}
@Override
public void KFC(String datetime) {
System.out.println("洗澡");
System.out.println("化妝");
System.out.println("穿衣服");
System.out.println("*****************");
g.KFC(datetime);
System.out.println("*****************");
System.out.println("卸妝");
System.out.println("洗澡");
System.out.println("睡覺");
}
@Override
public void meet(String datetime) {
System.out.println("洗澡");
System.out.println("化妝");
System.out.println("穿衣服");
System.out.println("*****************");
g.meet(datetime);
System.out.println("*****************");
System.out.println("卸妝");
System.out.println("洗澡");
System.out.println("睡覺");
}
}
Test.java
package aop005;
/*
* 增加一個代理類,類似與明星的經紀人
* 把核心的業務邏輯的程式碼 和 非核心的 分離
* 把非核心的程式碼交給經紀人(proxy)去管理,
* 注意:經紀人和要明星,必須實現同一個介面
*/
public class Test {
public static void main(String[] args) {
Girl g1 = new GirlProxy("girl1");
Girl g2 = new GirlProxy("girl2");
g1.KFC("週六");
g1.meet("週日");
g2.KFC("週六");
g2.meet("週日");
}
}
程式碼正常執行:
這5個例子,雖然簡單,但是 重要的是理解!
看完一定要自己寫一個不同的,才能算領會。
要是上面都看完了,我再修改一下,把Proxy 代理由靜態代理,改為動態代理!
六:aop06:動態代理。
Girl,Girl1.java,Girl2.java 3個不變
GirlProxy.java刪除了,換為GirlHandler.java
Test也做出了修改。
GirlHandler.java:
package aop006;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class GirlHandler implements InvocationHandler { //呼叫處理器
private Object targer;// 目標是不固定
public GirlHandler(Object targer) {
this.targer = targer;
}
/*
* return 返回是原來目標方法所返回的內容 method 就是要執行的方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
// 具體的業務邏輯程式碼
// Object returnValue = targer.method(args);
Object returnValue = method.invoke(targer, args);
after();
return returnValue;
}
private void before() {
// 前置任務
System.out.println("[代理執行前置]洗澡");
System.out.println("[代理執行前置]化妝");
System.out.println("[代理執行前置]穿衣服");
System.out.println("*****************");
}
private void after() {
// 後置任務
System.out.println("*****************");
System.out.println("[代理執行後置]卸妝");
System.out.println("[代理執行後置]洗澡");
System.out.println("[代理執行後置]聽歌");
System.out.println("");
}
}
Test.java
package aop006;
import java.lang.reflect.Proxy;
/*
* 增加一個【動態代理類】,類似與明星的經紀人
*/
public class Test {
public static void main(String[] args) {
//第一步:建立目標實現類的例項
Girl g1 = new Girl1();
Girl g2 = new Girl2();
//第二步:建立一個動態代理類(CEO 執行長)
GirlHandler handler1 = new GirlHandler(g1);
GirlHandler handler2 = new GirlHandler(g2);
//第三步:建立動態代理(跟靜態代理一樣,申明的變數仍然是目標的介面)
//建立一個宋喆
Girl girlProxy1 = (Girl) Proxy.newProxyInstance(
g1.getClass().getClassLoader(),
g1.getClass().getInterfaces(),
handler1);
girlProxy1.KFC("週六"); //對比 g1.KFC("週六"); 執行後的區別
girlProxy1.meet("週日");
Girl girlProxy2 = (Girl) Proxy.newProxyInstance(
g2.getClass().getClassLoader(),
g2.getClass().getInterfaces(),
handler2);
girlProxy2.KFC("週六"); //對比 g1.KFC("週六"); 執行後的區別
girlProxy2.meet("週日");
}
}
註釋寫的比較仔細了,這裡理解可能更難,但是弄懂之後就簡單了。