更新時(shí)間:2022-12-20 12:04:17 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1854次
Java有很多種模式,以下的是一些總結(jié)的模式。
1.單例模式 (實(shí)現(xiàn)方式 私有構(gòu)造器 + 私有靜態(tài)本身的實(shí)例 + 共有實(shí)例方法返回本身的實(shí)例), 需要判斷是否已經(jīng)生成過實(shí)例)一個(gè)類只允許其有一個(gè)實(shí)例化對象 在并發(fā)程序中用的可能比較多, 涉及線程安全, 我自己知道的是Spring 依賴注入, 在容器中的Bean一般都是單例的.
public class Singelton { // 最平凡的實(shí)現(xiàn)方式
private volatile static Singelton singelton;
public static Singelton getInstance(){
if(singelton == null) {
synchronized {
if(singelton == null) {
singelton = new Singelton();
return singelton;
}
}
}
}
}
2.工廠模式(一個(gè)創(chuàng)建型設(shè)計(jì)模式) 有很多實(shí)現(xiàn)的例子 比如說很多帶有*BeanFactrory的類都是工廠模式的體現(xiàn) 他通過形參等 生成不同的對象 LoggerFactory BeanFactory 等. 其實(shí)就是通過工廠的方式, 返回某個(gè)接口不同的實(shí)例, 其實(shí)就是可以根據(jù)客戶要求的返回她想要的產(chǎn)品..
工廠模式分為三種:
第一種: 簡單工廠(靜態(tài)工廠) 有一個(gè)工廠類擁有一個(gè)靜態(tài)的方法, 用來產(chǎn)生產(chǎn)品實(shí)例, 通過傳遞參數(shù)的不同來區(qū)分生成哪個(gè)產(chǎn)品實(shí)例.
第二種: 工廠方法 : 這個(gè)是用來解決簡單工廠存在的問題 比如: 增加一個(gè)產(chǎn)品簡單工廠需要對工廠類代碼進(jìn)行修改, 增加一個(gè)判斷條件, 這樣就增加了代碼的復(fù)雜程度, 工廠方法為了解決這個(gè)問題, 通過多態(tài)的方式來實(shí)現(xiàn)不同的工廠類來生產(chǎn)不同的產(chǎn)品. 即會(huì)有一個(gè)工廠接口, 通過實(shí)現(xiàn)工廠接口的方式實(shí)現(xiàn)新的工廠類, 來代替修改工廠類代碼, 這樣會(huì)使得代碼耦合度降低.
第三種: 抽象工廠 為產(chǎn)品分類, 將縱向的產(chǎn)品實(shí)現(xiàn)類, 橫向化, 就是組成更大的產(chǎn)品工廠 具體實(shí)現(xiàn)如圖:(手畫工廠圖) 用來生產(chǎn)復(fù)雜的產(chǎn)品.
3.觀察者模式 用于一對多 或者是 一對一 關(guān)系中 在一中有什么改動(dòng) 會(huì)導(dǎo)致和他有關(guān)系的多(也就是觀察者們也發(fā)生變動(dòng))
Redis 實(shí)現(xiàn)異步消息隊(duì)列 有一種實(shí)現(xiàn)方式叫: 發(fā)布訂閱者模式 類似但是 調(diào)度方式不一樣 觀察者模式由發(fā)布者調(diào)度 而 另一種模式不是 他有單獨(dú)的調(diào)度中心
例子:
public interface Subject {
public void attach(Observer o);
public void detach(Observer o);
public void notice();
}
interface Observer{
public void update();
}
class Student implements Observer{
String teacherPhone = "";
Teacher teacher ;
public Student(String phone,Teacher t){
teacher = t;
teacherPhone = phone;
}
@Override
public void update() {
teacherPhone = teacher.getPhone();
}
public void show(){
System.out.println(teacherPhone);
}
}
class Teacher implements Subject{
private String phone;
private ArrayList<Observer> students;
public Teacher(){
phone = "";
students = new ArrayList<Observer>();
}
@Override
public void attach(Observer o) {
students.add(o);
}
@Override
public void detach(Observer o) {
students.remove(o);
}
@Override
public void notice() {
for(Observer o:students){
o.update();
}
}
public String getPhone(){
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
notice();
}
}
Test:
public static void main(String[] args) {
Teacher teacher = new Teacher();
Student s = new Student("",teacher);
Student s1 = new Student("",teacher);
teacher.attach(s);
teacher.attach(s1);
teacher.setPhone("13215646");//核心在這個(gè)set方法上 他的變動(dòng)導(dǎo)致很多都發(fā)生了改變
s.show();
s1.show();
}
4.外觀模式(門面模式) Facade Pattern
這個(gè)感覺是最簡單的 他通過一個(gè)門面類 將具體操作隱藏在方法中 客戶只需要調(diào)用方法 不用知道具體的實(shí)現(xiàn) 這樣就很好
(說的個(gè)更加科學(xué)一點(diǎn)就是, 這個(gè)模式的作用就是實(shí)現(xiàn)客戶端和子系統(tǒng)的解耦, 用戶在調(diào)用客戶端接口的時(shí)候我們可以將它具體調(diào)用的操作隱藏起來, 只需要給他提供一個(gè)門面接口, 這樣就可以使得調(diào)用更加簡單)
public void Solution(){
Analyze a = new Analyze();//這三個(gè)類的具體實(shí)現(xiàn)不知道 不過用戶只要對調(diào)用方法 自動(dòng)都會(huì)產(chǎn)生結(jié)果
Think t = new Think();
Finally f = new Finally();
a.Analyze();
t.Think();
f.Finally();
}
public class Test {
public static void main(String[] args) {
Problem p = new Problem();
p.Solution();
}
}
5.組合模式 解釋一下這個(gè)模式是什么, 首先他是用來解決樹形對象模型的(這個(gè)說的有一點(diǎn)不是很確切, 我感覺組合模式是用來解決類似有多種不同的對象, 但是他們之間還有一定的相似性 類似于這種問題就可以用組合模式來解決, 組合模式可以將他們抽象到一個(gè)Component), 就是例如文件系統(tǒng)這種樹形的結(jié)構(gòu). 他的方式是通過將葉子節(jié)點(diǎn)(文件), 非葉子結(jié)點(diǎn)(文件夾) , 抽象成一個(gè)component類或者是接口, 然后葉子節(jié)點(diǎn)和非葉子結(jié)點(diǎn), 分別實(shí)現(xiàn)一下這個(gè)類, 然后通過重寫方法的形式來實(shí)現(xiàn)樹形遍歷
還分為兩種: 透明組合模式 安全組合模式
6.命令模式
先上圖:(傳統(tǒng)的命令模式 可能都不是這么用)
這個(gè)模式可以類比于開關(guān), 有不同的功能選項(xiàng), 當(dāng)你按不同的按鈕的時(shí)候, 會(huì)有不同的物品反應(yīng)你的命令(暫時(shí)理解就是這個(gè)含義)
對于上圖來說, 一個(gè)命令模式需要一個(gè)Invoker調(diào)用者, 也就是發(fā)出命令的人, 它關(guān)聯(lián)了一個(gè)command對象(或者是一系列command對象), 然后我們需要具體的command實(shí)現(xiàn)類, 用來調(diào)用Handler(某個(gè)功能具體的實(shí)現(xiàn)類), 這個(gè)圖還少了個(gè)模塊就是我們應(yīng)該將Handler抽象成接口, 這樣的話, 如果添加刪除具體的Handler也可以減少我們修改之前的代碼. 然后我們的邏輯關(guān)系是, 我們的實(shí)現(xiàn)類接口會(huì)關(guān)聯(lián)一個(gè)Handler, 通過set方法set具體的Handler實(shí)現(xiàn)類之后, 調(diào)用具體的功能模塊.................(這是傳統(tǒng)的)
但是現(xiàn)在的命令名模式很多情況下都不是直接將Handler和Command 耦合起來, 因?yàn)槲覀円獫M足設(shè)計(jì)的高內(nèi)聚弱耦合的原則, 所以 -> 演變出了一個(gè)命令隊(duì)列.
7.裝飾模式 (分為透明裝飾模式和半透明裝飾模式)
然后簡單的說一下這個(gè)模式是什么, 這個(gè)模式是為了為被修飾的類添加一個(gè)方法, 其實(shí)就是裝飾一下一個(gè)類, 使其具有其他功能, 具體的實(shí)現(xiàn)方式是: 首先我們需要一個(gè)被裝飾的抽象構(gòu)建Component(其有一個(gè)需要被修飾的方法), 然后我們需要一個(gè)抽象裝飾器類Decorator, 實(shí)現(xiàn)我們的需要被修飾的抽象構(gòu)建, 然后與其關(guān)聯(lián)一下. 最后我們需要一個(gè)具體的裝飾器類ConcreteDecorator, 它實(shí)現(xiàn)我們的抽象裝飾器類, 然后加入我們要加入的 方法, 這樣我們就可以為我們的具體實(shí)現(xiàn)類set一個(gè)ConcreteComponent, 之后就可以調(diào)用被修飾的方法.
8.代理模式 這個(gè)模式較難 單獨(dú)建立了一個(gè)文檔 詳見 java學(xué)習(xí)/代理模式
9.原型模式 這個(gè)模式就是獲取原型的一個(gè)克隆對象, 克隆對象和原型不能是同一個(gè)對象的引用. 在java中可以調(diào)用基類Object 的clone() 方法, 但是要重寫這個(gè)方法必須實(shí)現(xiàn)Cloneable
這個(gè)模式有兩種級別:
淺克隆 : 就是上頭說到的那種情況, 實(shí)現(xiàn)一個(gè)Cloneable 接口 這個(gè)只能克隆基本類型, 但是對于引用類型 他只能克隆引用類型的地址 所以說引用類型的對象克隆之后兩個(gè)實(shí)例指向的還是一個(gè)對象
深克隆 : 這個(gè)是通過實(shí)現(xiàn)一個(gè)Serializable 接口來實(shí)現(xiàn) , 把對象實(shí)例放到流里, 然后再取回來, 這樣就可以獲得一個(gè)新的克隆實(shí)例
10.建造者模式
建造者模式類似于抽象工廠模式, 抽象工廠是將不同的產(chǎn)品進(jìn)行組合, 組合成新產(chǎn)品, 他是用來生產(chǎn)復(fù)雜產(chǎn)品(也就是類)的. 類似的, 建造者模式是用來產(chǎn)生復(fù)雜對象的, 在這里兩者的核心區(qū)別就是, 建造者模式使用來生產(chǎn)復(fù)雜對象的, 他把一個(gè)對象的不同屬性的建造抽象化, 也就是說一個(gè)對象的屬性的值是通過調(diào)用建造函數(shù)獲取的, 相對的抽象工廠是用來講不同種的產(chǎn)品(也就是類) 組合起來生成新的產(chǎn)品的過程, 他的組裝對象是類. 而建造者模式組裝的是屬性
首先他分為, 要生產(chǎn)的對象 Actor , 建造者(AbstrackBuilder, *Builder) , 控制者
抽象建造者有一個(gè)Actor類型的屬性, 并且有為這個(gè)Actor 的各個(gè)屬性賦值的函數(shù), 具體建造者繼承抽象建造者, 然后實(shí)現(xiàn)具體的建造函數(shù), 最后控制者需要一個(gè)具體建造者作為參數(shù), 控制者分別調(diào)用具體建造者的建造函數(shù), 然后獲取這個(gè)建造出來的Actor 也就是說我可以選擇不調(diào)用某個(gè)函數(shù), 這樣就很靈活
11.適配器模式
這個(gè)模式的含義我的理解是, 我們有一個(gè)(目標(biāo)/目的)抽象類的兩個(gè)方法, 但是在某個(gè)地方已經(jīng)有實(shí)現(xiàn)了的現(xiàn)成的方法, 那么我們想要不用自己再重新實(shí)現(xiàn)一遍這兩個(gè)一樣的方法有兩種辦法 1.把之前實(shí)現(xiàn)的代碼copy過去, 2. 就是寫一個(gè)目標(biāo)抽象類的適配器,
對于第二種方法也就是實(shí)現(xiàn)這個(gè)抽象類然后提供一下這兩個(gè)方法的實(shí)現(xiàn), 然后這兩個(gè)方法的實(shí)現(xiàn)是通過關(guān)聯(lián)已經(jīng)實(shí)現(xiàn)過這兩個(gè)方法的類然后調(diào)用他們的方法來實(shí)現(xiàn), 這樣就避免了copy代碼從而增加代碼長度, 而且冗余度高的問題.
然后適配器模式還分為對象適配器模式和類適配器模式, 對象適配器模式是通過關(guān)聯(lián)的方式來調(diào)用適配者的方法, 但是類適配器模式是通過繼承的方式, 由于java語言單繼承的特性, 其實(shí)這個(gè)類適配器模式很少被使用,
適配器模式有一種雙向適配器模式, 這個(gè)其實(shí)就是可以雙向適配. 適配者是雙方的.還有一種叫缺省適配器, 缺省適配器的最大的特點(diǎn)就是適配器類是一個(gè)抽象的, 他不用實(shí)現(xiàn)目標(biāo)接口的所有方法, 而是可以只實(shí)現(xiàn)幾個(gè).
12.橋接模式
廢話不多說先來上個(gè)圖
來解釋一下這個(gè)橋接模式, 首先他的作用是分離一個(gè)實(shí)體中兩種或者多種維度的抽象, 把他們抽象成抽象類 -> 關(guān)聯(lián) -> 抽象接口的模式 這樣就可以了 要增添新的類型, 只需要在他對應(yīng)的維度下創(chuàng)建一個(gè)對應(yīng)的具體實(shí)現(xiàn)類, 然后就可以實(shí)現(xiàn)復(fù)雜功能的解耦.
13.享元模式 (不是特別常用)
這個(gè)模式的作用就是, 實(shí)現(xiàn)一個(gè)享元工廠, 將一些具有相同功能的對象集中起來, 減少對象的數(shù)量, 降低系統(tǒng)因?yàn)閷ο笕哂鄬?dǎo)致的內(nèi)存消耗, 最典型的例子運(yùn)用了享元模式的就是String這個(gè)對象. 每次創(chuàng)建新對象的時(shí)候他總是要先在常量池中查找是不是已經(jīng)有了相同字符串的引用如果有了的話就不用在創(chuàng)建一個(gè)新的對象了, 只要把之前那個(gè)字符串的引用返回即可
14.職責(zé)鏈模式
責(zé)任鏈模式是什么尼? 其實(shí)責(zé)任鏈模式就是對于一系列的處理, 請求需要在一個(gè)鏈上依次傳遞. (類似于jsp的過濾器和Spring的攔截器)
責(zé)任鏈模式分為純的責(zé)任鏈模式和不純的責(zé)任鏈模式.
以上就是關(guān)于“Java設(shè)計(jì)模式詳解”的介紹,如果大家對此比較感興趣,想了解更多相關(guān)知識(shí),不妨來關(guān)注一下本站的Java設(shè)計(jì)模式技術(shù)文檔,里面還有更豐富的知識(shí)等著大家去學(xué)習(xí),希望對大家能夠有所幫助。
相關(guān)閱讀

初級 202925

初級 203221

初級 202629

初級 203743