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