1. 程式人生 > >單例、多例模式&&工廠模式

單例、多例模式&&工廠模式

單例、多例模式

假設,老張開車去東北

public class Car {
    public void run(){      
      System.out.println("冒著煙奔跑中car.........");
    }
}
public class Test {
    public static void main(String[] args) {    
        //如果把new交給司機,那麼司機想new多少car就能有多少。
        Car c=new Car();
        c.run();        
    }
}

想要控制只給老張一輛車,不讓他隨便new出來,可以把Car的建構函式設為private,Car自主生產一個例項,不再依賴於new,封裝一個方法,讓Car定義一個方法返回唯一例項。

單例模式

public class Car {  
    private static Car car=new Car();   //例項
    private Car(){  }   //建構函式私有

    //單例模式的getInstance方法==靜態工廠方法
    public static Car getInstance(){
       return car;  
    }   
    public void run(){
        System.out.println("冒著煙奔跑中car.........");
    }
}

測試:
因為Car的getInstance()方法返回static變數,是同一個例項,所以c1和c2是同一個物件。

public class Test { 
    public static void main(String[] args) {        
        Car c1=Car.getInstance();
        Car c2=Car.getInstance();
        if(c1==c2){
            System.out.print("same car");
        }       
    }
}

如果需要在Car中產生多個例項,不只是一個例項,可以用多例模式。
比如JDBC的連線池,從池中選擇一條連線使用,使用後回收到池中,Connection就是多例

多例模式
在Car中定義List<Car>成員變數

private static List<Car> cars=new ArrayList<Car>();

再把cars初始化,當需要使用的時候,就從cars中選擇一個使用。

工廠模式

new產生例項,如果想對物件的生產過程也能夠進行定製,有好多可擴充套件性,且能封裝生產過程,使用工廠模式

1、簡單工廠模式

//Moveable介面用於實現run
public class Car implements Moveable{
    @Override
    public void run() {
        System.out.print("開汽車\n");
    }
} 
//Moveable介面用於實現run
public class Plane implements Moveable {
    @Override
    public void run() {
        System.out.print("開飛機\n");      
    }
}

工廠

public class CarFactory {
    public Car createCar(){
        return new Car();
    }
}
public class PlaneFactory {
    public Plane createPlane(){
        return new Plane();
    }
}
public class Test { 
    public static void main(String[] args) {
        PlaneFactory planeFactory=new PlaneFactory();
        Plane p=planeFactory.createPlane();//從工廠獲取
        p.run();        
    }
}

簡單工廠模式的工廠可擴充套件性不好,如果想要替換工廠,則換掉的工廠方法也得改,可擴充套件性不好

2、抽象工廠模式

產生交通工具的抽象工廠

public abstract class VehicleFactory {
    abstract Moveable create();
}

繼承自抽象工廠類的具體工廠(子工廠)

public class CarFactory extends VehicleFactory{
    @Override
    Moveable create() {
        return new Car();
    }
}
public class PlaneFactory extends VehicleFactory{
    @Override
    Moveable create() {
        return new Plane();
    }
}
public class Test { 
    public static void main(String[] args) {
        VehicleFactory factory=new PlaneFactory();
        Plane p=(Plane) factory.create();//多型,會隱藏具體實現方法
        p.run();

        factory=new CarFactory();
        Car c=(Car) factory.create();//多型,會隱藏具體實現方法
        c.run();
    }
}

不僅可以控制物件,還可以控制物件的生產過程。
需要修改的只有VehicleFactory factory=new PlaneFactory();,需要生產什麼物件,就new出相應的工廠,如果有配置檔案,連這個都不用修改
這裡寫圖片描述

體會:產生物件的方法,就是工廠方法,不一定侷限於是在哪個位置,是哪個範疇,學習到最後要靈活運用,手中無劍心中有劍

getInstance和Factory在jdk中常用,還有abstractFactory也非常常用

3、配置檔案

對於普通工廠來說,產生產品系列時,會產生工廠氾濫的問題,對於抽象工廠來說,也有一個問題:比如抽象工廠類,當它需要在抽象類中新增或者刪去一個方法(即改變產品時),就需要改動所有繼承自該廠的所有子類的方法,改動的地方太多
spring提供了一種方案:
1、spring提供的是bean工廠(BeanFactory)
2、原先通過new方式得到的例項Bean物件,現在通過配置檔案的配置來配置例項

模擬spring
1、配置檔案spring.properties

VehicleType=com.HL.spring.Train  //  鍵值對

2、通過java的Properties、反射來獲取例項物件

package com.HL.spring;
import java.io.IOException;
import java.util.Properties;
public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {

        //用來讀配置檔案的
        Properties pros=new Properties();
        //Test.class.getClassLoader():拿到裝載類物件的class裝載器,getResourceAsStream:把檔案當成流
        pros.load(Test.class.getClassLoader().getResourceAsStream("com/HL/spring/spring.properties"));

        //獲取key為VehicleType的值
        String vehicleTypeName=pros.getProperty("VehicleType");
        System.out.println(vehicleTypeName);

        //運用java的反射機制,通過字串得到例項
        Object o=Class.forName(vehicleTypeName).newInstance();
        Moveable m=(Moveable)o;
        m.run();    
    }
}

4、Spring

Spring中的運用:使用application.xml作為全域性配置檔案
application.xml中的配置資訊

<Bean id="v" class="com.HL.spring.Car" />

載入配置檔案,用ClassPathXmlApplication

BeanFactory f=new ClassPathXmlApplicationContext("application.xml");//載入配置檔案中配置的Bean類

java解析XML檔案,有多種方法,比如JDOM、SAX等,可以搜尋一下JDOM/XPATH程式設計指南.
spring中載入完xml配置檔案之後,會把配置檔案中宣告的Bean放在List中,然後放進Map中,即Bean容器(IOC),提供給應用程式(程式通過getBean根據id得到Bean),即AOP

Object o=f.getBean("v");//根據id獲取相應ID的Bean例項
Moveable m=(Moveable)o;
m.run();

這就是Bean容器,即IOC。

相關推薦

模式&&工廠模式

單例、多例模式 假設,老張開車去東北 public class Car { public void run(){ System.out.println("冒著煙奔跑中car........."); } } pub

設計模式列舉

單例設計模式:     特徵是構造方法私有化,而後在類的內部提供有一個static本類物件,並且利用static方法取得此物件。   程式碼如下:  class Singleton{private static final Singleton INSTANCE = new

7【C++】模式/工廠模式

一、單例模式     單例模式,可以說設計模式中最常應用的一種模式了,據說也是面試官最喜歡的題目。但是如果沒有學過設計模式的人,可能不會想到要去應用單例模式,面對單例模式適用的情況,可能會優先考慮使用全域性或者靜態變數的方式,這樣比較簡單,也是沒學過設計模式的人所能想到的最簡單的方式了。

模式工廠模式

eight 不同的 name 利用 創建樹 pan cto finall har 單例模式 單例模式的目的就是為了控制特定的類只產生一個對象。 產生單例的步驟: 1、構造方法私有化(在構造方法前面加prevate static finall)為的是不讓其他類創建該類的實例化

自定義註解(三)支付渠道:消除if-策略模式+工廠模式+模式

自定義支付註解=消除if:策略模式+工廠模式+單例模式 程式碼取景,知識來源於視訊《雲析學院【路飛老師】-一次學習終身受用-如何正確使用設計模式寫出優雅的程式碼》 1、定義註解標籤 PayChannel @Target(ElementType.TYPE) @Re

PHP 模式 工廠模式 策略模式程式碼理解

//單個類 單例 <?php /** *單例模式:一個類只能有一個物件 *三私一公 */ class MySQLDB { private static $instance; //私有的成員用來儲存類的例項 private function __construct()

spring詳解的實驗,以及如何使用模式

原文:http://www.tuicool.com/articles/RzIvAj spring生成物件預設是單例的。通過scope屬性可以更改為多例。 <bean id="user" class="modle.User" scope="prototype"&

常用設計者模式---工廠模式模式

從今天起(2017.2.14),我要開始系統認真的啃基礎,堅持下去,每天進步一點點。 一、什麼是設計者模式(what)? 最早提出“設計模式”概念的是建築設計大師亞力山大Alexander。在他的《建築的永恆之道》裡這樣描述:模式是一條由三個部分組成的通用規則:它表示了一個

《JAVA與模式》26天系列—第12天—享元模式=模式+工廠模式+合成模式

享元模式=單例模式+工廠模式+合成模式 單例模式: 保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。 結構圖: 注意多執行緒的單例。 package com.bankht.Flyweight.complex; /** * @author: 特種兵—AK47

設計模式---- 模式 工廠模式 建構函式模式 原型模式 混合模式

單例模式 把描述同一個事物(同一個物件)的屬性和方法放在一個記憶體空間下,起到分組的作用,這樣不同事物之間的屬性即使屬性名相同,相互之間也不會衝突。 在專案中可以使用單例模式來進行模組化開發。 var

模式+工廠模式的c++實現

一、單例 #include <iostream> using namespace std; class Singleton { public: static Singleton& getInst (void) { return s_inst;

模式&工廠模式

單例模式 一、什麼是單例模式 有時候我們會遇到這樣一種情況,一個類只能有一個物件被例項化,這時我們就可以使用單例模式了。 單例模式通過類本身來管理其唯一例項。在設計這個類的時候,讓他只能建立一個例項並提供對此例項的全域性訪問。因此單例模式有兩個

MYSQL密碼找回

skip l數據庫 tar safe tails amp date 成功 ges 1、在單實例的MYSQL數據庫中:killall mysqldmysqld_safe --skip-grant-tables &mysqlupdate mysql.user set p

spring自動註入是還是例如何註入

struts1 contex resolv inject interface struts2 ans 我們 instant 單例多例需要搞明白這些問題: 1. 什麽是單例多例; 2. 如何產生單例多例; 3. 為什麽要用單例多例 4.

Struts2

text 屬性 用戶修改 出現 兩個 容器 pre min 得到 struts2中action是多例的,即一個session產生一個action如果是單例的話,若出現兩個用戶都修改一個對象的屬性值,則會因為用戶修改時間不同,兩個用戶訪問得到的屬性不一樣,操作得出的結果不一樣

day39——線程實線程鎖

sta 提取 修飾 start 解決 也有 pen pro finished python的鎖可以獨立提取出來 1 mutex = threading.Lock() 2 #鎖的使用 3 #創建鎖 4 mutex = threading.Lock() 5 #鎖定 6 mut

java

單個 static 改變 cpu lazy pack out ont 通過 背景:最近在學習韓老師的筆記時候發現不是很了解單例和多例,於是通過網上查找資料的方式去學習。 設計模式:最佳的實踐,是軟件開發人員在軟件開發過程中面臨一般解決方案,也就是開發的經驗總結。 單例模式(

SSM-Spring-05:Spring的bean是還是,怎麽改變?

BE pro font 單例 best prototype pri gpo xxx ------------吾亦無他,唯手熟爾,謙卑若愚,好學若饑------------- Spring的bean是單例的 它在Spring容器初始化的時候創建對象 可

java中的區別

單例 多例 區別 線程 1. 什麽是單例多例:所謂單例就是所有的請求都用一個對象來處理,比如我們常用的service和dao層的對象通常都是單例的,而多例則指每個請求用一個新的對象來處理,比如action; 2. 如何產生單例多例:在通用的SSH中,單例在spring中是默認的,如果要產生多例

springboot默認創建的bean是實還是

comment 多例 bean 什麽 安全問題 管理 mod 意圖 return 轉:https://blog.csdn.net/q1512451239/article/details/53122687 springboot默認創建的bean是單實還是多例 曾經面試