java設計模式淺談(單例模式,模板模式,工廠模式,代理模式)
這篇文章講述的是java設計模式,包括單例模式、工廠模式、代理模式,如有錯誤或不當之處,希望各位大神批評指正。
什麼是設計模式?
設計模式:是指在大量的理論和實踐中總結和理論化之後,優選的程式碼結構、程式設計風格、以及解決問題的思考模式。正如數學中的公式的使用一樣。
包括:
- 單例模式
- 模板模式
- 工廠模式
- 代理模式
- 等等…
單例模式
什麼是單例模式?
單例模式是指,採用某種手段或者方法,保證整個軟體系統中只能存在一個物件的例項,並且該例項只提供建立該物件的方法。
使用情況及優缺點
- 使用情況:當您想控制例項數目,節省系統資源的時候,和一個全域性使用的類頻繁地建立與銷燬的時候
- 優點:節省系統資源的開銷,避免記憶體的重複使用
- 缺點:沒有介面,不能繼承
單例模式的例子
餓漢式
package com.cn.cmc.javadesignstyle;
public class SingletonDemo {
//獲取一個單例的例項
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance() ;
Singleton singleton2 = Singleton.getInstance() ;
System.out.println(singleton1 == singleton2);
singleton1.claim();
}
}
/**
* 單例模式:程式執行中只能存在一個物件的例項
*
* 設計步驟:1. 將構造器私有化,保證外部不能建立
* 2. 初始化例項
* 3. 私有化例項,向外界提供一個返回例項的介面
* 4. 次公共方法必須通過類來呼叫static
*/
class Singleton{
//將構造器私有化
private Singleton(){
}
//在內部初始化一個例項
//惡漢模式:在初始化類的時候直接例項化物件
private static Singleton singleton = new Singleton() ;
//懶漢模式:初始化時候不新建物件,在具體用到的時候在例項化
private static Singleton singleton2 = null ;
//向外部提供一個返回例項方法
//餓漢
public static Singleton getInstance () {
return singleton;
}
}
懶漢式
package com.cn.cmc.javadesignstyle;
public class SingletonDemo {
//獲取一個單例的例項
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance() ;
Singleton singleton2 = Singleton.getInstance() ;
System.out.println(singleton1 == singleton2);
singleton1.claim();
}
}
/**
* 單例模式:程式執行中只能存在一個物件的例項
*
* 設計步驟:1. 將構造器私有化,保證外部不能建立
* 2. 初始化例項
* 3. 私有化例項,向外界提供一個返回例項的介面
* 4. 次公共方法必須通過類來呼叫static
*/
class Singleton{
//將構造器私有化
private Singleton(){
}
//在內部初始化一個例項
//懶漢模式:初始化時候不新建物件,在具體用到的時候在例項化
private static Singleton singleton2 = null ;
//向外部提供一個返回例項方法
public synchronized static Singleton getInstance2(){
if(singleton2 == null){
singleton2 = new Singleton() ;
}
return singleton2 ;
}
}
注:使用懶漢模式時要注意執行緒安全問題,需要使用synchronized來控制進入建立例項方法的執行緒
靜態內部類式
package com.cn.cmc.javadesignstyle;
public class SingletonDemo {
//獲取一個單例的例項
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance() ;
Singleton singleton2 = Singleton.getInstance() ;
System.out.println(singleton1 == singleton2);
}
}
/**
* 單例模式:程式執行中只能存在一個物件的例項
*
* 設計步驟:1. 將構造器私有化,保證外部不能建立
* 2. 初始化例項
* 3. 私有化例項,向外界提供一個返回例項的介面
* 4. 次公共方法必須通過類來呼叫static
*/
class Singleton{
//將構造器私有化
private Singleton(){
}
//靜態內部類方式,在第一次使用時才會載入
private static class SingletonClassInstance{
private static final Singleton instance = new Singleton() ;
}
public static Singleton getInstance(){
return SingletonClassInstance.instance ;
}
}
列舉式
package com.cn.cmc.javadesignstyle;
public class SingletonDemo {
//獲取一個單例的例項
public static void main(String[] args) {
Singleton singleton1 = Singleton.INSTANCE ;
Singleton singleton2 = Singleton.INSTANCE ;
System.out.println(singleton1 == singleton2);
}
}
/**
* 單例模式:程式執行中只能存在一個物件的例項
*
* 設計步驟:1. 將構造器私有化,保證外部不能建立
* 2. 初始化例項
* 3. 私有化例項,向外界提供一個返回例項的介面
* 4. 次公共方法必須通過類來呼叫static
*/
enum Singleton{
//列舉類本身就是單例
INSTANCE ;
//相關操作
public void operator(){
System.out.println("操作...");
}
}
單例模式總結
- 餓漢式自身執行緒安全,呼叫高效但不支援延遲載入
- 懶漢式需要synchronized保證執行緒安全,支援懶載入但呼叫低效
- 靜態內部類方式自身執行緒安全,支援懶載入且效率高效
列舉式自身執行緒安全,編寫方便效率高效但不支援懶載入
選用時:若佔用資源少,不需要懶載入,列舉式好於餓漢式
若佔用資源多,需要懶載入時,靜態內部類式要好於懶漢式
模板模式
什麼是模板模式
在模板模式(Template Pattern)中,一個抽象類公開定義了執行它的方法的方式/模板。它的子類可以按需要重寫方法實現,但呼叫將以抽象類中定義的方式進行。這種型別的設計模式屬於行為型模式。
使用情況及優缺點
- 使用情況:一些方法通用,卻在每一個子類都重新寫了這一方法。
- 優點: 封裝不變部分,擴充套件可變部分。 提取公共程式碼,便於維護。 行為由父類控制,子類實現。
- 缺點:每一個不同的實現都需要一個子類來實現,導致類的個數增加,使得系統更加龐大。
模板模式的例子
package com.cn.cmc.javadesignstyle;
/**
* 模板模式:父類只規定有什麼通用方法,具體的實現交給子類來執行
*
* 設計步驟:1. 將父類定義為抽象類
* 2. 將父類的方法定義為抽象方法
* 3.子類在繼承父類時實現具體的方法
*/
//將父類定義為抽象類
abstract class Template{
//將父類中的方法定義為抽象方法
abstract void begin() ;
abstract void say() ;
abstract void end() ;
}
//子類在繼承模板類時實現具體的方法
class Cat extends Template{
void begin() {
System.out.println("我是一隻貓");
}
void say() {
System.out.println("喵喵喵~");
}
void end() {
System.out.println("說完了");
}
}
class Dog extends Template{
void begin() {
System.out.println("我是一隻狗");
}
void say() {
System.out.println("汪汪汪!");
}
void end() {
System.out.println("說完了");
}
}
public class TemplatePattern {
public static void main(String[] args) {
//建立實現模板方法的類
Cat cat = new Cat() ;
Dog dog = new Dog() ;
cat.begin();
cat.say();
cat.end();
dog.begin();
dog.say();
dog.end();
}
}
工廠模式
什麼是工廠模式?
工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。
使用情況及優缺點
- 使用情況:定義一個建立物件的介面,讓其子類自己決定例項化哪一個工廠類,工廠模式使其建立過程延遲到子類進行。
- 優點:一個呼叫者想建立一個物件,只要知道其名稱就可以了。 擴充套件性高,如果想增加一個產品,只要擴充套件一個工廠類就可以。 遮蔽產品的具體實現,呼叫者只關心產品的介面。
- 缺點:每次增加一個產品時,都需要增加一個具體類和物件實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。
工廠模式的例子
簡單工廠模式
package com.cn.cmc.singleton;
/**
* 工廠模式:定義一個建立類的介面,並讓其子類決定實現哪個工廠類,使建立者和呼叫者分離
* 簡單工廠模式:對於同一等級結構的任一產品,對於新增加的產品需要修改已有程式碼
* 工廠方法模式:用來生產同一等級結構中的任一產品,對於新增加的產品支援
* 抽象工廠模式:用來生產不同產品族的全部產品
*
* 設計步驟:1.定義工廠類
* 2.定義建立類的介面
*/
/*工廠類*/
class AnimalFactory {
//工廠介面中只寫獲取類的方法
public static Sheep createSheep(){
return new Sheep() ;
}
public static Cow createCow(){
return new Cow() ;
}
}
/*介面類*/
interface Animal {
public void cry() ;
}
/*實現類*/
class Cow implements Animal{
public void cry() {
System.out.println("哞哞哞~");
}
}
class Sheep implements Animal{
public void cry(){
System.out.println("咩咩咩~");
}
}
public class SimpleFactory {
public static void main(String[] args) {
//工廠模式建立物件
Sheep sheep = AnimalFactory.createSheep() ;
Cow cow = AnimalFactory.createCow() ;
sheep.cry();
cow.cry();
}
}
工廠方法模式
package com.cn.cmc.factory;
/**
* 工廠模式:定義一個建立類的介面,並讓其子類決定實現哪個工廠類,使建立者和呼叫者分離
* 簡單工廠模式:對於同一等級結構的任一產品,對於新增加的產品需要修改已有程式碼
* 工廠方法模式:用來生產同一等級結構中的任一產品,對於新增加的產品支援
* 抽象工廠模式:用來生產不同產品族的全部產品
*
* 設計步驟:1.定義工廠類
* 2.定義建立類的介面
*/
/*工廠類*/
class AnimalFactory {
//工廠介面中只寫獲取類的方法
public static Sheep createSheep(){
return new Sheep() ;
}
public static Cow createCow(){
return new Cow() ;
}
}
/*介面類*/
interface Animal {
public void cry() ;
}
/*實現類*/
class Cow implements Animal{
public void cry() {
System.out.println("哞哞哞~");
}
}
class Sheep implements Animal{
public void cry(){
System.out.println("咩咩咩~");
}
}
public class SimpleFactory {
public static void main(String[] args) {
//工廠模式建立物件
Sheep sheep = AnimalFactory.createSheep() ;
Cow cow = AnimalFactory.createCow() ;
sheep.cry();
cow.cry();
}
}
抽象工廠模式
package com.cn.cmc.factory;
public class AbstractFactory {
/**
* 抽象工廠模式:提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。
* 系統的產品有多於一個的產品族,而系統只消費其中某一族的產品時使用。
*/
public static void main(String[] args) {
Engine e = new LuxuryCarFactory().createEngine() ;
Tyre t = new LuxuryCarFactory().createTyre() ;
Seat s = new LuxuryCarFactory().createSeat() ;
e.run();
e.start();
t.revolve();
s.feel();
}
}
/*高階車生產工廠*/
class LuxuryCarFactory implements CarFactory{
@Override
public Seat createSeat() {
return new LuxurySeat();
}
@Override
public Tyre createTyre() {
return new LuxuryTyre();
}
@Override
public Engine createEngine() {
return new LuxuryEngine();
}
}
/*低端車生產工廠*/
class LowCarFactory implements CarFactory{
@Override
public Seat createSeat() {
return new LowSeat();
}
@Override
public Tyre createTyre() {
return new LowTyre();
}
@Override
public Engine createEngine() {
return new LowEngine();
}
}
/*汽車抽象工廠類*/
interface CarFactory{
Seat createSeat() ;
Tyre createTyre() ;
Engine createEngine() ;
}
/*座椅介面*/
interface Seat{
void feel() ;
}
/*座椅實現類-高階*/
class LuxurySeat implements Seat{
@Override
public void feel() {
System.out.println("高階座椅十分舒適");
}
}
/*座椅實現類-低端*/
class LowSeat implements Seat{
@Override
public void feel() {
System.out.println("低端座椅不舒服");
}
}
/*輪胎介面*/
interface Tyre{
void revolve() ;
}
/*輪胎實現類-高階輪胎*/
class LuxuryTyre implements Tyre{
@Override
public void revolve() {
System.out.println("高階輪胎不易磨損");
}
}
/*輪胎實現類-低端輪胎*/
class LowTyre implements Tyre{
@Override
public void revolve() {
System.out.println("低端輪胎易磨損");
}
}
/*引擎介面*/
interface Engine {
void run() ;
void start() ;
}
/*引擎實現類-高階*/
class LuxuryEngine implements Engine{
@Override
public void run() {
System.out.println("高階引擎馬力大");
}
@Override
public void start() {
System.out.println("高階引擎轉速快");
}
}
/*引擎實現類-低端*/
class LowEngine implements Engine{
@Override
public void run() {
System.out.println("低端引擎馬力小");
}
@Override
public void start() {
System.out.println("低端引擎轉速慢");
}
}
工廠模式之間的對比
- 簡單靜態工廠模式:雖然不符合設計原則,但用的最多
- 工廠方法模式:可以通過不修改原有類的前提下實現對類的擴充套件
- 抽象工廠模式:不可以增加單個產品,但可以增加產品族,大專案用的多
代理模式
什麼是代理模式
為其他物件提供一種代理以控制對這個物件的訪問。
使用情況及優缺點
- 使用情況:想在訪問一個類時做一些控制。如安全代理,遠端載入,延遲載入
- 優點:職責清晰、高擴充套件性、智慧化。
- 缺點:由於在客戶端和真實主題之間增加了代理物件,因此有些型別的代理模式可能會造成請求的處理速度變慢。而且實現代理模式需要額外的工作,有些代理模式的實現非常複雜。
代理模式的例子
靜態代理
- 模擬客戶找代理買手機
package com.cn.cmc.proxy;
public class StaticProxy {
public static void main(String[] args) {
//模擬客戶找代理買一臺蘋果手機
IPhone iphone = new IPhone() ;
PhoneProxy phoneproxy = new PhoneProxy(iphone) ;
phoneproxy.look();
phoneproxy.tryout();
phoneproxy.consult();
phoneproxy.buy();
phoneproxy.bill();
}
}
/*手機介面*/
interface Phone {
public void look();
public void tryout();
public void consult() ;
public void buy() ;
public void bill() ;
}
/*手機代理類*/
class PhoneProxy implements Phone{
private Phone phone ;
public PhoneProxy(Phone phone) {
super();
this.phone = phone;
}
@Override
public void look() {
System.out.println("代理看手機");
}
@Override
public void tryout() {
System.out.println("代理試用手機");
}
@Override
public void consult() {
System.out.println("代理諮詢手機效能");
}
@Override
public void buy() {
phone.buy();
}
@Override
public void bill() {
System.out.println("代理要發票");
}
}
/*手機類*/
class IPhone implements Phone {
@Override
public void look() {
System.out.println("蘋果店裡看手機");
}
@Override
public void tryout() {
System.out.println("蘋果店裡試用手機");
}
@Override
public void consult() {
System.out.println("蘋果店裡諮詢手機");
}
@Override
public void buy() {
System.out.println("蘋果店裡買手機");
}
@Override
public void bill() {
System.out.println("蘋果店裡要發票");
}
}
動態代理
package com.cn.cmc.proxy;
import java.awt.PageAttributes;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKDynamicProxy {
public static void main(String[] args) {
Phone iphone = new IPhone() ;
PhoneHandler phonehandler = new PhoneHandler(iphone) ;
/*建立一個代理
* classloader:類載入器
* class[]:要代理的Class陣列
* handler:代理要實現的Handler
* */
Phone proxy = (Phone) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Phone.class}, phonehandler) ;
proxy.buy();
}
}
/*手機代理類*/
class PhoneHandler implements InvocationHandler{
Phone phone ;
public PhoneHandler(Phone phone) {
super();
this.phone = phone;
}
/**
* invoke為呼叫真正的方法
* proxy:為在其上呼叫方法的代理例項
* method:對應於在代理例項上呼叫的介面方法的 Method 例項
* args:包含傳入代理例項上方法呼叫的引數值的物件陣列
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理開始買手機");
if(method.getName().equals("look")){
phone.look();
}else if(method.getName().equals("tryout")){
phone.tryout();
}else if(method.getName().equals("consult")){
phone.consult();
}else if(method.getName().equals("buy")){
phone.buy();
}else if(method.getName().equals("bill")){
phone.bill();
}else{
System.out.println("沒有此方法");
}
System.out.println("代理買手機結束");
return null;
}
}
/*手機介面*/
interface Phone {
public void look();
public void tryout();
public void consult() ;
public void buy() ;
public void bill() ;
}
/*手機類*/
class IPhone implements Phone {
@Override
public void look() {
System.out.println("蘋果店裡看手機");
}
@Override
public void tryout() {
System.out.println("蘋果店裡試用手機");
}
@Override
public void consult() {
System.out.println("蘋果店裡諮詢手機");
}
@Override
public void buy() {
System.out.println("蘋果店裡買手機");
}
@Override
public void bill() {
System.out.println("蘋果店裡要發票");
}
}
相關推薦
java設計模式淺談(單例模式,模板模式,工廠模式,代理模式)
這篇文章講述的是java設計模式,包括單例模式、工廠模式、代理模式,如有錯誤或不當之處,希望各位大神批評指正。 什麼是設計模式? 設計模式:是指在大量的理論和實踐中總結和理論化之後,優選的程式碼結構、程式設計風格、以及解決問題的思考模式。正如數學中的公
Java設計模式學習筆記(單例模式)
最近一直在看《Head First設計模式》,這本書寫的確實是很不錯的,專注於怎麼用最簡單的方式最通俗的語言讓人瞭解設計模式。據說GoF的設計模式那本書寫的很好,是一本經典,但是就是難懂,這本書應該就是我們這些一看經典書就困的人的寶貝了。 不過Head First系列並不專注於
java設計模式---淺談2種工廠模式和單例模式
1、 工廠模式 。比如有一個統一介面 A ,這個A介面是一個標準 。如果有類 B 和 C 那麼 BC必須實現A介面 。 我們在以往的 方法生成這種物件的時候 A b=new B() ; A c=new C() ;這樣的方式來的 .但是如果不同的
java 設計模式(單例,享元,策略)
讀書不覺已春深,一寸光陰一寸金。 java的設計模式大體上分為三大類: 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。
【JAVA】基礎:設計模式(單例設計模式,工廠設計模式)
設計模式:解決某一類問題最行之有效的方法。 java中有23種設計模式。 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。 行為型模式(11種):策略模式、模板方法
java中幾種設計模式(單例模式,介面卡模式,簡單工廠模式)
1、單例模式:也分餓漢式單例模式(建立物件)與懶漢式單例模式(未建立物件)程式碼實現:餓漢式單例模式:懶漢式單例模式:2、介面卡模式:介面:實現介面的類:實現介面某個方法的類:3、簡單工廠模式:介面:類1:類2:工廠類:測試類:
Java---設計模式(單例變形)多例
★ 快取在單例中的使用(“單例+快取”技術) 快取在程式設計中使用很頻繁,有著非常重要的作用,它能夠幫助程式實現以空間換取時間,通常被設計成整個應用程式所共享的一個空間,現要求實現一個用快取存放單例物
JAVA 中類如何只實例化一次(單例模式)
回來 記錄 實例 static ret clas 實例化 best pub 以前只運用過單例模式,但是沒有具體的了解過單例模式的含義,今天去面試讓一下一個類只實例化一次,想了好久沒想出來,回來查了資料才知道是單例模式,記錄下來。public class Singleton
創建型設計模式(單例模式)
創建型設計模式 true 自己 singleton span 創建 final 調用 ati 單例模式有以下特點: 1、單例類只能有一個實例。 2、單例類必須自己創建自己的唯一實例。 3、單例類必須給所有其他對象提供這一實例。 一、懶漢式單例 //懶漢式單例類.在第
JAVA-初步認識-第八章-單例設計模式-概述體現
產生 比較 23種設計模式 設計 兩種 數據類型 計算機 一個 java (本節講述的知識點,有像更新,一個變化,另一個也同時變化) 一. 接下來是比較重要的一部分知識點-設計模式。 設計模式的定義,從字面來看就是設計時的統一規範。 java有23種設計模式,也可以用於C
添磚加瓦:設計模式(單例模式)
argv pri 方法 職責 ger 資源管理 存在 優缺點 names 1、單例定義及要素 定義: 保證一個類只有一個實例存在,同時提供能對該實例加以訪問的全局訪問方法(GoF中單例模式的定義)。 要素: (1)某個類只能有一個實例 (2)必須自行
單態(單例)設計模式
autoloat 單態設計模式一、二、最終結果是只得到一個對象 1、不能讓用戶在外面new----->封裝構造方法 2、一個對象都得不到---->提供一個方法用來得到對象 3、普通的方法在外部無法訪問--->static靜態方法用來在外部直接訪問方法的作用,使用s
Java設計模式透析之 —— 單例(Singleton)
too 不能 占用內存 有道 機會 title bugs 功能 就是 轉載請註明出處:http://blog.csdn.net/guolin_blog/article/details/8860649 寫軟件的時候經常需要用到打印日誌功能,可以幫助你調試和定位問題,項目上
設計模式:對象生成(單例、工廠、抽象工廠)
添加 對象實例 log return ray 靜態 學習 線程 tco 對象的創建有時會成為面向對象設計的一個薄弱環節。我們可以使用多種面向對象設計方案來增加對象的創建的靈活性。 單例模式:生成一個且只生成一個對象實例的特殊類 工廠方法模式:構建創建者類的繼承層級
Java併發程式設計中的設計模式解析(二)一個單例的七種寫法
Java單例模式是最常見的設計模式之一,廣泛應用於各種框架、中介軟體和應用開發中。單例模式實現起來比較簡單,基本是每個Java工程師都能信手拈來的,本文將結合多執行緒、類的載入等知識,系統地介紹一下單例模式的演變,並體現在7種不同的單例設計中。說到這個,非常像孔乙己裡那個“回字有四種寫法”的梗,不過與封建迂腐
單例模式新談(包含三種方式)
設計模式是一套被反覆使用,多數人知曉,經過分類編目的,程式碼設計的總結,也可以說是前人的智慧結晶。學習設計模式能讓我們對一些應用場景使用相同的套路達到很好的效果,我會不定時更新一些自己對設計模式的理解的文章,從定義,實現,應用場景來說說設計模式,今天我要說的物件是單例模式一,定義 什麼是單例模式,字面理
路一步步走>> 設計模式五:Singleton-單例(單件)
package com.test.DPs.ChuangJian.Singleton; /** * 建立型:Singleton-單例(單件) * * 單例模式-Singleton * 用途:保證一個類僅有一個例項,並提供一個訪問他的全域性訪問點。 */ public class Si
設計模式之三:單例模式(餓漢式與懶漢式)
//保證類在記憶體中只有一個物件 package com.xjh.demo.designpattern.pattern3; public class Student { private Student(){ } //懶漢式 priva
python單例模式淺談
單例模式 單例模式(Singleton Pattern)是一種常用的軟體設計模式,該模式的主要目的是確保某一個類只有一個例項存在。當你希望在整個系統中,某個類只能出現一個例項時,單例物件就能派上用場。 比如,某個伺服器程式的配置資訊存放在一個檔案中,客戶端通過一個 AppConf
javaSE (三十八)設計模式 ( 單例設計模式(餓漢式/懶漢式)、簡單工廠模式、工廠模式、介面卡模式、模板方法設計模式)
1、單例設計模式(餓漢式/懶漢式): 概念:保證類在記憶體中只有一個物件 思路: 私有構造方法,其他類不能再訪問該構造方法了 建立本類物件(就在本類裡建立),將物件的應用作為成員變數,並私有靜態化(在這裡又分為餓漢式和懶漢式,餓漢式直接引用連線物件,而懶漢式在第二步先建