1. 程式人生 > >【java初學者】理解,從面向過程 到 面向物件,面向介面,面向切面

【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("週日");
		

	}

}

註釋寫的比較仔細了,這裡理解可能更難,但是弄懂之後就簡單了。