亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
Num1:單例模式
Num2:工廠模式
Num3:建造(Builder)模式
Num7:java常用的設計模式有哪些
Num5:適配器(Adapter)模式
java常用的設計模式有哪些:
java常用的設計模式有哪些模式:
首頁 Java Java基礎 java常用的設計模式有哪些

java常用的設計模式有哪些

May 25, 2021 pm 01:51 PM
java 設計模式

java常用的設計模式:1、單例模式;2、工廠模式;3、建造(Builder)模式;4、觀察者模式;5、適配器(Adapter)模式;6、java常用的設計模式有哪些; 7、裝飾模式。

java常用的設計模式有哪些

本教學操作環(huán)境:windows7系統(tǒng)、java8版、DELL G3電腦。

Num1:單例模式

基本概念:保證一個類別只有一個實例,並提供一個存取它的全域存取點。

常見寫法:

餓漢式

public class Singleton{
    private static Singleton singleton = new Singleton();
    private Singleton(){
    }
    public static Singleton getInstance(){
        return singleton;
    }
}

呼叫

Singleton.getInstance().method();

懶漢式

#
public class Singleton {  
    /* 持有私有靜態(tài)實例,防止被引用,此處賦值為null,目的是實現(xiàn)延遲加載 */  
    private static Singleton instance = null;  
  
    /* 私有構造方法,防止被實例化 */  
    private Singleton() {}  
  
    /* 1:懶漢式,靜態(tài)工程方法,創(chuàng)建實例 */  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
protected void method() {  
        System.out.println("SingletonInner");  
    }
}

呼叫:

Singleton.getInstance().method();

優(yōu)點:延遲載入(需要的時候才去載入),適合單執(zhí)行緒操作
缺點: 執(zhí)行緒不安全,在多執(zhí)行緒中很容易出現(xiàn)不同步的情況,如在資料庫物件進行的頻繁讀寫操作時。

雙重執(zhí)行緒檢查模式

public class SingletonInner {  
    private static volatile SingletonInner sInst = null;  // <<< 這里添加了 volatile  
    /** 
     * 私有的構造函數(shù) 
     */  
    private SingletonInner() {}  
  
    public static SingletonInner getInstance() {  
        if (inst == null) {            synchronized (SingletonInner.class) {if (inst == null) {
                    sInst = new SingletonInner();
                }
            }
        }        return sInst;  
    }    protected void method() {  
        System.out.println("SingletonInner");  
    }  
}

呼叫:

Singleton.getInstance().method();

優(yōu)點:執(zhí)行緒安全,支援延時加載,呼叫效率高
缺點:寫法複雜,不簡潔

內(nèi)部類別的實作

public class SingletonInner {  
    /** 
     * 內(nèi)部類實現(xiàn)單例模式 
     * 延遲加載,減少內(nèi)存開銷   
     */  
    private static class SingletonHolder {  
        private static SingletonInner instance = new SingletonInner();  
    }  
  
    /** 
     * 私有的構造函數(shù) 
     */  
    private SingletonInner() {}  
  
    public static SingletonInner getInstance() {  
        return SingletonHolder.instance;  
    }  
  
    protected void method() {  
        System.out.println("SingletonInner");  
    }  
}

#呼叫:

Singleton.getInstance().method();

優(yōu)點:延遲加載,執(zhí)行緒安全(java中class載入時互斥的),也減少了記憶體消耗,建議使用內(nèi)部類別方式。

Num2:工廠模式

基本概念:為建立物件提供過渡接口,以便將創(chuàng)建物件的具體流程屏蔽隔離起來,達到提高靈活性的目的。

分為三類:

  • 簡單工廠模式Simple Factory:不利於產(chǎn)生系列產(chǎn)品;

  • 工廠方法模式Factory Method:又稱為多形性工廠;

  • #抽象工廠模式Abstract Factory:又稱為工具箱,產(chǎn)生產(chǎn)品族,但不利於產(chǎn)生新的產(chǎn)品;

這三種模式從上到下逐步抽象,並且更具一般性。 GOF在《設計模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(摘要 Factory)。將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。

簡單工廠模式

簡單工廠模式又稱靜態(tài)工廠方法模式。重命名上就可以看出這個模式一定很簡單。它存在的目的很簡單:定義一個用於建立物件的介面。

在簡單工廠模式中,一個工廠類處於對產(chǎn)品類實例化調用的中心位置上,它決定那一個產(chǎn)品類應當被實例化, 如同一個交通警察站在來往的車輛流中,決定放行那一個方向的車輛往那一個方向流動一樣。

先來看看它的組成:

  • 工廠類別角色:這是本模式的核心,含有一定的商業(yè)邏輯和判斷邏輯。在java中它往往由一個具體類別實現(xiàn)。
  • 抽象產(chǎn)品角色:它一般是具體產(chǎn)品繼承的父類別或實作的介面。在java中由介面或抽象類別來實作。
  • 具體產(chǎn)品角色:工廠類別所建立的物件就是此角色的實例。在java中由一個具體類別實作。

範例程式碼:

public class Factory{ //getClass 產(chǎn)生Sample 一般可使用動態(tài)類裝載裝入類。
    public static Sample creator(int which){ 
        if (which==1)
            return new SampleA();
        else if (which==2)
            return new SampleB();
    }
}

還有一個目前比較流行的規(guī)格是把靜態(tài)工廠方法命名為valueOfgetInstance。

valueOf:此方法傳回的實例與它的參數(shù)具有相同的值,例如:

Integer a=Integer.valueOf(100); //返回取值為100的Integer對象
public class Complex {
    private final float re;
    private final float im;

    private Complex(float re, float im){
        this.re = re;
        this.im = im;
    }

    public static Complex valueOf(float re, float im){
        return new Complex(re, im);
    }

    public static Complex valueOfPolar(float r, float theta){
        return new Complex((float)(r * Math.cos(theta)), (float)(r * Math.sin(theta)));
    }
}

從上面程式碼可以看出,valueOf()方法能執(zhí)行類型轉換操作,在本例中,把int型別的基本資料轉換成Integer物件。

getInstance:傳回的實例與參數(shù)匹配,例如:

Calendar cal=Calendar.getInstance(Locale.CHINA); //返回符合中國標準的日歷

工廠方法模式

工廠方法模式是簡單工廠模式的進一步抽象化和推廣,工廠方法模式裡不再只由一個工廠類別決定那一個產(chǎn)品類別應當被實例化,這個決定被交給抽象工廠的子類別去做。
來看下它的組成:

  • 抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現(xiàn)的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現(xiàn)。
  • 具體工廠角色:它含有和具體業(yè)務邏輯有關的代碼。由應用程序調用以創(chuàng)建對應的具體產(chǎn)品的對象
  • 抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實現(xiàn)的接口。在java中一般有抽象類或者接口來實現(xiàn)。
  • 具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對象就是此角色的實例。在java中由具體的類來實現(xiàn)。

工廠方法模式使用繼承自抽象工廠角色的多個子類來代替簡單工廠模式中的“上帝類”。正如上面所說,這樣便分擔了對象承受的壓力;而且這樣使得結構變得靈活 起來——當有新的產(chǎn)品(即暴發(fā)戶的汽車)產(chǎn)生時,只要按照抽象產(chǎn)品角色、抽象工廠角色提供的合同來生成,那么就可以被客戶使用,而不必去修改任何已有的代 碼??梢钥闯龉S角色的結構也是符合開閉原則的!

示例代碼:

//抽象產(chǎn)品角色
public interface Moveable {
    void run();
}
//具體產(chǎn)品角色
public class Plane implements Moveable {
    @Override
    public void run() {
        System.out.println("plane....");
    }
}
//具體產(chǎn)品角色
public class Broom implements Moveable {
    @Override
    public void run() {
        System.out.println("broom.....");
    }
}

//抽象工廠
public abstract class VehicleFactory {
    abstract Moveable create();
}
//具體工廠
public class PlaneFactory extends VehicleFactory{
    public Moveable create() {
        return new Plane();
    }
}
//具體工廠
public class BroomFactory extends VehicleFactory{
    public Moveable create() {
        return new Broom();
    }
}
//測試類
public class Test {
    public static void main(String[] args) {
        VehicleFactory factory = new BroomFactory();
        Moveable m = factory.create();
        m.run();
    }
}

可以看出工廠方法的加入,使得對象的數(shù)量成倍增長。當產(chǎn)品種類非常多時,會出現(xiàn)大量的與之對應的工廠對象,這不是我們所希望的。因為如果不能避免這種情 況,可以考慮使用簡單工廠模式與工廠方法模式相結合的方式來減少工廠類:即對于產(chǎn)品樹上類似的種類(一般是樹的葉子中互為兄弟的)使用簡單工廠模式來實 現(xiàn)。

簡單工廠和工廠方法模式的比較

工廠方法模式和簡單工廠模式在定義上的不同是很明顯的。工廠方法模式的核心是一個抽象工廠類,而不像簡單工廠模式, 把核心放在一個實類上。工廠方法模式可以允許很多實的工廠類從抽象工廠類繼承下來, 從而可以在實際上成為多個簡單工廠模式的綜合,從而推廣了簡單工廠模式。
反過來講,簡單工廠模式是由工廠方法模式退化而來。設想如果我們非常確定一個系統(tǒng)只需要一個實的工廠類, 那么就不妨把抽象工廠類合并到實的工廠類中去。而這樣一來,我們就退化到簡單工廠模式了。

抽象工廠模式

示例代碼:

//抽象工廠類
public abstract class AbstractFactory {
    public abstract Vehicle createVehicle();
    public abstract Weapon createWeapon();
    public abstract Food createFood();
}
//具體工廠類,其中Food,Vehicle,Weapon是抽象類,
public class DefaultFactory extends AbstractFactory{
    @Override
    public Food createFood() {
        return new Apple();
    }
    @Override
    public Vehicle createVehicle() {
        return new Car();
    }
    @Override
    public Weapon createWeapon() {
        return new AK47();
    }
}
//測試類
public class Test {
    public static void main(String[] args) {
        AbstractFactory f = new DefaultFactory();
        Vehicle v = f.createVehicle();
        v.run();
        Weapon w = f.createWeapon();
        w.shoot();
        Food a = f.createFood();
        a.printName();
    }
}

在抽象工廠模式中,抽象產(chǎn)品 (AbstractProduct) 可能是一個或多個,從而構成一個或多個產(chǎn)品族(Product Family)。 在只有一個產(chǎn)品族的情況下,抽象工廠模式實際上退化到工廠方法模式。

總結

  • 簡單工廠模式是由一個具體的類去創(chuàng)建其他類的實例,父類是相同的,父類是具體的。

  • 工廠方法模式是有一個抽象的父類定義公共接口,子類負責生成具體的對象,這樣做的目的是將類的實例化操作延遲到子類中完成。

  • 抽象工廠模式提供一個創(chuàng)建一系列相關或相互依賴對象的接口,而無須指定他們具體的類。它針對的是有多個產(chǎn)品的等級結構。而工廠方法模式針對的是一個產(chǎn)品的等級結構。

Num3:建造(Builder)模式

基本概念:是一種對象構建的設計模式,它可以將復雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現(xiàn)方法可以構造出不同表現(xiàn)(屬性)的對象。

java常用的設計模式有哪些是一步一步創(chuàng)建一個復雜的對象,它允許用戶可以只通過指定復雜對象的類型和內(nèi)容就可以構建它們。用戶不知道內(nèi)部的具體構建細節(jié)。java常用的設計模式有哪些是非常類似抽象工廠模式,細微的區(qū)別大概只有在反復使用中才能體會到。

UML結構圖:

java常用的設計模式有哪些

上圖是Strategy 模式的結構圖,讓我們可以進行更方便的描述:

  • Builder:為創(chuàng)建一個Product對象的各個部件指定抽象接口。

  • ConcreteBuilder:實現(xiàn)Builder的接口以構造和裝配該產(chǎn)品的各個部件,定義并明確它所創(chuàng)建的表示,提供一個檢索產(chǎn)品的接口

  • Director:構造一個使用Builder接口的對象。

  • Product:表示被構造的復雜對象。ConcreateBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程。

為何使用

是為了將構建復雜對象的過程和它的部件解耦。注意:是解耦過程和部件。
因為一個復雜的對象,不但有很多大量組成部分,如汽車,有很多部件:車輪、方向盤、發(fā)動機,還有各種小零件等等,部件很多,但遠不止這些,如何將這些部件裝配成一輛汽車,這個裝配過程也很復雜(需要很好的組裝技術),java常用的設計模式有哪些就是為了將部件和組裝過程分開。

如何使用

首先假設一個復雜對象是由多個部件組成的,java常用的設計模式有哪些是把復雜對象的創(chuàng)建和部件的創(chuàng)建分別開來,分別用Builder類和Director類來表示。

首先,需要一個接口,它定義如何創(chuàng)建復雜對象的各個部件:

public interface Builder {
   //創(chuàng)建部件A  比如創(chuàng)建汽車車輪void buildPartA();
   //創(chuàng)建部件B 比如創(chuàng)建汽車方向盤void buildPartB();
   //創(chuàng)建部件C 比如創(chuàng)建汽車發(fā)動機void buildPartC();
   //返回最后組裝成品結果 (返回最后裝配好的汽車)
   //成品的組裝過程不在這里進行,而是轉移到下面的Director類中進行.
   //從而實現(xiàn)了解耦過程和部件    Product getResult();
}

用Director構建最后的復雜對象,而在上面Builder接口中封裝的是如何創(chuàng)建一個個部件(復雜對象是由這些部件組成的),也就是說Director的內(nèi)容是如何將部件最后組裝成成品:

public class Director {
    private Builder builder;
    public Director( Builder builder ) {
        this.builder = builder;
   }
   // 將部件partA partB partC最后組成復雜對象
   //這里是將車輪 方向盤和發(fā)動機組裝成汽車的過程
    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
    }
}

Builder的具體實現(xiàn)ConcreteBuilder:

  • 通過具體完成接口Builder來構建或裝配產(chǎn)品的部件;
  • 定義并明確它所要創(chuàng)建的是什么具體東西;
  • 提供一個可以重新獲取產(chǎn)品的接口。
public class ConcreteBuilder implements Builder {
 Part partA, partB, partC;
 public void buildPartA() {
  //這里是具體如何構建 }
 public void buildPartB() {
  //這里是具體如何構建 }
 public void buildPartC() {
  //這里是具體如何構建 }
 public Product getResult() {
  //返回最后組裝成品結果 }
}

復雜對象:產(chǎn)品Product:

public interface Product { }

復雜對象的部件:

public interface Part { }

我們看看如何調用java常用的設計模式有哪些:

ConcreteBuilder builder = new ConcreteBuilder();
Director director = new Director( builder );
director.construct();
Product product = builder.getResult();

java常用的設計模式有哪些的應用

在Java實際使用中,我們經(jīng)常用到"池"(Pool)的概念,當資源提供者無法提供足夠的資源,并且這些資源需要被很多用戶反復共享時,就需要使用池。"池"實際是一段內(nèi)存,當池中有一些復雜的資源的"斷肢"(比如數(shù)據(jù)庫的連接池,也許有時一個連接會中斷),如果循環(huán)再利用這些"斷肢",將提高內(nèi)存使用效率,提高池的性能。修改java常用的設計模式有哪些中Director類使之能診斷"斷肢"斷在哪個部件上,再修復這個部件。

Num4:java常用的設計模式有哪些

基本概念:java常用的設計模式有哪些定義了一種一對多的依賴關系,讓多個觀察者對象同時監(jiān)聽某一主題對象。這個主題對象在狀態(tài)發(fā)生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。java常用的設計模式有哪些又叫發(fā)布-訂閱(Publish/Subscribe)模式。

UML結構圖

java常用的設計模式有哪些

上圖是Observer 模式的結構圖,讓我們可以進行更方便的描述:

  • Subject類:它把所有對觀察者對象的引用保存在一個聚集里,每個主題都可以有任何數(shù)量的觀察著。抽象主題提供一個接口,可以增加和刪除觀察著對象。

  • Observer類:抽象觀察者,為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己。

  • ConcreteSubject類:具體主題,將有關狀態(tài)存入具體觀察者對象;在具體主題的內(nèi)部狀態(tài)改變時,給所有登記過的觀察者發(fā)出通知。

  • ConcreteObserver類:具體觀察者,實現(xiàn)抽象觀察者角色所要求的更新接口,以便使本身的狀態(tài)與主題的狀態(tài)相協(xié)調。

如何使用

例如:老師有電話號碼,學生需要知道老師的電話號碼以便于在合適的時候撥打,在這樣的組合中,老師就是一個被觀察者(Subject),學生就是需要知道信息的觀察者,當老師的電話號碼發(fā)生改變時,學生得到通知,并更新相應的電話記錄。

先創(chuàng)建一個Subject類:

/**  
 * Subject(目標,Subject):    
 * 目標知道它的觀察者??梢杂腥我舛鄠€觀察者觀察同一個目標。  
 * 提供注冊和刪除觀察者對象的接口。  
 */  public interface Subject {  
    public void attach(Observer mObserver);  
    public void detach(Observer mObserver);        
    public void notice();  
}

創(chuàng)建Observer類:

/**  
 * Observer(觀察者,Observer):  
 * 為那些在目標發(fā)生改變時需要獲得通知的對象定義一個更新接口。   
 */  public interface Observer {  
    public void update();  
}

創(chuàng)建ConcreteSubject類:

/**  
 * ConcreteSubject(具體目標,Teacher)  
 * 將有關狀態(tài)存入各ConcreteObserve對象。  
 * 當他的狀態(tài)發(fā)生改變時,向他的各個觀察者發(fā)出通知。   
 */  public class Teacher implements Subject{  
     
    private String phone;  
    private Vector students;  
    
    public Teacher(){  
        phone = "";  
        students = new Vector();  
    }  
  
    @Override  
    public void attach(Observer mObserver) {  
        students.add(mObserver);  
    }  
  
    @Override  
    public void detach(Observer mObserver) {  
        students.remove(mObserver);  
    }  
  
    @Override  
    public void notice() {  
        for(int i=0;i<students.size();i++){  
            ((Observer)students.get(i)).update();  
        }  
    }  
  
    public String getPhone() {  
        return phone;  
    }  
  
    public void setPhone(String phone) {  
        this.phone = phone;  
        notice();  
    }  
}

創(chuàng)建ConcreteObserver類:

/**  
 * ConcreteObserver(具體觀察者, Student):  
 * 維護一個指向ConcreteSubject對象的引用。  
 * 存儲有關狀態(tài),這些狀態(tài)應與目標的狀態(tài)保持一致。  
 * 實現(xiàn)Observer的更新接口以使自身狀態(tài)與目標的狀態(tài)保持一致。  
 */  public class Student implements Observer{  
  
    private String name;  
    private String phone;  
    private Teacher mTeacher;  
      
    public Student(String name,Teacher t){  
       this.name = name;  
       mTeacher = t;  
    }  
      
    public void show(){  
       System.out.println("Name:"+name+"\nTeacher&#39;sphone:" + phone);  
    }  
      
    @Override  
    public void update() {  
        phone = mTeacher.getPhone();  
    }  
}

客戶端測試:

/**  
 * 觀察者(Observer)模式測試類   
 */  public class ObserverClient {  
    public static void main(String[] args) {  
       Vector students = new Vector();  
       Teacher t = new Teacher();  
       for(int i= 0;i<10;i++){  
           Student st = new Student("Andy.Chen"+i,t);  
           students.add(st);  
           t.attach(st);  
       }  
         
       System.out.println("Welcome to Andy.Chen Blog!" +"\n"   
                   +"Observer Patterns." +"\n"  
                   +"-------------------------------");  
         
       t.setPhone("12345678");  
       for(int i=0;i<3;i++)  
           ((Student)students.get(i)).show();  
         
       t.setPhone("87654321");  
       for(int i=0;i<3;i++)  
           ((Student)students.get(i)).show();  
    }  
}

程序運行結果如下:

Welcome to Andy.Chen Blog!  Observer Patterns.  
-------------------------------  Name:Andy.Chen0  
Teacher&#39;sphone:12345678  
Name:Andy.Chen1  
Teacher&#39;sphone:12345678  
Name:Andy.Chen2  
Teacher&#39;sphone:12345678  
Name:Andy.Chen0  
Teacher&#39;sphone:87654321  
Name:Andy.Chen1  
Teacher&#39;sphone:87654321  
Name:Andy.Chen2  
Teacher&#39;sphone:87654321

總結

java常用的設計模式有哪些何時適用?

  • 當一個抽象模型有兩個方面,其中一個方面依賴于另一方面。將這二者封裝在獨立的對象中可以使他們各自獨立地改變和復用。

  • 當對一個對象的改變需要同時改變其它對象,而不知道具體由多少對象有待改變。

  • 當一個對象必須通知其他對象,而它又不能假定其他對象是誰,換言之,你不希望這些對象是緊密耦合的。讓耦合的雙方都依賴于抽象,而不是依賴于具體。

Num5:適配器(Adapter)模式

基本概念:適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。

適配器模式的用途

用電器做例子,筆記本電腦的插頭一般都是三相的,即除了陽極、陰極外,還有一個地極。而有些地方的電源插座卻只有兩極,沒有地極。電源插座與筆記本電腦的電源插頭不匹配使得筆記本電腦無法使用。這時候一個三相到兩相的轉換器(適配器)就能解決此問題,而這正像是本模式所做的事情。

適配器模式的結構
適配器模式有類的適配器模式對象的適配器模式兩種不同的形式。

java常用的設計模式有哪些:

java常用的設計模式有哪些

在上圖中可以看出,Adaptee類并沒有sampleOperation2()方法,而客戶端則期待這個方法。為使客戶端能夠使用Adaptee類,提供一個中間環(huán)節(jié),即類Adapter,把Adaptee的API與Target類的API銜接起來。Adapter與Adaptee是繼承關系,這決定了這個適配器模式是類的:

  • 目標(Target)角色:這就是所期待得到的接口。注意:由于這里討論的是java常用的設計模式有哪些,因此目標不可以是類。
  • 源(Adapee)角色:現(xiàn)在需要適配的接口。
  • 適配器(Adaper)角色:適配器類是本模式的核心。適配器把源接口轉換成目標接口。顯然,這一角色不可以是接口,而必須是具體類。
java常用的設計模式有哪些模式:

java常用的設計模式有哪些

從上圖可以看出,Adaptee類并沒有sampleOperation2()方法,而客戶端則期待這個方法。為使客戶端能夠使用Adaptee類,需要提供一個包裝(Wrapper)類Adapter。這個包裝類包裝了一個Adaptee的實例,從而此包裝類能夠把Adaptee的API與Target類的API銜接起來。Adapter與Adaptee是委派關系,這決定了適配器模式是對象的。

示例代碼:

public interface Target {    /**
     * 這是源類Adaptee也有的方法     */
    public void sampleOperation1(); 
    /**
     * 這是源類Adapteee沒有的方法     */
    public void sampleOperation2(); 
}public class Adaptee {    public void sampleOperation1(){}
}

適配器類:

public class Adapter {
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee){
        this.adaptee = adaptee;
    }
    /**
     * 源類Adaptee有方法sampleOperation1
     * 因此適配器類直接委派即可
     */
    public void sampleOperation1(){
        this.adaptee.sampleOperation1();
    }
    /**
     * 源類Adaptee沒有方法sampleOperation2
     * 因此由適配器類需要補充此方法
     */
    public void sampleOperation2(){
        //寫相關的代碼
    }
}

類適配器和java常用的設計模式有哪些的權衡

  • 類適配器使用對象繼承的方式,是靜態(tài)的定義方式;而java常用的設計模式有哪些使用對象組合的方式,是動態(tài)組合的方式。
  • 對于類適配器由于適配器直接繼承了Adaptee,使得適配器不能和Adaptee的子類一起工作,因為繼承是靜態(tài)的關系,當適配器繼承了Adaptee后,就不可能再去處理 Adaptee的子類了。

  • 對于java常用的設計模式有哪些一個適配器可以把多種不同的源適配到同一個目標。換言之,同一個適配器可以把源類和它的子類都適配到目標接口。因為java常用的設計模式有哪些采用的是對象組合的關系,只要對象類型正確,是不是子類都無所謂。

  • 對于類適配器適配器可以重定義Adaptee的部分行為,相當于子類覆蓋父類的部分實現(xiàn)方法。

  • 對于java常用的設計模式有哪些要重定義Adaptee的行為比較困難,這種情況下,需要定義Adaptee的子類來實現(xiàn)重定義,然后讓適配器組合子類。雖然重定義Adaptee的行為比較困難,但是想要增加一些新的行為則方便的很,而且新增加的行為可同時適用于所有的源。

  • 對于類適配器,僅僅引入了一個對象,并不需要額外的引用來間接得到Adaptee。

  • 對于java常用的設計模式有哪些,需要額外的引用來間接得到Adaptee。

建議盡量使用java常用的設計模式有哪些的實現(xiàn)方式,多用合成或聚合、少用繼承。當然,具體問題具體分析,根據(jù)需要來選用實現(xiàn)方式,最適合的才是最好的。

適配器模式的優(yōu)點

  • 更好的復用性:系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。那么通過適配器模式就可以讓這些功能得到更好的復用。

  • 更好的擴展性:在實現(xiàn)適配器功能的時候,可以調用自己開發(fā)的功能,從而自然地擴展系統(tǒng)的功能。

適配器模式的缺點

  過多的使用適配器,會讓系統(tǒng)非常零亂,不易整體進行把握。比如,明明看到調用的是A接口,其實內(nèi)部被適配成了B接口的實現(xiàn),一個系統(tǒng)如果太多出現(xiàn)這種情況,無異于一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統(tǒng)進行重構。

Num6:java常用的設計模式有哪些

基本概念:為其他對象提供一種代理以控制對這個對象的訪問。也可以說,在出發(fā)點到目的地之間有一道中間層,意為代理。

為什么要使用

  • 授權機制不同級別的用戶對同一對象擁有不同的訪問權利,如在論壇系統(tǒng)中,就使用Proxy進行授權機制控制,訪問論壇有兩種人:注冊用戶和游客(未注冊用戶),論壇就通過類似ForumProxy這樣的代理來控制這兩種用戶對論壇的訪問權限。

  • 某個客戶端不能直接操作到某個對象,但又必須和那個對象有所互動。

舉例兩個具體情況:

  • 如果那個對象是一個是很大的圖片,需要花費很長時間才能顯示出來,那么當這個圖片包含在文檔中時,使用編輯器或瀏覽器打開這個文檔,打開文檔必須很迅速,不能等待大圖片處理完成,這時需要做個圖片Proxy來代替真正的圖片。
  • 如果那個對象在Internet的某個遠端服務器上,直接操作這個對象因為網(wǎng)絡速度原因可能比較慢,那我們可以先用Proxy來代替那個對象。

總之原則是,對于開銷很大的對象,只有在使用它時才創(chuàng)建,這個原則可以為我們節(jié)省很多寶貴的Java內(nèi)存。所以,有些人認為Java耗費資源內(nèi)存,我以為這和程序編制思路也有一定的關系。

如何使用

以論壇系統(tǒng)為例,訪問論壇系統(tǒng)的用戶有多種類型:注冊普通用戶、論壇管理者、系統(tǒng)管理者、游客。注冊普通用戶才能發(fā)言,論壇管理者可以管理他被授權的論壇,系統(tǒng)管理者可以管理所有事務等,這些權限劃分和管理是使用Proxy完成的。
在Forum中陳列了有關論壇操作的主要行為,如論壇名稱,論壇描述的獲取和修改,帖子發(fā)表刪除編輯等,在ForumPermissions中定義了各種級別權限的用戶:

public class ForumPermissions implements Cacheable {
    /**
    * Permission to read object.
    */
    public static final int READ = 0;

    /**
    * Permission to administer the entire sytem.
    */
    public static final int SYSTEM_ADMIN = 1;

    /**
    * Permission to administer a particular forum.
    */
    public static final int FORUM_ADMIN = 2;

    /**
    * Permission to administer a particular user.
    */
    public static final int USER_ADMIN = 3;

    /**
    * Permission to administer a particular group.
    */
    public static final int GROUP_ADMIN = 4;

    /**
    * Permission to moderate threads.
    */
    public static final int MODERATE_THREADS = 5;

    /**
    * Permission to create a new thread.
    */
    public static final int CREATE_THREAD = 6;

    /**
    * Permission to create a new message.
    */
    public static final int CREATE_MESSAGE = 7;

    /**
    * Permission to moderate messages.
    */
    public static final int MODERATE_MESSAGES = 8;
  
    public boolean isSystemOrForumAdmin() {
        return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]);
    }

//相關操作代碼
}

因此,F(xiàn)orum中各種操作權限是和ForumPermissions定義的用戶級別有關系的,作為接口Forum的實現(xiàn):ForumProxy正是將這種對應關系聯(lián)系起來。比如,修改Forum的名稱,只有論壇管理者或系統(tǒng)管理者可以修改,代碼如下:

public class ForumProxy implements Forum {
    private ForumPermissions permissions;
    private Forum forum;
    this.authorization = authorization;

    public ForumProxy(Forum forum, Authorization authorization,ForumPermissions permissions){
        this.forum = forum;
        this.authorization = authorization;
        this.permissions = permissions;
    }
    .....
    public void setName(String name) throws UnauthorizedException,
        ForumAlreadyExistsException{
        //只有是系統(tǒng)或論壇管理者才可以修改名稱
      if (permissions.isSystemOrForumAdmin()) {
        forum.setName(name);
      }
    else {
    throw new UnauthorizedException();
    }
    }
    ...

}

而DbForum才是接口Forum的真正實現(xiàn),以修改論壇名稱為例:

public class DbForum implements Forum, Cacheable {
    ...
    public void setName(String name) throws ForumAlreadyExistsException {
  ....
        this.name = name;
       //這里真正將新名稱保存到數(shù)據(jù)庫中
       saveToDb();
  ....
    }
    ...
}

凡是涉及到對論壇名稱修改這一事件,其他程序都首先得和ForumProxy打交道,由ForumProxy決定是否有權限做某一樣事情,F(xiàn)orumProxy是個名副其實的"網(wǎng)關","安全代理系統(tǒng)"。
在平時應用中,無可避免總要涉及到系統(tǒng)的授權或安全體系,不管你有無意識的使用Proxy,實際你已經(jīng)在使用Proxy了。

流程圖

java常用的設計模式有哪些

Num7:java常用的設計模式有哪些

基本概念:java常用的設計模式有哪些(Decorator),動態(tài)地給一個對象添加一些額外的職責,就增加功能來說,java常用的設計模式有哪些比生成子類更為靈活。

UML結構圖

java常用的設計模式有哪些

上圖是Decorator 模式的結構圖,讓我們可以進行更方便的描述:

  • Component是定義一個對象接口,可以給這些對象動態(tài)地添加職責。

  • ConcreteComponent是定義了一個具體的對象,也可以給這個對象添加一些職責。

Decorator是裝飾抽象類,繼承了Component,從外類來擴展Component類的功能,但對于Component來說,是無需知道Decorator存在的。ConcreteDecorator就是具體的裝飾對象,起到給Component添加職責的功能。

如何使用

假設情景:某人裝扮自己形象,穿衣服,褲子,鞋子,戴帽子等來把自己給包裝起來,需要把所需的功能按正確的順序串聯(lián)起來進行控制,我們應該如何設計才能做到呢?如下,先看下代碼結構圖:

先創(chuàng)建一個接口類:Component.java

public interface Component {    
    void show();
}

創(chuàng)建一個具體的 ConcreteComponent 來實現(xiàn) Component 接口:Person.java

public class Person implements Component{
    private String name;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(String name){
        this.name = name;
    }

    @Override
    public void show() {
        System.out.println("裝扮的" + name);
    }
}

創(chuàng)建裝飾類 Decorator 實現(xiàn) Component 接口

public class Decorator implements Component{
    private Component mComponent;
    public void decoratorObj(Component component){
        mComponent = component;
    }

    @Override
    public void show() {
        if(mComponent != null){
            mComponent.show();
        }
    }
}

分別創(chuàng)建具體的裝飾類:Jeans.java , Pelisse.java, Sandal.java ...等等,分別繼承 Decorator.java 類

/** 牛仔褲 */
public class Jeans extends Decorator {
    @Override
    public void show(){
        System.out.println("穿牛仔褲");
        super.show();
    }
    
}

客戶端測試類

/**
 * java常用的設計模式有哪些測試客戶端
 */
public class DecoratorClient {
    public static void main(String[] args) {
        System.out.println("Welcome to Andy.Chen Blog!" +"\n" 
                   +"Decorator Patterns." +"\n");
        
        Person mPerson = new Person("Andy");
        
        Sandal mSandal = new Sandal();
        Jeans mJeans = new Jeans();
        TShirt mShirt = new TShirt();
        
        mShirt.decoratorObj(mPerson);
        mJeans.decoratorObj(mShirt);
        mSandal.decoratorObj(mJeans);
        mSandal.show(); 
    }
}

測試結果

Welcome to Andy.Chen Blog!
Decorator Patterns.
  
穿涼鞋
穿牛仔褲
穿T-Shirt
裝扮的Andy

總結

Decorator模式有以下的優(yōu)缺點:

  • 比靜態(tài)繼承更靈活與物件的靜態(tài)繼承相比,Decorator模式提供了更靈活的向物件添加職責的方式,可以使用添加和分離的方法,用裝飾在運行時刻增加和刪除職責。使用繼承機制增加職責需要創(chuàng)建一個新的子類,如果需要為原來所有的子類都添加功能的話,每個子類都需要重寫,增加系統(tǒng)的複雜度,此外可以為一個特定的Component類提供多個Decorator,這種混合匹配是適用繼承很難做到的。

  • 避免在層次結構高層的類別有太多的特徵,Decorator模式提供了一種「即用即付」的方法來添加職責,他並不試圖在一個複雜的可訂制的類別中支援所有可預見的特徵,相反可以定義一個簡單的類,並且用Decorator類給他逐漸的添加功能,從簡單的部件組合出複雜的功能。

  • Decorator?與它的Component不一樣Decorator是一個透明的包裝,如果我們從物件標識的觀點出發(fā),一個被裝飾了的元件與這個元件是有差別的,因此使用裝飾時不應該以來物件標識。

  • 產(chǎn)生許多小對象,採用Decorator模式進行系統(tǒng)設計往往會產(chǎn)生許多看上去類似的小對象,這些對象僅在他們相互連接的方式上有所不同。

相關影片教學推薦:Java影片教學

以上是java常用的設計模式有哪些的詳細內(nèi)容。更多資訊請關注PHP中文網(wǎng)其他相關文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
VSCODE設置。 JSON位置 VSCODE設置。 JSON位置 Aug 01, 2025 am 06:12 AM

settings.json文件位於用戶級或工作區(qū)級路徑,用於自定義VSCode設置。 1.用戶級路徑:Windows為C:\Users\\AppData\Roaming\Code\User\settings.json,macOS為/Users//Library/ApplicationSupport/Code/User/settings.json,Linux為/home//.config/Code/User/settings.json;2.工作區(qū)級路徑:項目根目錄下的.vscode/settings

如何使用JDBC處理Java的交易? 如何使用JDBC處理Java的交易? Aug 02, 2025 pm 12:29 PM

要正確處理JDBC事務,必須先關閉自動提交模式,再執(zhí)行多個操作,最後根據(jù)結果提交或回滾;1.調用conn.setAutoCommit(false)以開始事務;2.執(zhí)行多個SQL操作,如INSERT和UPDATE;3.若所有操作成功則調用conn.commit(),若發(fā)生異常則調用conn.rollback()確保數(shù)據(jù)一致性;同時應使用try-with-resources管理資源,妥善處理異常並關閉連接,避免連接洩漏;此外建議使用連接池、設置保存點實現(xiàn)部分回滾,並保持事務盡可能短以提升性能。

在Java的掌握依賴注入春季和Guice 在Java的掌握依賴注入春季和Guice Aug 01, 2025 am 05:53 AM

依賴性(di)IsadesignpatternwhereObjectsReceivedenciesenciesExtern上,推廣looseSecouplingAndEaseerTestingThroughConstructor,setter,orfieldInjection.2.springfraMefringframeWorkSannotationsLikeLikeLike@component@component,@component,@service,@autowiredwithjava-service和@autowiredwithjava-ligatiredwithjava-lase-lightike

Python Itertools組合示例 Python Itertools組合示例 Jul 31, 2025 am 09:53 AM

itertools.combinations用於生成從可迭代對像中選取指定數(shù)量元素的所有不重複組合(順序無關),其用法包括:1.從列表中選2個元素組合,如('A','B')、('A','C')等,避免重複順序;2.對字符串取3個字符組合,如"abc"、"abd",適用於子序列生成;3.求兩數(shù)之和等於目標值的組合,如1 5=6,簡化雙重循環(huán)邏輯;組合與排列的區(qū)別在於順序是否重要,combinations視AB與BA為相同,而permutations視為不同;

Python Pytest夾具示例 Python Pytest夾具示例 Jul 31, 2025 am 09:35 AM

fixture是用於為測試提供預設環(huán)境或數(shù)據(jù)的函數(shù),1.使用@pytest.fixture裝飾器定義fixture;2.在測試函數(shù)中以參數(shù)形式註入fixture;3.yield之前執(zhí)行setup,之後執(zhí)行teardown;4.通過scope參數(shù)控製作用域,如function、module等;5.將共用fixture放在conftest.py中實現(xiàn)跨文件共享,從而提升測試的可維護性和復用性。

故障排除常見的java`ofmemoryError`場景'' 故障排除常見的java`ofmemoryError`場景'' Jul 31, 2025 am 09:07 AM

java.lang.OutOfMemoryError:Javaheapspace表示堆內(nèi)存不足,需檢查大對象處理、內(nèi)存洩漏及堆設置,通過堆轉儲分析工具定位並優(yōu)化代碼;2.Metaspace錯誤因類元數(shù)據(jù)過多,常見於動態(tài)類生成或熱部署,應限制MaxMetaspaceSize並優(yōu)化類加載;3.Unabletocreatenewnativethread因係統(tǒng)線程資源耗盡,需檢查線程數(shù)限制、使用線程池、調整棧大??;4.GCoverheadlimitexceeded指GC頻繁但回收少,應分析GC日誌,優(yōu)化

如何使用Java的日曆? 如何使用Java的日曆? Aug 02, 2025 am 02:38 AM

使用java.time包中的類替代舊的Date和Calendar類;2.通過LocalDate、LocalDateTime和LocalTime獲取當前日期時間;3.使用of()方法創(chuàng)建特定日期時間;4.利用plus/minus方法不可變地增減時間;5.使用ZonedDateTime和ZoneId處理時區(qū);6.通過DateTimeFormatter格式化和解析日期字符串;7.必要時通過Instant與舊日期類型兼容;現(xiàn)代Java中日期處理應優(yōu)先使用java.timeAPI,它提供了清晰、不可變且線

了解Java虛擬機(JVM)內(nèi)部 了解Java虛擬機(JVM)內(nèi)部 Aug 01, 2025 am 06:31 AM

TheJVMenablesJava’s"writeonce,runanywhere"capabilitybyexecutingbytecodethroughfourmaincomponents:1.TheClassLoaderSubsystemloads,links,andinitializes.classfilesusingbootstrap,extension,andapplicationclassloaders,ensuringsecureandlazyclassloa

See all articles