1. 程式人生 > >Java的幾種設計模式

Java的幾種設計模式

java的設計模式大體上分為三大類:

  • 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。
  • 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。
  • 行為型模式(11種):策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。

設計模式遵循的原則有6個:

1、開閉原則(Open Close Principle)

  對擴充套件開放,對修改關閉

2、里氏代換原則(Liskov Substitution Principle)

  只有當衍生類可以替換掉基類,軟體單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行為。

3、依賴倒轉原則(Dependence Inversion Principle)

  這個是開閉原則的基礎,對介面程式設計,依賴於抽象而不依賴於具體。

4、介面隔離原則(Interface Segregation Principle)

  使用多個隔離的藉口來降低耦合度。

5、迪米特法則(最少知道原則)(Demeter Principle)

  一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模組相對獨立。

6、合成複用原則(Composite Reuse Principle)

  原則是儘量使用合成/聚合的方式,而不是使用繼承。繼承實際上破壞了類的封裝性,超類的方法可能會被子類修改。

1. 工廠模式(Factory Method)

  常用的工廠模式是靜態工廠,利用static方法,作為一種類似於常見的工具類Utils等輔助效果,一般情況下工廠類不需要例項化。

複製程式碼
interface food{}

class A implements food{}
class B implements food{}
class C implements food{}
public class StaticFactory {
private StaticFactory(){} public static food getA(){ return new A(); } public static food getB(){ return new B(); } public static food getC(){ return new C(); } } class Client{ //客戶端程式碼只需要將相應的引數傳入即可得到物件 //使用者不需要了解工廠類內部的邏輯。 public void get(String name){ food x = null ; if ( name.equals("A")) { x = StaticFactory.getA(); }else if ( name.equals("B")){ x = StaticFactory.getB(); }else { x = StaticFactory.getC(); } } }
複製程式碼

2. 抽象工廠模式(Abstract Factory)

  一個基礎介面定義了功能,每個實現介面的子類就是產品,然後定義一個工廠介面,實現了工廠介面的就是工廠,這時候,介面程式設計的優點就出現了,我們可以新增產品類(只需要實現產品介面),只需要同時新增一個工廠類,客戶端就可以輕鬆呼叫新產品的程式碼。

  抽象工廠的靈活性就體現在這裡,無需改動原有的程式碼,畢竟對於客戶端來說,靜態工廠模式在不改動StaticFactory類的程式碼時無法新增產品,如果採用了抽象工廠模式,就可以輕鬆的新增拓展類。

  例項程式碼:

複製程式碼
interface food{}

class A implements food{}
class B implements food{}

interface produce{ food get();}

class FactoryForA implements produce{
    @Override
    public food get() {
        return new A();
    }
}
class FactoryForB implements produce{
    @Override
    public food get() {
        return new B();
    }
}
public class AbstractFactory {
    public void ClientCode(String name){
        food x= new FactoryForA().get();
        x = new FactoryForB().get();
    }
}
複製程式碼

3. 單例模式(Singleton)

   在內部建立一個例項,構造器全部設定為private,所有方法均在該例項上改動,在建立上要注意類的例項化只能執行一次,可以採用許多種方法來實現,如Synchronized關鍵字,或者利用內部類等機制來實現。

複製程式碼
public class Singleton {
    private Singleton(){}

    private static class SingletonBuild{
        private static Singleton value = new Singleton();
    }

    public Singleton getInstance(){  return  SingletonBuild.value ;}
    
}
複製程式碼

4.建造者模式(Builder)

  在瞭解之前,先假設有一個問題,我們需要建立一個學生物件,屬性有name,number,class,sex,age,school等屬性,如果每一個屬性都可以為空,也就是說我們可以只用一個name,也可以用一個school,name,或者一個class,number,或者其他任意的賦值來建立一個學生物件,這時該怎麼構造?

  難道我們寫6個1個輸入的建構函式,15個2個輸入的建構函式.......嗎?這個時候就需要用到Builder模式了。給個例子,大家肯定一看就懂:

複製程式碼
public class Builder {

    static class Student{
        String name = null ;
        int number = -1 ;
        String sex = null ;
        int age = -1 ;
        String school = null ;
     //構建器,利用構建器作為引數來構建Student物件 static class StudentBuilder{ String name = null ; int number = -1 ; String sex = null ; int age = -1 ; String school = null ; public StudentBuilder setName(String name) { this.name = name; return this ; } public StudentBuilder setNumber(int number) { this.number = number; return this ; } public StudentBuilder setSex(String sex) { this.sex = sex; return this ; } public StudentBuilder setAge(int age) { this.age = age; return this ; } public StudentBuilder setSchool(String school) { this.school = school; return this ; } public Student build() { return new Student(this); } } public Student(StudentBuilder builder){ this.age = builder.age; this.name = builder.name; this.number = builder.number; this.school = builder.school ; this.sex = builder.sex ; } } public static void main( String[] args ){ Student a = new Student.StudentBuilder().setAge(13).setName("LiHua").build(); Student b = new Student.StudentBuilder().setSchool("sc").setSex("Male").setName("ZhangSan").build(); } }
複製程式碼

5. 原型模式(Protype)

原型模式就是講一個物件作為原型,使用clone()方法來建立新的例項。

複製程式碼
public class Prototype implements Cloneable{

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone()   {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }finally {
            return null;
        }
    }

    public static void main ( String[] args){
        Prototype pro = new Prototype();
        Prototype pro1 = (Prototype)pro.clone();
    }
}
複製程式碼

此處使用的是淺拷貝,關於深淺拷貝,大家可以另行查詢相關資料。

6.介面卡模式(Adapter)

介面卡模式的作用就是在原來的類上提供新功能。主要可分為3種:

  • 類適配:建立新類,繼承源類,並實現新介面,例如 
    class  adapter extends oldClass  implements newFunc{}
  • 物件適配:建立新類持源類的例項,並實現新介面,例如 
    class adapter implements newFunc { private oldClass oldInstance ;}
  • 介面適配:建立新的抽象類實現舊介面方法。例如 
    abstract class adapter implements oldClassFunc { void newFunc();}

7.裝飾模式(Decorator)

 給一類物件增加新的功能,裝飾方法與具體的內部邏輯無關。例如:

複製程式碼
interface Source{ void method();}
public class Decorator implements Source{

    private Source source ;
    public void decotate1(){
        System.out.println("decorate");
    }
    @Override
    public void method() {
        decotate1();
        source.method();
    }
}
複製程式碼

8.代理模式(Proxy)

客戶端通過代理類訪問,代理類實現具體的實現細節,客戶只需要使用代理類即可實現操作。

這種模式可以對舊功能進行代理,用一個代理類呼叫原有的方法,且對產生的結果進行控制。

複製程式碼
interface Source{ void method();}

class OldClass implements Source{
    @Override
    public void method() {
    }
}

class Proxy implements Source{
    private Source source = new OldClass();

    void doSomething(){}
    @Override
    public void method() {
        new Class1().Func1();
        source.method();
        new Class2().Func2();
        doSomething();
    }
}
複製程式碼

9.外觀模式(Facade)

為子系統中的一組介面提供一個一致的介面,定義一個高層介面,這個介面使得這一子系統更加容易使用。這句話是百度百科的解釋,有點難懂,但是沒事,看下面的例子,我們在啟動停止所有子系統的時候,為它們設計一個外觀類,這樣就可以實現統一的介面,這樣即使有新增的子系統subSystem4,也可以在不修改客戶端程式碼的情況下輕鬆完成。

複製程式碼
public class Facade {
    private subSystem1 subSystem1 = new subSystem1();
    private subSystem2 subSystem2 = new subSystem2();
    private subSystem3 subSystem3 = new subSystem3();
    
    public void startSystem(){
        subSystem1.start();
        subSystem2.start();
        subSystem3.start();
    }
    
    public void stopSystem(){
        subSystem1.stop();
        subSystem2.stop();
        subSystem3.stop();
    }
}
複製程式碼

10.橋接模式(Bridge)

複製程式碼
interface DrawAPI {
    public void drawCircle(int radius, int x, int y);
}
class RedCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing Circle[ color: red, radius: "
                + radius +", x: " +x+", "+ y +"]");
    }
}
class GreenCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing Circle[ color: green, radius: "
                + radius +", x: " +x+", "+ y +"]");
    }
}

abstract class Shape {
    protected DrawAPI drawAPI;
    protected Shape(DrawAPI drawAPI){
        this.drawAPI = drawAPI;
    }
    public abstract void draw();
}

class Circle extends Shape {
    private int x, y, radius;

    public Circle(int x, int y, int radius, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public void draw() {
        drawAPI.drawCircle(radius,x,y);
    }
}

//客戶端使用程式碼
Shape redCircle = new Circle(100,100, 10, new RedCircle());
Shape greenCircle = new Circle(100,100, 10, new GreenCircle());
redCircle.draw();
greenCircle.draw();
複製程式碼

11.組合模式(Composite)

 組合模式是為了表示那些層次結構,同時部分和整體也可能是一樣的結構,常見的如資料夾或者樹。舉例:

複製程式碼
abstract class component{}

class File extends  component{ String filename;}

class Folder extends  component{
    component[] files ;  //既可以放檔案File類,也可以放資料夾Folder類。Folder類下又有子檔案或子資料夾。
    String foldername ;
    public Folder(component[] source){ files = source ;}
    
    public void scan(){
        for ( component f:files){
            if ( f instanceof File){
                System.out.println("File "+((File) f).filename);
            }else if(f instanceof Folder){
                Folder e = (Folder)f ;
                System.out.println("Folder "+e.foldername);
                e.scan();
            }
        }
    }
    
}
複製程式碼

12.享元模式(Flyweight)

使用共享物件的方法,用來儘可能減少記憶體使用量以及分享資訊。通常使用工廠類輔助,例子中使用一個HashMap類進行輔助判斷,資料池中是否已經有了目標例項,如果有,則直接返回,不需要多次建立重複例項。

複製程式碼
abstract class flywei{ }

public class Flyweight extends flywei{
    Object obj ;
    public Flyweight(Object obj){
        this.obj = obj;
    }
}

class  FlyweightFactory{
    private HashMap<Object,Flyweight> data;

    public FlyweightFactory(){ data = new HashMap<>();}

    public Flyweight getFlyweight(Object object){
        if ( data.containsKey(object)){
            return data.get(object);
        }else {
            Flyweight flyweight = new Flyweight(object);
            data.put(object,flyweight);
            return flyweight;
        }
    }
}
複製程式碼

相關推薦

java常見的設計模式

設計模式 單例 餓漢式 懶漢式 設計模式 1、概述 1)設計模式(Design pattern):是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結; 2)分類: 創建型模式(創建對象的): 單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。 行為型模式(對象

JAVA中常用的設計模式--單例

前段時間面試的時候被問到了設計模式,結果想想只瞭解單例、工廠…囧,所以整理下,溫故而知新。 設計模式:簡單說就是前人留下的一些經驗,有助於提高程式碼的複用率,增加可讀性; 單例模式應該是使用比較多的模式之一,很多人都是一知半解,其中也包括我,哈

Java設計模式

java的設計模式大體上分為三大類: 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。 行為型模式(11種):策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、

java設計模式(單例模式,介面卡模式,簡單工廠模式

1、單例模式:也分餓漢式單例模式(建立物件)與懶漢式單例模式(未建立物件)程式碼實現:餓漢式單例模式:懶漢式單例模式:2、介面卡模式:介面:實現介面的類:實現介面某個方法的類:3、簡單工廠模式:介面:類1:類2:工廠類:測試類:

Java常用的設計模式

一、單例模式(有的書上說叫單態模式其實都一樣) 該模式主要目的是使記憶體中保持1個物件。看下面的例子: 方法一 方法二 synchronized :/'sɪŋkrənaɪzd/ :Java語言的關鍵字,當它用來修飾一個方法或者一個程式碼塊的時候,能夠保證

java 23設計模式

代理 建造者 學習 article 適配器 htm ava arc 叠代 備註這是別人總結的本來想轉載可惜不會怎麽轉載(感謝) 以下是學習過程中查詢的資料,別人總結的資料,比較容易理解(站在各位巨人的肩膀上,望博主勿究) 創建型抽象工廠模式 http://www.cnblo

iOS 開發中的設計模式

設計模式 開發 模式 ios 設計 iOS 開發中的幾種設計模式

兩週多學完Java 23設計模式

       最近兩週任務不是很繁重,對於一個剛入職4個月的菜鳥來說,學習設計模式並靈活使用簡直天方夜譚;但是當我詢問我導師需要學點啥的時候?“《Java設計模式》,這個必須要學”,一句簡單粗略的話就打發我了。我花了將近兩週多的時間看了一部分《Java設計

兩周多學完Java 23設計模式

橋接 總結 .net 機制 接下來 策略模式 行為型模式 java 享元    最近兩周任務不是很繁重,對於一個剛入職4個月的菜鳥來說,學習設計模式並靈活使用簡直天方夜譚;但是當我詢問我導師需要學點啥的時候?“《Java設計模式》,這個必須要學”,一句簡單粗略的話就打發

JAVA 23設計模式---工廠模式(簡單工廠模式)

寫在前面的話: java常用的設計模式有23種,設計模式就是為了重用程式碼、解耦、讓程式碼更容易讓他人理解、保證程式碼可靠性 設計模式遵循的原則有6個: 1、開閉原則(Open Close Principle)   對擴充套件開放,對修改關閉。 2、里氏代換原則(Liskov S

java設計模式之間的區別

Q1: What is the difference between State and Strategy patterns? {#Q1} 狀態模式和策略模式之間有什麼區別 While the implementation is similar they sol

java 23設計模式--代理模式

代理模式 為其他物件提供一種代理以控制對此物件的訪問 Subject類:定義了RealSubject類和proxy類共同的介面,這樣就可以在任何使用RealSubject的地方都可以使用proxy; public interface Subject{ /** *

Unity中常用的設計模式

23種設計模式,實在是太多了,而且其中有一些看著還貌似差不多,讓人很費解,好不容易理解了每一種設計模式的含義,並且看了一堆虛擬碼之後,高高興興的合上了書本去玩幾把LOL,贏了幾把之後腦袋裡關於那23種設計模式的概念就剩下80%了,然後接下來的每日工作中,基本寫程式碼的時候

一個優秀的Unity3d開發者必備的設計模式

變更引起的風險降低,變更是必然的,如果單一職責原則遵守的好,當修改一個功能時,可以顯著降低對其他功能的影響。 需要說明的一點是單一職責原則不只是面向物件程式設計思想所特有的,只要是模組化的程式設計,都適用單一職責原則。 原則2:里氏替換原則 名字的由來 肯定有不少人跟我剛看到這項原則的時候一樣,對這個原則的名

常用設計模式的特點

名稱 特點 工廠模式 用一個工廠方法或者類生成物件,來替換掉在在程式碼中直接new 物件的方式 單例模式 構造方法私有化,通過靜態的公有方法來獲取例項物件

php中常見的設計模式

1. 單例模式 單例模式可以說是面嚮物件語言裡最常用、也是最簡單的一種模式。單例就是單個例項,單個物件的意思,就是說我們去例項化一個類的時候,不管呼叫多少次,都永遠只有一個例項, 不會有多個,這樣就節省了記憶體分配開支。 先簡單說下單例模式的原理:將建構函式__constr

IOS開發中的設計模式介紹

ios開發學習中,經常弄不清楚ios的開發模式,今天我們就來進行簡單的總結和探討~ (一)代理模式 應用場景:當一個類的某些功能需要由別的類來實現,但是又不確定具體會是哪個類實現。 優勢:解耦合 敏捷原則:開放-封閉原則 例項:tableview的 資料來源delegate

Unity3d程式必備的設計模式

interface I { public void method1(); public void method2(); public void method3(); public void method4(); public vo

Java 23設計模式對比總結

一、設計模式的分類 建立型模式,共五種(1-5):工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。  結構型模式,共七種(6-12):介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。  行為型模式,共十一種(13-23):策略模式、模板方法模式、觀察者模

Java設計模式

Java設計模式 1,靜態工廠方法模式 提供一個工廠類,構造方法私有,不允許外界直接建立該工廠類的物件. 在工廠類中新增一個靜態方法,用於建立物件並返回. 缺點:不利於後期維護 如果後期要再建