1. 程式人生 > >Java-6種常用的設計模式

Java-6種常用的設計模式

一.單例模式

(一)要點

1.某個類只有一個例項
2.它必須自行建立物件
3.它必須自行向整個系統提供這個例項

(二)實現單例模式要注意以下幾點

1.私有的構造方法。保證外部無法建立例項。
2.私有的靜態的型別引用。因為靜態就可以保證只有一個變數引用
3.提供獲取例項的方法。方法名一般為getInstance()。

(三)兩種實現方式

1.單例模式之懶漢式

優點:需要物件的時候才建立。
缺點:執行緒不安全(可以在獲取物件的方法申明上用synchronized修飾來保證執行緒安全)
在這裡插入圖片描述

單例模式之惡漢式

優點:實現簡單。
缺點:在不需要的時候,白建立了物件,造成資源浪費
在這裡插入圖片描述

二.簡單工廠模式

(一)目的

提供一個統一建立物件的場所

(二)實質

簡單工廠模式的實質是由一個工廠類根據傳入的引數,動態的決定應該建立哪一個產品類的例項,並且這些產品類繼承自一個父類或介面

(三)要點

(1)工廠(Factory)角色。它是簡單工廠模式的核心,它負責實現建立所有例項的內部邏輯。工廠類可以被外界直接呼叫,建立所需的產品物件。
(2)抽象(Product)角色。簡單工廠模式建立物件所屬類的父類,它負責描述所有例項所共有的公共介面。
(3)具體產品角色。是簡單工廠模式的建立目標,是一個具體的例項物件

(四)例子

在這裡插入圖片描述
在這裡插入圖片描述

三.工廠方法模式

(一)概述

簡單工廠模式是工廠模式中最簡單的一種,它在應對產品類別比較多的時候,往往力不從心,因此就有了工廠方法模式的出現。
工廠方法模式是簡單工廠模式的衍生,解決了許多簡單工廠模式的問題。完全實現“開閉原則”。其次更復雜的層次結構,可以應用於產品結構複雜的場合。

(二)原理

工廠方法模式對簡單工廠模式進行了抽象。有一個抽象的Factory類(可以是抽象類或者介面),這個類將不再負責具體的產品生產,而是隻制訂一些規範(也就是申明一些抽象方法),具體的生產工作由其子類去完成。在這個模式中,工廠類和產品類可以一一對應。即一個抽象工廠對應一個抽象產品,一個具體工廠對應一個具體產品

(三)

在這裡插入圖片描述


在這裡插入圖片描述

四.抽象工廠方法模式

(一)概述

如果抽象角色不止一個時,也就是工廠需要造出多種產品(這些產品是有聯絡的)的時候,簡單工廠模式和工廠方法模式就不太應付得了。此時,就需要使用抽象工廠方法模式了,它就是為了專門應對多種抽象產品而設計的。

(二)原理

當每個抽象產品都有多於一個的具體子類的時候,工廠角色怎麼知道例項化哪一個類呢?如每個抽象產品角色都有兩個具體產品。其實,抽象工廠模式提供兩個具體工廠角色,分別對應著兩個具體產品角色,每一個具體工廠角色只負責某一個產品角色的例項化。每一個具體工廠類只負責建立某一具體子類的例項。例如一個抽象的汽車工廠可以生產汽車及其配套的輪子,它的子類工廠是轎車工廠和卡車工廠,轎車工廠可以生產轎車和轎車輪子,卡車工廠可以生產卡車和卡車輪子。

(三)程式碼

abstract class Auto {//車類
}
class Car extends Auto{//轎車類
}
class Truck extends Auto{//卡車類
}
abstract class Wheel{//抽象的輪胎類
    
}
class Carwheel extends Wheel{//汽車輪胎
    
}
class Truckwheel extends Wheel{//卡車輪胎
    
}
interface createWheelAble{
    public abstract Wheel createWheel();
}
abstract class AutoFactory implements createWheelAble{
    public abstract Auto createAuto();//建立一個汽車的抽象方法
    public abstract Wheel createWheel();//建立一個輪胎的抽象方法
}
class Carfactory extends AutoFactory{

    @Override
    public Auto createAuto() {
        return new Car ();
    }

    @Override
    public Wheel createWheel() {
        return new Carwheel ();
    }
}
class Truckfactory extends AutoFactory{

    @Override
    public Auto createAuto() {
        return new Truck ();
    }

    @Override
    public Wheel createWheel() {
        return new Truckwheel ();
    }
}

接下來看看如何生產
在這裡插入圖片描述

五.觀察者模式

(一)概述

觀察者模式有稱為監聽者模式,它廣泛的應用於圖形化程式設計中。例如,當用戶單擊某個按鈕的時候,應該做出什麼響應;當商城打折的時候,應該通過E-mail和電話等形式通知消費者。

(二)實現

實現觀察者模式有很多方式,比較直觀的一種是使用“註冊,通知,撤銷註冊”的形式,大致過程如下:
1.觀察者(Observer)將自己註冊到被觀察者物件(Subject)中,被觀察者物件將觀察者存放在一個容器(Container)中.
2.被觀察物件發生了某種變化(如按鈕被單擊,商品價格發生變化等),從容器中得到所有註冊過的觀察者,將變化通知給觀察者。在程式碼中,需要做的就是遍歷容器中的觀察者,呼叫他們的回撥方法。
3.觀察者告訴被觀察者要撤銷觀察,被觀察者從容器中將觀察者去除。

(三)程式碼

package com.westos.mydemo.demo4;

import java.util.HashSet;

public class ObserverPattern {
    public static void main(String[] args) {
        Product product = new Product ( "OPPO-r9", 1140 );
        WebObserver webObserver = new WebObserver ( );//第一個觀測者
        MailObserver mailObserver = new MailObserver ( );//第二個觀測者
        product.addObserver ( webObserver );
        product.addObserver ( mailObserver );
        System.out.println ("===第一次價格改動===" );
        product.setPrice ( 1056 );
        webObserver.unreg ( product );   //網頁觀察者取消觀察
        System.out.println ("===第二次價格改動===" );
        product.setPrice ( 998 );
    }
}

interface Observer{//觀察者介面
    public void update(Product product);
    public void unreg(Product product);
}
class WebObserver implements Observer{

    @Override
    public void update(Product product) {
        System.out.println ("通過網頁為所有會員傳送價格變化訊息:"+product.getName ()+":"+product.getPrice ());
    }

    @Override
    public void unreg(Product product) {
        product.getObservers ().remove ( this );
    }
}
class MailObserver implements Observer{

    @Override
    public void update(Product product) {
        System.out.println ("通過Mail為所有會員傳送價格變化訊息:"+product.getName ()+":"+product.getPrice ());
    }

    @Override
    public void unreg(Product product) {
        product.getObservers ().remove ( this );
    }
}
class Product{//產品類,被觀察者
    private double price;//價格
    private String name;//商品名稱
    private HashSet<Observer> observers;//存放觀察者物件

    public Product( String name,double price) {
        this.price = price;
        this.name = name;
        observers=new HashSet < Observer> ( );
    }
    public void addObserver( Observer observer){//新增觀察者
        observers.add ( observer );
    }
    public void notifyObserver(){
        for (Observer observer : observers) {
            observer.update ( this );
        }
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
        //當價格改變時通知觀察者
        notifyObserver ();
    }

    public String getName() {
        return name;
    }

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

    public HashSet <Observer> getObservers() {
        return observers;
    }

    public void setObservers(HashSet <Observer> observers) {
        this.observers = observers;
    }

}

在這裡插入圖片描述

六.模版設計模式

(一)概述

模版方法模式就是定義一個演算法的骨架,而將具體的演算法延遲到子類中來實現

(二)優缺點

優點:使用模版方法模式,在定義演算法骨架的同時,可以很靈活的實現具體的演算法,滿足使用者靈活多變的需求
缺點:如果演算法骨架有修改的話,則需要修改抽象類

(三)程式碼

public abstract class CalcTime {
    //計算耗時的方法
    public long getTime(){
        long begin = System.currentTimeMillis();
        testTime();
        long end = System.currentTimeMillis();
        return end-begin;
    }

    public abstract void  testTime();
}
public class TestFor extends CalcTime{
    @Override
    public void testTime() {
        for (int i = 0; i < 10000; i++) {
            System.out.println();
        }
    }
}
public class Test4 {
    public static void main(String[] args) {
    	long time = new TestFor().getTime();
        System.out.println(time);
    }
}