工廠模式以及代理模式


工廠模式:

工廠模式是一種創建模式,:什么是創建,我們知道Java是面向對象的語言,那么我們想使用類中的方法以及屬性,那么我們需要創建對象才能調用,那么我們我們必須:A a = new A();來創建實例,我們的工廠模式就是使用工廠來幫我們創建對象。工廠模式主要是為創建對象提供了接口:工廠模式分為3類:簡單工廠 、工廠方法、抽象工廠、工廠模式我們在什么時候使用呢?

1.在編碼時不能預見需要創建那種對象。

2.系統不應依賴於產品類實例如何被創建,組合、和表達的細節。

一、簡單工廠模式:

  這個模式很簡單,使用的業務比較簡單的情況下;

由3種角色組成:

  工廠類角色::這是本模式的核心,含有一定的商業邏輯和判斷邏輯。在java中它往往由一個具體類實現

 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現

具體產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個具體類實現

package com.factory.simple;

/**
 * 水果接口
 */
public interface Fruitable {

//     水果的功能
     void WhatIm();

}
package com.factory.simple;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class Apple implements Fruitable {




    @Override
    public void WhatIm() {

    }
}
package com.factory.simple;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class FruitFactory {

   //工廠方法
    public Fruitable createFruit(String type){

        if("apploe".equals (type)){

            return new Apple ();
        }else if("Pear".equals (type)){

            return new Pear ();

        }

        return null;
    }

}

 

工廠方法模式:

1、抽象工廠角色:這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現。
2、具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。在java中它由具體的類來實現。
3、抽象產品角色:它是具體產品繼承的父類或者是實現的接口。在java中一般有抽象類或者接口來實現。
4、具體產品角色:具體工廠角色所創建的對象就是此角色的實例。在java中由具體的類來實現。

 

package com.factory.method;

/**
 * 工廠接口
 */
public interface FactoryInterface {

    Fruit  createFruit();

}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 每個產品的具體工廠
 */
public class AppleFactory implements FactoryInterface {

    @Override
    public Fruit createFruit() {
        return new Apple ();
    }
}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 每個產品的具體工廠
 */
public class PearFactory implements FactoryInterface {

    @Override
    public Fruit createFruit() {
        return new Pear ();
    }
}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 水果類
 */
public abstract class Fruit {


}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class Apple extends Fruit {


}
package com.factory.method;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 */
public class Pear extends Fruit {
}

 

抽象工廠模式:

1.系統中有多個產品族,而系統一次只可能消費其中一族產品
2.同屬於同一個產品族的產品一起使用時。
來看看抽象工廠模式的各個角色(和工廠方法的如出一轍):
抽象工廠角色:這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現。
具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。在java中它由具體的類來實現。
抽象產品角色:它是具體產品繼承的父類或者是實現的接口。在java中一般有抽象類或者接口來實現。
具體產品角色:具體工廠角色所創建的對象就是此角色的實例。在java中由具體的類來實現。

 

package com.factory.abs;

/**
 * 產品接口
 */
public interface ThinkPadInterface {

    public void show();



}
package com.factory.abs;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 具體的產品
 */
public class ThinkPadE implements ThinkPadInterface {

    @Override
    public void show() {

    }
}
package com.factory.abs;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 具體的產品
 */
public class ThinkPadT implements ThinkPadInterface {

    @Override
    public void show() {

    }
}
package com.factory.abs;

/**
 * 工廠接口
 */
public interface FactoryInterface {

    public ThinkPadE createThinkPad();

    public ThinkPadT createThinkPadE();

}
package com.factory.abs;

/**
 * @author :wuzhilong
 * @date:2018年10月25日
 * 工廠
 */
public class Factory implements FactoryInterface{

    @Override
    public ThinkPadE createThinkPad() {
        return new ThinkPadE ();
    }

    @Override
    public ThinkPadT createThinkPadE() {
        return new ThinkPadT ();
    }
}

 

 

代理模式:

什么是代理模式:

Proxy模式又叫代理模式,是構造型的模式之一,它可以為其他對象提供一種代理(Proxy)以控制對這個對象的訪問。

所謂代理,是指具有與代理元(被代理的對象)具有相同的接口的類,客戶端必須通過代理與被代理的目標類交互,而代理一般在交互的過程中(交互前后)進行某些特別的處理。

代理模式結構圖:

 

  

代理模式的實現

代理模式可以有兩種實現的方式,一種是靜態代理類,另一種是各大框架都喜歡的動態代理

靜態代理:

package com.wuzhilong.proxy;

public interface ISinger {

    public void sing();
}
package com.wuzhilong.proxy;

/**
 * 目標對象實現某一接口
 */
public class Singer implements ISinger{



    public void sing(){
        System.out.println ("唱一首歌......");

    }
}
package com.wuzhilong.proxy;

/**
 * 代理對象和目標對象實現相同接口
 */
public class SingerProxy implements  ISinger {

    //接收目標對象,來調用sing方法

    private  ISinger singer;

    public SingerProxy(ISinger singer) {
        this.singer = singer;
    }

    //對目標對象的sing方法進行擴展
    @Override
    public void sing() {

        System.out.println ("向觀眾問好");
        singer.sing ();
        System.out.println ("謝謝大家");


    }
}

測試:

package com.wuzhilong.proxy;

/**
 * 靜態代理模式
 */
public class Demo {


    public static void main(String[] args) {
        //目標對象
        ISinger iSinger = new Singer ();

        //代理對象
        ISinger iSinger1 = new SingerProxy (iSinger);

        iSinger1.sing ();



    }




}

總結:其實這里做的事情無非就是,創建一個代理類SingerProxy,繼承了ISinger接口並實現了其中的方法。只不過這種實現特意包含了目標對象的方法,正是這種特征使得看起來像是“擴展”了目標對象的方法。假使代理對象中只是簡單地對sing方法做了另一種實現而沒有包含目標對象的方法,也就不能算作代理模式了。所以這里的包含是關鍵。

  缺點:這種實現方式很直觀也很簡單,但其缺點是代理對象必須提前寫出,如果接口層發生了變化,代理對象的代碼也要進行維護。如果能在運行時動態地寫出代理對象,不但減少了一大批代理類的代碼,也少了不斷維護的煩惱,不過運行時的效率必定受到影響。這種方式就是接下來的動態代理。

 

動態代理(JDK代理):

package com.wuzhilong.jdkproxy;

public interface ISinger {

    public void sing();
}
package com.wuzhilong.jdkproxy;

import com.wuzhilong.jdkproxy.ISinger;

/**
 * 目標對象實現某一接口
 */
public class Singer implements ISinger {



    public void sing(){
        System.out.println ("唱一首歌......");

    }
}
package com.wuzhilong.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class SingerProxy implements InvocationHandler {
    //需要代理的真實對象
    private Object subject;
//    構造方法,給我們要代理的真實對象賦初值

    public SingerProxy(Object subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println ("向觀眾問好");

//        執行目標類的方法
         method.invoke (subject,args);

        System.out.println ("謝謝大家");

        return null;
    }
}
package com.wuzhilong.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Demo {


    public static void main(String[] args) throws Exception{
         //代理的真實對象
        ISinger singer = new Singer ();

        //    我們要代理哪個真實對象,就將該對象傳進去,最后是通過該真實對象來調用其方法的
        InvocationHandler invocationHandler = new SingerProxy (singer);

        /*
         * 通過Proxy的newProxyInstance方法來創建我們的代理對象,我們來看看其三個參數
         * 第一個參數 handler.getClass().getClassLoader() ,我們這里使用handler這個類的ClassLoader對象來加載我們的代理對象
         * 第二個參數realSubject.getClass().getInterfaces(),我們這里為代理對象提供的接口是真實對象所實行的接口,表示我要代理的是該真實對象,這樣我就能調用這組接口中的方法了
         * 第三個參數handler, 我們這里將這個代理對象關聯到了上方的 InvocationHandler 這個對象上
         */

        ISinger singerProxy =(ISinger)  Proxy.newProxyInstance (invocationHandler.getClass ().getClassLoader (),singer.getClass ().getInterfaces (),invocationHandler);
         //通過代理對象執行方法
        singerProxy.sing ();





    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM