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

Table of Contents
Num1: Singleton mode
Num2: Factory pattern
Num3:建造(Builder)模式
Num7:What are the commonly used design patterns in Java?
Num5:適配器(Adapter)模式
What are the commonly used design patterns in Java?:
What are the commonly used design patterns in Java?模式:
Home Java JavaBase What are the commonly used design patterns in Java?

What are the commonly used design patterns in Java?

May 25, 2021 pm 01:51 PM
java Design Patterns

Commonly used design patterns in java: 1. Singleton mode; 2. Factory mode; 3. Builder mode; 4. Observer mode; 5. Adapter mode; 6. Agent mode; 7. Decoration mode.

What are the commonly used design patterns in Java?

The operating environment of this tutorial: windows7 system, java8 version, DELL G3 computer.

Num1: Singleton mode

Basic concept: Ensure that a class has only one instance and provide a global access point to access it.

Common writing:

hunger style

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

call

Singleton.getInstance().method();

lazy man style

public class Singleton {  
    /* 持有私有靜態(tài)實例,防止被引用,此處賦值為null,目的是實現(xiàn)延遲加載 */  
    private static Singleton instance = null;  
  
    /* 私有構(gòu)造方法,防止被實例化 */  
    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");  
    }
}

Call:

Singleton.getInstance().method();

Advantages: Delayed loading (loading only when needed), suitable for single-threaded operation
Disadvantages: Thread unsafe, it is easy to be out of sync in multi-threads , such as when frequent read and write operations are performed on database objects.

Dual thread check mode

public class SingletonInner {  
    private static volatile SingletonInner sInst = null;  // <<< 這里添加了 volatile  
    /** 
     * 私有的構(gòu)造函數(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");  
    }  
}

Call:

Singleton.getInstance().method();

Advantages: thread safety, support delayed loading, high calling efficiency
Disadvantages: The writing method is complicated and not concise

Implementation of internal classes

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

Call:

Singleton.getInstance().method();

Advantages: delayed loading, thread safety (when loading class in java Mutually exclusive), also reduces memory consumption, it is recommended to use the inner class method.

Num2: Factory pattern

Basic concept: Provide a transition interface for creating objects, so as to shield and isolate the specific process of creating objects to achieve the purpose of improving flexibility.

is divided into three categories:

  • Simple factory modelSimple Factory: Not conducive to the production of series products;

  • Factory Method PatternFactory Method: Also known as Polymorphic Factory;

  • Abstract Factory PatternAbstract Factory: Also known as The toolbox generates product families, but is not conducive to generating new products;

These three modes are gradually abstracted from top to bottom and are more general. In the book "Design Patterns", GOF divides the factory pattern into two categories: Factory Method pattern (Factory Method) and Abstract Factory pattern (Abstract Factory). Think of the Simple Factory pattern as a special case of the Factory Method pattern, and the two are classified into the same category.

Simple Factory Pattern

Simple Factory Pattern is also called Static Factory Method Pattern. It can be seen from the renaming that this mode must be very simple. Its purpose is simple: to define an interface for creating objects.

In the simple factory pattern, a factory class is at the center of the call to product class instantiation. It determines which product class should be instantiated, just like a traffic policeman standing in the flow of passing vehicles. It is the same as deciding which direction to let vehicles flow in.

Let’s take a look at its composition first:

  • Factory role: This is the core of this model and contains certain business logic and judgment logic. In java it is often implemented by a concrete class.
  • Abstract product role: It is generally the parent class inherited by a specific product or the interface implemented. It is implemented in java by interface or abstract class.
  • Specific product role: The object created by the factory class is an instance of this role. Implemented by a concrete class in java.

Sample code:

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();
    }
}

Another popular norm is to name the static factory method valueOf or getInstance.

valueOf: The instance returned by this method has the same value as its parameter, for example:

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)));
    }
}

As can be seen from the above code, the valueOf() method can be executed Type conversion operation, in this example, converts basic data of type int into Integer objects.

getInstance: The returned instance matches the parameters, for example:

Calendar cal=Calendar.getInstance(Locale.CHINA); //返回符合中國標(biāo)準(zhǔn)的日歷

Factory method pattern

The factory method pattern is simple Further abstraction and promotion of the factory pattern, in the factory method pattern, it is no longer just a factory class that determines which product class should be instantiated. This decision is left to the subclasses of the abstract factory.
Let’s take a look at its composition:

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

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

示例代碼:

//抽象產(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ù)量成倍增長。當(dāng)產(chǎn)品種類非常多時,會出現(xiàn)大量的與之對應(yīng)的工廠對象,這不是我們所希望的。因為如果不能避免這種情 況,可以考慮使用簡單工廠模式與工廠方法模式相結(jié)合的方式來減少工廠類:即對于產(chǎn)品樹上類似的種類(一般是樹的葉子中互為兄弟的)使用簡單工廠模式來實 現(xiàn)。

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

工廠方法模式和簡單工廠模式在定義上的不同是很明顯的。工廠方法模式的核心是一個抽象工廠類,而不像簡單工廠模式, 把核心放在一個實類上。工廠方法模式可以允許很多實的工廠類從抽象工廠類繼承下來, 從而可以在實際上成為多個簡單工廠模式的綜合,從而推廣了簡單工廠模式。
反過來講,簡單工廠模式是由工廠方法模式退化而來。設(shè)想如果我們非常確定一個系統(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) 可能是一個或多個,從而構(gòu)成一個或多個產(chǎn)品族(Product Family)。 在只有一個產(chǎn)品族的情況下,抽象工廠模式實際上退化到工廠方法模式。

總結(jié)

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

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

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

Num3:建造(Builder)模式

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

What are the commonly used design patterns in Java?是一步一步創(chuàng)建一個復(fù)雜的對象,它允許用戶可以只通過指定復(fù)雜對象的類型和內(nèi)容就可以構(gòu)建它們。用戶不知道內(nèi)部的具體構(gòu)建細節(jié)。What are the commonly used design patterns in Java?是非常類似抽象工廠模式,細微的區(qū)別大概只有在反復(fù)使用中才能體會到。

UML結(jié)構(gòu)圖:

What are the commonly used design patterns in Java?

上圖是Strategy 模式的結(jié)構(gòu)圖,讓我們可以進行更方便的描述:

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

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

  • Director:構(gòu)造一個使用Builder接口的對象。

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

為何使用

是為了將構(gòu)建復(fù)雜對象的過程和它的部件解耦。注意:是解耦過程和部件。
因為一個復(fù)雜的對象,不但有很多大量組成部分,如汽車,有很多部件:車輪、方向盤、發(fā)動機,還有各種小零件等等,部件很多,但遠不止這些,如何將這些部件裝配成一輛汽車,這個裝配過程也很復(fù)雜(需要很好的組裝技術(shù)),What are the commonly used design patterns in Java?就是為了將部件和組裝過程分開。

如何使用

首先假設(shè)一個復(fù)雜對象是由多個部件組成的,What are the commonly used design patterns in Java?是把復(fù)雜對象的創(chuàng)建和部件的創(chuàng)建分別開來,分別用Builder類和Director類來表示。

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

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();
   //返回最后組裝成品結(jié)果 (返回最后裝配好的汽車)
   //成品的組裝過程不在這里進行,而是轉(zhuǎn)移到下面的Director類中進行.
   //從而實現(xiàn)了解耦過程和部件    Product getResult();
}

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

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

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

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

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

public interface Product { }

復(fù)雜對象的部件:

public interface Part { }

我們看看如何調(diào)用What are the commonly used design patterns in Java?:

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

What are the commonly used design patterns in Java?的應(yīng)用

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

Num4:What are the commonly used design patterns in Java?

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

UML結(jié)構(gòu)圖

What are the commonly used design patterns in Java?

上圖是Observer 模式的結(jié)構(gòu)圖,讓我們可以進行更方便的描述:

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

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

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

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

如何使用

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

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

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

創(chuàng)建Observer類:

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

創(chuàng)建ConcreteSubject類:

/**  
 * ConcreteSubject(具體目標(biāo),Teacher)  
 * 將有關(guān)狀態(tài)存入各ConcreteObserve對象。  
 * 當(dāng)他的狀態(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對象的引用。  
 * 存儲有關(guān)狀態(tài),這些狀態(tài)應(yīng)與目標(biāo)的狀態(tài)保持一致。  
 * 實現(xiàn)Observer的更新接口以使自身狀態(tài)與目標(biāo)的狀態(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();  
    }  
}

程序運行結(jié)果如下:

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

總結(jié)

What are the commonly used design patterns in Java?何時適用?

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

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

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

Num5:適配器(Adapter)模式

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

適配器模式的用途

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

適配器模式的結(jié)構(gòu)
適配器模式有類的適配器模式對象的適配器模式兩種不同的形式。

What are the commonly used design patterns in Java?:

What are the commonly used design patterns in Java?

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

  • 目標(biāo)(Target)角色:這就是所期待得到的接口。注意:由于這里討論的是What are the commonly used design patterns in Java?,因此目標(biāo)不可以是類。
  • 源(Adapee)角色:現(xiàn)在需要適配的接口。
  • 適配器(Adaper)角色:適配器類是本模式的核心。適配器把源接口轉(zhuǎn)換成目標(biāo)接口。顯然,這一角色不可以是接口,而必須是具體類。
What are the commonly used design patterns in Java?模式:

What are the commonly used design patterns in Java?

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

示例代碼:

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(){
        //寫相關(guān)的代碼
    }
}

類適配器和What are the commonly used design patterns in Java?的權(quán)衡

  • 類適配器使用對象繼承的方式,是靜態(tài)的定義方式;而What are the commonly used design patterns in Java?使用對象組合的方式,是動態(tài)組合的方式。
  • 對于類適配器由于適配器直接繼承了Adaptee,使得適配器不能和Adaptee的子類一起工作,因為繼承是靜態(tài)的關(guān)系,當(dāng)適配器繼承了Adaptee后,就不可能再去處理 Adaptee的子類了。

  • 對于What are the commonly used design patterns in Java?一個適配器可以把多種不同的源適配到同一個目標(biāo)。換言之,同一個適配器可以把源類和它的子類都適配到目標(biāo)接口。因為What are the commonly used design patterns in Java?采用的是對象組合的關(guān)系,只要對象類型正確,是不是子類都無所謂。

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

  • 對于What are the commonly used design patterns in Java?要重定義Adaptee的行為比較困難,這種情況下,需要定義Adaptee的子類來實現(xiàn)重定義,然后讓適配器組合子類。雖然重定義Adaptee的行為比較困難,但是想要增加一些新的行為則方便的很,而且新增加的行為可同時適用于所有的源。

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

  • 對于What are the commonly used design patterns in Java?,需要額外的引用來間接得到Adaptee。

建議盡量使用What are the commonly used design patterns in Java?的實現(xiàn)方式,多用合成或聚合、少用繼承。當(dāng)然,具體問題具體分析,根據(jù)需要來選用實現(xiàn)方式,最適合的才是最好的。

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

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

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

適配器模式的缺點

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

Num6:What are the commonly used design patterns in Java?

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

為什么要使用

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

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

舉例兩個具體情況:

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

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

如何使用

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

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]);
    }

//相關(guān)操作代碼
}

因此,F(xiàn)orum中各種操作權(quán)限是和ForumPermissions定義的用戶級別有關(guān)系的,作為接口Forum的實現(xiàn):ForumProxy正是將這種對應(yīng)關(guān)系聯(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決定是否有權(quán)限做某一樣事情,F(xiàn)orumProxy是個名副其實的"網(wǎng)關(guān)","安全代理系統(tǒng)"。
在平時應(yīng)用中,無可避免總要涉及到系統(tǒng)的授權(quán)或安全體系,不管你有無意識的使用Proxy,實際你已經(jīng)在使用Proxy了。

流程圖

What are the commonly used design patterns in Java?

Num7:What are the commonly used design patterns in Java?

基本概念:What are the commonly used design patterns in Java?(Decorator),動態(tài)地給一個對象添加一些額外的職責(zé),就增加功能來說,What are the commonly used design patterns in Java?比生成子類更為靈活。

UML結(jié)構(gòu)圖

What are the commonly used design patterns in Java?

上圖是Decorator 模式的結(jié)構(gòu)圖,讓我們可以進行更方便的描述:

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

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

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

如何使用

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

先創(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();
    }
    
}

客戶端測試類

/**
 * What are the commonly used design patterns in 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(); 
    }
}

測試結(jié)果

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

總結(jié)

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

  • More flexible than static inheritance Compared with static inheritance of objects, the Decorator pattern provides a more flexible way to add responsibilities to objects. You can use the add and detach methods, and use decoration to add responsibilities at runtime. and remove responsibilities. Using the inheritance mechanism to add responsibilities requires creating a new subclass. If you need to add functions to all original subclasses, each subclass needs to be rewritten, increasing the complexity of the system. In addition, multiple subclasses can be provided for a specific Component class. Decorator, this kind of mixing and matching is difficult to achieve using inheritance.

  • Avoid having too many features in classes higher up in the hierarchy. The Decorator pattern provides a "pay-as-you-go" approach to adding responsibilities without trying to create a complex The customizable class supports all foreseeable features. Instead, you can define a simple class and gradually add functions to it using the Decorator class, combining simple components to create complex functions.

  • Decorator is different from its Component. Decorator is a transparent package. If we start from the perspective of object identification, there is a difference between a decorated component and this component, so Decorators should not be used with object identifiers.

  • Produces many small objects. System design using the Decorator pattern often produces many small objects that look similar. These objects only differ in the way they are connected to each other.

Recommended related video tutorials: Java video tutorial

The above is the detailed content of What are the commonly used design patterns in Java?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1488
72
VSCode settings.json location VSCode settings.json location Aug 01, 2025 am 06:12 AM

The settings.json file is located in the user-level or workspace-level path and is used to customize VSCode settings. 1. User-level path: Windows is C:\Users\\AppData\Roaming\Code\User\settings.json, macOS is /Users//Library/ApplicationSupport/Code/User/settings.json, Linux is /home//.config/Code/User/settings.json; 2. Workspace-level path: .vscode/settings in the project root directory

How to handle transactions in Java with JDBC? How to handle transactions in Java with JDBC? Aug 02, 2025 pm 12:29 PM

To correctly handle JDBC transactions, you must first turn off the automatic commit mode, then perform multiple operations, and finally commit or rollback according to the results; 1. Call conn.setAutoCommit(false) to start the transaction; 2. Execute multiple SQL operations, such as INSERT and UPDATE; 3. Call conn.commit() if all operations are successful, and call conn.rollback() if an exception occurs to ensure data consistency; at the same time, try-with-resources should be used to manage resources, properly handle exceptions and close connections to avoid connection leakage; in addition, it is recommended to use connection pools and set save points to achieve partial rollback, and keep transactions as short as possible to improve performance.

python itertools combinations example python itertools combinations example Jul 31, 2025 am 09:53 AM

itertools.combinations is used to generate all non-repetitive combinations (order irrelevant) that selects a specified number of elements from the iterable object. Its usage includes: 1. Select 2 element combinations from the list, such as ('A','B'), ('A','C'), etc., to avoid repeated order; 2. Take 3 character combinations of strings, such as "abc" and "abd", which are suitable for subsequence generation; 3. Find the combinations where the sum of two numbers is equal to the target value, such as 1 5=6, simplify the double loop logic; the difference between combinations and arrangement lies in whether the order is important, combinations regard AB and BA as the same, while permutations are regarded as different;

Mastering Dependency Injection in Java with Spring and Guice Mastering Dependency Injection in Java with Spring and Guice Aug 01, 2025 am 05:53 AM

DependencyInjection(DI)isadesignpatternwhereobjectsreceivedependenciesexternally,promotingloosecouplingandeasiertestingthroughconstructor,setter,orfieldinjection.2.SpringFrameworkusesannotationslike@Component,@Service,and@AutowiredwithJava-basedconfi

python pytest fixture example python pytest fixture example Jul 31, 2025 am 09:35 AM

fixture is a function used to provide preset environment or data for tests. 1. Use the @pytest.fixture decorator to define fixture; 2. Inject fixture in parameter form in the test function; 3. Execute setup before yield, and then teardown; 4. Control scope through scope parameters, such as function, module, etc.; 5. Place the shared fixture in conftest.py to achieve cross-file sharing, thereby improving the maintainability and reusability of tests.

Troubleshooting Common Java `OutOfMemoryError` Scenarios Troubleshooting Common Java `OutOfMemoryError` Scenarios Jul 31, 2025 am 09:07 AM

java.lang.OutOfMemoryError: Javaheapspace indicates insufficient heap memory, and needs to check the processing of large objects, memory leaks and heap settings, and locate and optimize the code through the heap dump analysis tool; 2. Metaspace errors are common in dynamic class generation or hot deployment due to excessive class metadata, and MaxMetaspaceSize should be restricted and class loading should be optimized; 3. Unabletocreatenewnativethread due to exhausting system thread resources, it is necessary to check the number of threads, use thread pools, and adjust the stack size; 4. GCoverheadlimitexceeded means that GC is frequent but has less recycling, and GC logs should be analyzed and optimized.

How to work with Calendar in Java? How to work with Calendar in Java? Aug 02, 2025 am 02:38 AM

Use classes in the java.time package to replace the old Date and Calendar classes; 2. Get the current date and time through LocalDate, LocalDateTime and LocalTime; 3. Create a specific date and time using the of() method; 4. Use the plus/minus method to immutably increase and decrease the time; 5. Use ZonedDateTime and ZoneId to process the time zone; 6. Format and parse date strings through DateTimeFormatter; 7. Use Instant to be compatible with the old date types when necessary; date processing in modern Java should give priority to using java.timeAPI, which provides clear, immutable and linear

How to Monitor a Java Application with Prometheus and Grafana How to Monitor a Java Application with Prometheus and Grafana Jul 31, 2025 am 09:42 AM

TomonitoraJavaapplicationwithPrometheusandGrafana,firstinstrumenttheappusingMicrometerbyaddingmicrometer-registry-prometheusandSpringBootActuatordependencies,thenexposethe/actuator/prometheusendpointviaconfigurationinapplication.yml.2.SetupPrometheus

See all articles