1. 程式人生 > >java設計模式-每天三個設計模式之工廠、單例、建造者

java設計模式-每天三個設計模式之工廠、單例、建造者

    前情提要    

        在上篇文章中介紹了面向物件程式設計的七個基本原則,分別是單一職責,裡式替換、依賴注入、介面分離、迪米特原則、開閉原則、優先使用組合而不是繼承原則。

    本文重點

  1.  工廠模式
  2. 單例模式
  3. 建造者模式

    工廠模式,工廠模式又分為簡單工廠、工廠方法、抽象工廠。工廠模式要實現的是將使用者與具體實現分離。

    1.簡單工廠

     角色:使用者,例項工廠(或者靜態工廠),抽象產品和產品實現。類圖如下

實現程式碼:

public class CarFactory{
public Car createCar(String name){
if("BMW".equals()){
return new BMW("BMW");
}
if("BENZ".equals()){
return new BENZ("BENZ");
}
}
}


public interface Car{
void run();
}


public class BMW implements Car{
private String name;
public BMW(String name){
this.name = name;
}

public void run(){
System.out.println(name + "開始行駛了...");
}
}


public class BENZ implements Car{
private String name;
public BENZ(String name){
this.name = name;
}
public void run(){
System.out.println(name + "開始行駛了...");
}
}


public class Driver{
public void drive(){
Car bmw = CarFactory.createCar("BMW");
Car benz = CarFactory.createCar("BENZ");
bmw.run();
benz.run();
}

}

使用場景

代替new產生物件時,產品的型別比較少時。

缺點

不符合開閉原則,當新加產品型別的時候,就需要修改工廠中的建立的程式碼。

工廠方法模式:

角色:抽象工廠,抽象工廠實現,抽象產品,產品,使用者

類圖,略。

程式碼實現:

public class ICarFactory{
Car createBMWCar();

Car createBENZCar();
}


public class CarFactory implements ICarFactory{
public Car createBMWCar(){
return new BMW("BMW");
}

public Car createBENZCar(){
return new BENZ("BENZ");
}
}


public interface Car{
void run();
}


public class BMW implements Car{
private String name;
public BMW(){
this.name =  "BMW";
}

public void run(){
System.out.println(name + "開始行駛了...");
}
}


public class BENZ implements Car{
private String name;
public BENZ(){
this.name = "BENZ";
}
public void run(){
System.out.println(name + "開始行駛了...");
}
}


public class Driver{
public void drive(){
Car bmw = CarFactory.createBMWCar();
Car benz = CarFactory.createBENZCar();
bmw.run();
benz.run();
}

}

這樣修改簡單工廠之後就可以滿足開閉原則了。

使用場景:系統產品包含多個產品族,每個產品族又有一系列產品,每次系統只使用一種產品族的產品。

主要缺點:產品族擴充套件比較難,需要修改的地方較多。

抽象工廠模式

角色:同工廠方法

類圖:略

實現程式碼:

public interface PCFactory{

    Cpu createCpu(String name);

    KeyBoard createKeyBoard(String name);

}

LenovoPCFactory implements PCFactory{

    public Cpu createCpu(){

        return LenovoCPU();

    }

public KeyBoard createKeyBoard (){

        return LenovoKeyBoard ();

    }

}

MACPCFactory implements PCFactory{

    public Cpu createCpu(){

        return MACCPU();

    }

public KeyBoard createKeyBoard (){

        return MACKeyBoard ();

    }

}

public interface Cpu{

}

public class LenovoCpu implements Cpu{

}

public class MACCpu implements Cpu{

}


public interface KeyBoard{

}

public class LenovoKeyBoard implements KeyBoard{

}

public class MACKeyBoard implements KeyBoard{

}

public class Test{

    public static void main(String[] args){

        MACPCFactory.createCpu();

        LenovoPCFactory.createCpu();

        LenovoPCFactory.createKeyBoard();

        MACPCFactory.createKeyBoard();

    }

}

單例模式:

使用場景:全域性只需要一個該物件,該物件的初始化比較耗費資源。

程式碼實現:

餓漢式:


public class Single{
private static final Single instance = new Single();

private Single(){

}


public static final Single getInstance(){
return instance;
}
}


懶漢式:


public class Single{
private volatile Single instance;

public Single(){
if(instance == null){
synchronized(this){
instance = new Single();
}
}else{
return instance;
}
}


public static final Single getInstance(){
return instance;
}
}




內部類同時具備餓漢式和懶漢式有點的實現


public class Single{
private Single(){
}

//靜態內部類由虛擬機器負責執行緒安全
private static class SingleHolder{
private static final Single instance = new Single();
}

public static final Single getInstance(){
return SingleHolder.instance;
}

}

建造者模式:

使用場景:如果一個物件比較的複雜,又比較關注產品構造的細節。與工廠模式的主要區別是工廠模式關注產品整體,也就是說只要造出產品即可,通常產品的屬性比較少;而建造模式關注產品製造的細節,屬性比較多複雜。

程式碼實現:

public interface Packing {
   public String pack();

}

public interface Item {
   public String name();
   public Packing packing();
   public float price();    

}

public interface Item {
   public String name();
   public Packing packing();
   public float price();    

}

public class Bottle implements Packing {
   @Override
   public String pack() {
      return "Bottle";
   }

}

public abstract class Burger implements Item {


   @Override
   public Packing packing() {
      return new Wrapper();
   }


   @Override
   public abstract float price();
}


public abstract class ColdDrink implements Item {


    @Override
    public Packing packing() {
       return new Bottle();
    }


    @Override
    public abstract float price();
}


public class VegBurger extends Burger {


   @Override
   public float price() {
      return 25.0f;
   }


   @Override
   public String name() {
      return "Veg Burger";
   }
}


public class ChickenBurger extends Burger {


   @Override
   public float price() {
      return 50.5f;
   }


   @Override
   public String name() {
      return "Chicken Burger";
   }
}


public class Coke extends ColdDrink {


   @Override
   public float price() {
      return 30.0f;
   }


   @Override
   public String name() {
      return "Coke";
   }
}


public class Pepsi extends ColdDrink {


   @Override
   public float price() {
      return 35.0f;
   }


   @Override
   public String name() {
      return "Pepsi";
   }
}


public class Meal {
   private List<Item> items = new ArrayList<Item>();    


   public void addItem(Item item){
      items.add(item);
   }


   public float getCost(){
      float cost = 0.0f;
      for (Item item : items) {
         cost += item.price();
      }        
      return cost;
   }


   public void showItems(){
      for (Item item : items) {
         System.out.print("Item : "+item.name());
         System.out.print(", Packing : "+item.packing().pack());
         System.out.println(", Price : "+item.price());
      }        
   }    
}


public class MealBuilder {


   public Meal prepareVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new VegBurger());
      meal.addItem(new Coke());
      return meal;
   }   


   public Meal prepareNonVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new ChickenBurger());
      meal.addItem(new Pepsi());
      return meal;
   }
}


public class Test {
   public static void main(String[] args) {
      MealBuilder mealBuilder = new MealBuilder();


      Meal vegMeal = mealBuilder.prepareVegMeal();
      System.out.println("Veg Meal");
      vegMeal.showItems();
      System.out.println("Total Cost: " +vegMeal.getCost());


      Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
      System.out.println("\n\nNon-Veg Meal");
      nonVegMeal.showItems();
      System.out.println("Total Cost: " +nonVegMeal.getCost());
   }

}

其中建造者模式程式碼引用http://www.runoob.com/design-pattern/builder-pattern.html一節建造者模式。

相關推薦

java設計模式-每天設計模式工廠建造

    前情提要            在上篇文章中介紹了面向物件程式設計的七個基本原則,分別是單一職責,裡式替換、依賴注入、介面分離、迪米特原則、開閉原則、優先使用組合而不是繼承原則。    本文重點 工廠模式單例模式建造者模式    工廠模式,工廠模式又分為簡單工廠、工廠

java設計模式-每天設計模式(前言)

我們知道JAVA是純面向物件的高階程式語言,使用面向物件的程式語言寫程式,特別是寫出好程式就必須掌握一些基本原則,就像資料庫設計中需要遵循三正規化(不知道的自行百度)一樣。那麼在編寫java程式時我們要遵循那些基本原則呢,聽我一一道來。Java面向物件程式設計主要設計的基本原

設計模式——建立型模式工廠,簡單工廠建造,原型)

目錄 一、工廠模式 簡單工廠模式 工廠方法模式 二、抽象工廠模式 三、單例模式 四、建造者模式 五、原型模式 建

編程經常使用設計模式具體解釋--(上篇)(工廠建造原型)

-a 裝飾器模式 nds support art 類的繼承 兩個 開放 lose 參考來自:http://zz563143188.iteye.com/blog/1847029 一、設計模式的分類 整體來說設計模式分為三大類: 創建型模式。共五種:工廠方法模式、抽

java設計模式)模板模式

pro str pan style coff pub 調用 類定義 ted   抽象類中公開定義了執行它的方法的方式,子類可以按需求重寫方法實現,但調用將以抽象類中定義的方式進行,典型應用如銀行辦理業務流程、沖泡飲料流程。下面給出簡單例子,用沸水沖泡飲料,分為四步:將水煮沸

Java工廠模式設計方式

工廠模式是我們最常用的例項化物件模式,是用工廠方法代替new操作的一種模式。工廠模式在Java程式系統可以說是隨處可見。因為工廠模式就相當於建立例項物件的new,我們經常要根據類Class生成例項物件,如A a=new A() 工廠模式也是用來建立例項物件的,所以在使用new例項化物件時,可以考慮使用工廠模

設計模式)- 狀態模式

.get TP 導致 做到 ring bubuko 對象 狀態 一個 [toc] 狀態模式 當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。 在平常開發自己也會遇到好多方法過長,裏面的判斷語句太多,導致後續修改十分麻煩。今天看到狀態模式的介紹,覺

設計模式)---原型模式

吐槽 今天帶貓貓去打針,然後她各種皮,差點從袋子裡面跑出去了emmmmm,早上上課時候,編譯原理上上課居然就聽不懂了,很尷尬,趕緊回去補。 什麼叫原型模式 就是類似鳴人的影分身之術,可以克隆物件 定義:用原型例項指向建立物件的種類,並通過複製這些原型建立新的物件

設計模式)代理模式

代理模式:一個代理角色和一個真正的角色,代理角色代替真正角色執行操作 代理模式又分為靜態代理模式和動態代理模式。 靜態代理模式: 1、首先抽象角色(參考武哥的例子) package 代理模式;

【轉】【設計模式種介面卡模式 總結和使用場景

一 概述定義:介面卡模式將某個類的介面轉換成客戶端期望的另一個介面表示,主的目的是相容性,讓原本因介面不匹配不能一起工作的兩個類可以協同工作。其別名為包裝器(Wrapper)。屬於結構型模式主要分為三類:類介面卡模式、物件的介面卡模式、介面的介面卡模式。本文定義:需要被適配的

MongoDB一對多模式設計方案

今天讀了篇文章,關於mongodb裡,一對多模式下的schema設計方案,感覺說的挺清晰,所以分享一下。原連結:問題:資料庫設計中,資料之間的引用不可避免,其中常見的模式就是一對多。舉個例子:Person和AddressesPerson是一個物件,地址是一個物件,一個Pers

Java設計模式模式登記式

package 建立型_單例模式_登記式; import java.util.HashMap; import java.util.Map; /** * 登記式單例實際上維護的是一組單例類的例項,將這些例項儲存到一個Map(登記簿) * 中,對於已經登記過的單例,則從

Unity遊戲設計模式)原型模式(Prototype Pattern)

        原型模式,顧名思義就是通過物件的原型克隆而產生的新的物件。原型模式在遊戲中運用非常多。怪物,一張地圖上有許許多多的怪物,這些怪物一般都具有共通性,同一種怪物就有可能擁有同樣的模型,同樣的攻擊方式等。即使是不同型別的怪物他們也擁有許多共通性,例如都擁有攻擊力,

JAVA設計模式 1 設計模式介紹模式的理解與使用

資料結構我們已經學了一部分了。是該瞭解瞭解設計模式了。習慣了`CRUD`的你,也該瞭解瞭解這一門神器、我為啥要說是神器呢? 因為在大廠的面試環節、以及很多的比如 - Springboot - Mybatis 等開源框架中、大量的使用到了設計模式。為了我們在之後學習原始碼的時候不再懵逼,為啥這程式碼能這樣

設計模式

println pre log 內存 urn args 懶漢 logs pan /* 設計模式:解決某一類問題最有效的方式 單例設計模式:解決的是一個類在內存中只有一個對象的問題 1:構造方法私有化 2:構造方法私有化之後,一個對象都不能創建了,所以只能在類中創建對

設計模式:簡單工廠工廠

判斷 include sse src div list .class name set 1 <?php 2 /** 3 * 純粹工廠類 4 */ 5 /*class Factory { 6 public static funct

zabbix的agent端的主動模式關鍵參數

tar round 1.8 include rac 主動 style server host 如多主機超過300+和隊列內容過多,就采用主動模式. [root@web03 zabbix]# egrep -v "^#|^$" zabbix_agentd.conf PidFil

設計模式:對象生成(工廠抽象工廠

添加 對象實例 log return ray 靜態 學習 線程 tco 對象的創建有時會成為面向對象設計的一個薄弱環節。我們可以使用多種面向對象設計方案來增加對象的創建的靈活性。 單例模式:生成一個且只生成一個對象實例的特殊類 工廠方法模式:構建創建者類的繼承層級

設計模式》之一文帶你理解JDK動態代理CGLIB動態代理靜態代理

個人認為我在動態代理方面的分析算是比較深入了,下次更新再修改一下,爭取做到最好,後續還有建造者模式、模板方法、介面卡、外觀、責任鏈、策略和原型模式的深入!各位讀者如果覺得還不錯的可以持續關注哦。謝謝各位!!! 我的github,到時上傳例子程式碼 https://github.com

關於緩衝區/池設計中的佇列

今天在看作業系統相關的書,看到一個例子:用三個佇列來管理緩衝區池的使用情況,三個佇列分別為:空閒緩衝佇列em,輸入緩衝佇列in,輸出緩衝佇列out。   對緩衝不是很瞭解,只知道緩衝是用來平衡不同裝置資料傳輸速度的差異的,對於其具體實現不是很瞭解。其實緩衝區用一個位元組陣列就可以實