Spring 實現兩種設計模式:工廠模式和單態模式
本文摘自:李剛 著 《輕量級 Java EE企業應用實戰 Struts2+Spring+hibernate整合開發》
在Spring 中大量使用的以下兩種設計模式:工廠模式和單態模式。
工廠模式可將Java 物件的呼叫者從被呼叫者的實現邏輯中分離出來,呼叫者只需關心被呼叫者必須滿足的規則(介面) ,而不必關心例項的具體實現過程。這是面向介面程式設計的優勢,能提高程式的解耦,避免所有的類以硬編碼方式耦合在一起。
如果所有的類直接耦合,極易形成"骨牌效應",假如B 類呼叫了A 類,一旦A 類需要修改,則B 類也需要修改;假如C 類呼叫了B 類,則C 類也需要修改......依次類推,從而導致整個系統都需要改寫。造成"牽一髮而動全身",而系統重構的代價是相當高的。
Spring 倡導”面向介面程式設計“,可以避免上述的問題,使設計良好的架構可保證系統重構的工作被封閉在重構的層內,絕不會影響其他層。
Spring 容器是例項化和管理全部bean 的工廠,Spring 預設將所有的bean 設定成單態模式,無須自己完成單態模式,即對所有相同id 的bean 請求都將返回同一個共享例項。因此,單態模式可大大降低Java 物件在建立和銷燬時的系統開銷。
一. 單態模式的回顧
單態模式限制了類例項的建立,但採用這種模式設計的類,可以保證僅有一個例項,並可提供訪問該例項的全域性訪問點。J2EE應用的大量元件,都需要保證一個類只有一個例項。
更多的時候,為了提高效能,程式應儘量減少Java 物件的建立和銷燬時的開銷。使用單態模式可避免Java 類被多次例項化,讓相同類的全部例項共享同一記憶體區。
為了防止單態模式的類被多次例項化,應將類的構造器設成私有,這樣就保證了只能通過靜態方法獲得類例項。而該靜態方法則保證每次返回的例項都是同一個,這就需將該類的例項設定成類屬性,由於該屬性需要被靜態方法訪問,因此該屬性應設成靜態屬性。
下面給出單態模式的示例程式碼:
package ppp; //單態模式測試類 public class SingletonTest { //該類的一個普通屬性 int value; //使用靜態屬性儲存該類的一個例項 private static SingletonTest instance; //構造器私有化,避免該類被多次例項化 private SingletonTest(){ System.out.println("正在執行構造器..."); } //提供靜態方法返回該類例項 public static SingletonTest getInstance(){ //例項化類例項前,先檢查該例項是否存在 if(instance == null){ //如果不存在,則新建一個例項 instance = new SingletonTest(); } //返回該類的成員變數:該類的例項 return instance; } //以下提供對普通屬性value的getter和setter方法 public int getValue(){ return value; } public void setValue(int values){ this.value = values; } public static void main(String args[]){ SingletonTest t1 = SingletonTest.getInstance(); SingletonTest t2 = SingletonTest.getInstance(); t2.setValue(9); System.out.println(t1 == t2); } }
從程式最後的列印結果可以看出,該類的兩個例項完全相同。這證明單態模式類的全部例項是同一共享例項。程式裡雖然獲得了類的兩個例項,但實際上只執行一次構造器,因為對於單態模式的類,無論有多少次的建立例項請求,都只執行一次構造器。
二. 工廠模式的回顧
工廠模式是根據呼叫資料返回某個類的一個例項,此類可以是多個類的某一個類。通常,這些類滿足共同的規則(介面)或父類。呼叫者只關心工廠生產的例項是否滿足某種規範,即實現的某個介面是否可供自己正常呼叫(呼叫者僅僅使用)。該模式給物件之間作出了清晰的角色劃分,降低程式的耦合。
介面產生的全部例項通常用於實現相同介面,接口裡定義了全部例項共同擁有的方法,這些方法在不同的實現類中實現的方式不同。從而使程式呼叫者無須關心方法的具體實現,降低了系統異構的代價。
下面是工廠模式的示例程式碼:
package ppp;
//Person介面定義
public interface Person {
public String sayHello(String name);
public String sayGoodbye(String name);
}
該介面定義了Person規範,規範要求實現該介面的類必須具有以下兩個的方法:能打招呼,能告別。
package ppp;
//American類實現Person介面
public class American implements Person {
public String sayHello(String name){
return name+",hello";
}
public String sayGoodbye(String name)
{
return name+",goodbye";
}
}
下面是Person類的另一個實現類:Chinese
package ppp;
//Chinese類實現Person介面
public class Chinese implements Person {
public String sayHello(String name){
return name+",您好";
}
public String sayGoodbye(String name)
{
return name+",下次再見";
}
}
然後再看Person工廠的程式碼:
package ppp;
public class PersonFactory {
public Person getPerson(String ethnic)
{
if(ethnic.equalsIgnoreCase("chin"))
{
return new Chinese();
}else{
return new American();
}
}
}
以上是最簡單的工廠模式框架,其主程式如下:
package ppp;
public class FactoryTest {
public static void main(String[] args){
//建立PersonFactory例項 ,獲得工廠例項
PersonFactory pf = new PersonFactory();
//定義介面Person例項,面向介面程式設計
Person p = null;
//使用工廠獲得person例項
p = pf.getPerson("chin");
//下面呼叫Person介面方法
System.out.println(p.sayHello("wawa"));
System.out.println(p.sayGoodbye("wawa"));
//使用工廠獲得Person的另一個例項
p = pf.getPerson("ame");
//再次呼叫Person介面的方法
System.out.println(p.sayHello("wawa"));
System.out.println(p.sayGoodbye("wawa"));
}
}
由此可看出,主程式從Person 介面的具體類中解耦出來,而且程式呼叫者無須關心Person 的例項化過程,主程式僅僅與工廠服務定位結合在一起,可獲得所有工廠能產生的例項。具體類的變化,介面無須發生任何改變,呼叫者程式程式碼部分也無須發生任何改動。
下面是Spring 對這兩種模式的實現。
三. Spring 對單態與工廠模式的實現
隨著Spring 提供工廠模式的實現,在使用Spring 時,無須自己提供工廠類。因為Spring容器是最大的工廠,而且是個功能超強的工廠。Spring 使用配置檔案管理所有的bean ,其配置檔案中bean 由Spring 工廠負責生成和管理。
下面是關於兩個例項的配置檔案:
<!--下面是xml檔案的檔案頭-->
<?xml version = "1.0" encoding = "gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springsource.org/dtd/spring-beans.dtd">
<!--beans是Spring配置檔案的根元素-->
<beans>
<!--定義第一個bean,該bean的id是chinese-->
<bean id = "chinese" class = "ppp.Chinese"/>
<!--定義第二個bean,該bean的id是American-->
<bean id = "american" class = "ppp.American"/>
</beans>
主程式部分如下:
package ppp;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class SpringTest {
public static void main(String[] args) {
//例項化Spring容器
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
//定義Person介面例項
Person p = null;
//通過Spring上下文獲得Chinese例項
p = (Person)ctx.getBean("chinese");
//執行chinese例項的方法
System.out.println(p.sayHello("wawa"));
System.out.println(p.sayGoodbye("wawa"));
p = (Person)ctx.getBean("american");
System.out.println(p.sayHello("wawa"));
System.out.println(p.sayGoodbye("wawa"));
}
}
使用Spring 時,即使沒有工廠類PersonFactory ,程式一樣可以使用工廠模式, Spring完全可以提供所有工廠模式的功能。
下面對主程式部分進行簡單的修改:
package ppp;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class SpringTest{
public static void main(String[] args){
//例項化Spring容器
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
//定義p1介面的例項p1
Person p1 = null;
//通過Spring上下文獲得Chinese例項
p1 = (Person)ctx.getBean("Chinese");
//定義p2介面的例項p2
Person p2 = null;
p2 = (Person)ctx.getBean("Chinese");
System.out.println(p1 == p2);
}
}
程式的執行結果是:true
表明Spring對接受容器管理的全部的bean,預設採用單態模式管理,建議不要隨意更改bean的行為方式。因為從效能上講,單態的bean比非單態的bean效能更為優秀。
仔細檢查上面的程式碼就會發現如下的特點;
(1)除測試部分的主程式外,程式碼並未出現Spring的特定類和介面。
(2)呼叫者的程式碼,也就是測試用的主程式部分,僅僅面向Person的介面程式設計,而無需知道實現類的具體名稱。同時,通過修改配置檔案來徹底切換底層的具體實現類。
(3)由於廠無需多個例項,因此工廠應該採用單態模式設計,其中Spring上下文也就是Spring工廠,已被設計成單態。
Spring工廠模式,不僅提供了建立bean的功能,還提供了對bean的生命週期的管理。最重要的是還以管理bean和bean之間的依賴關係。
相關推薦
Spring 實現兩種設計模式:工廠模式和單態模式
本文摘自:李剛 著 《輕量級 Java EE企業應用實戰 Struts2+Spring+hibernate整合開發》 在Spring 中大量使用的以下兩種設計模式:工廠模式和單態模式。 工廠模式可將Java 物件的呼叫者從被呼叫者的實現邏輯中分離出來,呼
Spring實現兩種設計模式:工廠模式和單態模式
工廠模式可將Java 物件的呼叫者從被呼叫者的實現邏輯中分離出來,呼叫者只需關心被呼叫者必須滿足的規則(介面) ,而不必關心例項的具體實現過程。這是面向介面程式設計的優勢,能提高程式的解耦,避免所有的類以硬編碼方式耦合在一起。 如果所有的類直接耦合,極易形成
深入研究Spring-IoC:兩種設計和實現
一.Sprng IOC 解除了物件例項化造成的耦合現象;將物件的建立和對生命週期的管理交給了容器來管理,可以通過注入的方式將IOC容器中的物件供給開發者使用,極大方便了開發。 二.IOC容器系列的兩種設計和實現–BeanFactory和ApplicationCont
Spring的兩種代理方式:JDK動態代理和CGLIB動態代理
轉自 :https://blog.csdn.net/cckevincyh/article/details/54962920 代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可譯為”代理“,所謂代理,就是一個人或者一個機構代表另一個人或者另一個機構採取行動。
scala 基礎十二 scala apply的使用,工廠方法和單例模式的實現
定義 其他 返回 pack 新的 true 伴生對象 args null 1. apply 可以用來實現類似於靜態的初始化類的實例,請看下面實例 package smart.iot class applyclass { } class A {
處理瀏覽器端長時間執行JavaScript指令碼的兩種優化方式:定時器和worker
第一種:定時器方式,把長時間的任務進行分割成一個數組,間隔一定的時間執行。 function timeProcessArray(items, process, callBack) { let todo = items.concat() setTimeout(function () {
執行緒的兩種建立方式:Thread類和Runnable介面,它們都要複寫run方法
/*執行緒: * 1.如何在自定義的程式碼中,自定義一個執行緒呢? * * 通過對API的查詢,java已提供了對執行緒這類事物的描述。就是Thread類 * * 建立執行緒的第一種方式:繼承Thread類。 * 步驟: * 1.定義類繼承Thread。
Spring—AOP兩種代理機制對比(JDK和CGLib動態代理)
Sprign 動態代理機制 Spirng的AOP的動態代理實現機制有兩種,分別是: 1)JDK動態代理: 具體實現原理: 1、通過實現InvocationHandlet介面建立自己的呼叫處理器 2、
C++工廠類和單例模式的結合使用
單例模式: 簡單來說一個類只有一個例項且封裝性好。這裡用巨集定義實現。 animal_singleton.h #pragma once #include <iostream> #define IMPLEMENTION_SINGLETON_CL
Spring(十三):使用工廠方法來配置Bean的兩種方式(靜態工廠方法&實例工廠方法)
color 示例 簡單的 rgs icc tostring pac ng- clas 通過調用靜態工廠方法創建Bean 1)調用靜態工廠方法創建Bean是將對象創建的過程封裝到靜態方法中。當客戶端需要對象時,只需要簡單地調用靜態方法,而不需要關心創建對象的具體細節。 2
兩種設計模式(單例 簡單工廠)
一.設計模式 1.什麼是設計模式 2.為什麼用設計模式 3.什麼時候使用設計模式 4.怎樣用設計模式 二.單例模式 1.單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。 通
Spring中常用的設計模式:工廠模式
文章目錄 工廠模式 例項 1. 先實現簡單工廠 2. 工廠類(修改) 3. 增加配置檔案 4. 測試類 5. 總結 工廠模式 Beanfactory是一
C++ 兩種設計模式:單例模式和觀察者監聽者模式
一、C++中有23種設計模式,大致分為建立型模式,結構型模式以及行為模式, 在這裡自己實現一下單例模式以及觀察者和監聽者模式 二、單例模式 我們通過維護一個static的成員變數來記錄唯一的物件例項,通過提供一個static的介面instance來獲得唯一的例項,就是一
Mysql讀寫分離的兩種方法對比:Spring+JPA應用層實現 vs Amoeba中介軟體實現
前段時間看了篇文章,講Youku網資料庫架構的演變,如何從最開始的讀寫分離,再到垂直分割槽,最後到水平分片,一步一步慢慢成熟的。看完之後很有衝動抽出一個模型來把這幾種技術都實現一下。 說幹就幹,首先是讀寫分離了,我使用的資料庫是Mysql,主從資料複製用的是半
我的設計模式:工廠模式和橋梁模式
工廠模式 橋梁模式 抽象工廠模式 1.簡單工廠模式 Factory Method Pattern能生產某類(接口管理)東東,可以指定特定的類延遲初始化: 使用全局變量Map減少類的初始化過程獲取接口下的全部實現類:ClassUtils2.抽象工廠模式 Abstract Factory
C#學習之設計模式:工廠模式
缺陷 進行 type 系列 concrete 改變 cnblogs static 優劣 最近研究一下設計模式中工廠模式的應用,在此記錄如下: 什麽是工廠模式? 工廠模式屬於設計模式中的創造型設計模式的一種。它的主要作用是協助我們創建對象,為創建對象提供最佳的方式
設計模式:工廠方法
card http tro 默認 方法 enter pre 繼承 bstr 設計模式:工廠方法 一、前言 前面我們說過模板方法被用在了工廠方法裏面,為什麽呢?工廠是制造產品的,需要按照一定的流程去創造產品,因此這一定的流程創造產品就是我們的模板了。工廠方法可以說用的很多
設計模式:工廠方法模式
left 實例 設計模式 設計 通過 耦合度 creat margin 增加 一、簡單工廠模式 1、內容 不直接向客戶端暴露對象創建的實現細節,而是通過一個工廠類來負責創建產品類的實例 2、角色 1、工廠角色(Factory) 2、抽象產品角色(Product) 3、具體產
Java設計模式(一)之建立型模式:工廠模式(簡單工廠模式+工廠方法模式)
在面向物件程式設計中, 最通常的方法是一個new操作符產生一個物件例項,new操作符就是用來構造物件例項的。但是在一些情況下, new操作符直接生成物件會帶來一些問題。舉例來說,許多型別物件的建立需要一系列的步驟:你可能需要計算或取得物件的初始位置;選擇生成哪個子物件例項;或在你生成你需要的物件
Spring 通過兩種工廠方法來配置bean
在Spring框架中建立Bean例項的時候中, 我們通常會利用配置檔案,也就是XML檔案形式 或者 annotation註解方式來配置bean. 在第一種利用配置檔案方式中, 還包括如下三小類 1、反射模式 2、工廠方法模式(本文重點) 3、Factory Be