1. 程式人生 > 其它 >【設計模式】----2.建立型模式

【設計模式】----2.建立型模式

技術標籤:# 1.1-java基礎

原文地址:http://c.biancheng.net/view/1319.html

在原文的基礎上稍微修改了一下,記錄學習過程,加深記憶,便於複習;

一、建立型模式概述

將物件的建立與使用分離,降低系統的耦合度。

二、分類

2.1 單例模式

定義:指一個類只有一個例項,且該類能自行建立這個例項的一種模式

優點
  1. 單例模式可以保證記憶體裡只有一個例項,減少了記憶體的開銷。
  2. 可以避免對資源的多重佔用。
  3. 單例模式設定全域性訪問點,可以優化和共享資源的訪問。

缺點:
  1. 單例模式一般沒有介面,擴充套件困難。如果要擴充套件,則除了修改原來的程式碼,沒有第二種途徑,違背開閉原則。
  2. 在併發測試中,單例模式不利於程式碼除錯。在除錯過程中,如果單例中的程式碼沒有執行完,也不能模擬生成一個新的物件。
  3. 單例模式的功能程式碼通常寫在一個類中,如果功能設計不合理,則很容易違背單一職責原則。
實現

懶漢式單例:類載入時沒有生成單例,只有當第一次呼叫 getlnstance 方法時才去建立這個單例。

public class LazySingleton {
	//保證 instance 在所有執行緒中同步
	private static volatile LazySingleton instance = null;

	//private 避免類在外部被例項化
	private LazySingleton() {
	}

	//getInstance 方法前加同步
	public static synchronized LazySingleton getInstance() {
		if (instance == null) {
			instance = new LazySingleton();
		}
		return instance;
	}
}

餓漢式單例:類一旦載入就建立一個單例

public class HungrySingleton {
	// 類一旦載入就建立一個單例
	private static final HungrySingleton instance = new HungrySingleton();
	private HungrySingleton() {
	}
	public static HungrySingleton getInstance() {
		return instance;
	}
}

2.2 原型模式

定義:用一個已經建立的例項作為原型,通過複製該原型物件來建立一個和原型相同或相似的新物件。

//具體原型類
public class Realizetype implements Cloneable {
	Realizetype() {
		System.out.println("具體原型建立成功!");
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		System.out.println("具體原型複製成功!");
		return (Realizetype) super.clone();
	}
}

public class Test {
	public static void main(String[] args) throws CloneNotSupportedException {
		Realizetype obj1 = new Realizetype();
		Realizetype obj2 = (Realizetype) obj1.clone();
		System.out.println("obj1==obj2?" + (obj1 == obj2));
	}
}

2.3 工廠模式

2.3.1 簡單工廠

定義;一個建立產品物件的工廠介面,將產品物件的實際建立工作推遲到具體子工廠類當中。

簡單工廠只適合於產品物件較少,且產品固定的需求

// 產品介面
public interface Product {
	void show();
}
public class ProductA implements Product{

	@Override
	public void show() {
		System.out.println("ProductA");
	}
}
public class ProductB implements Product {
	@Override
	public void show() {
		System.out.println("ProductB");
	}
}

public class SimpleFactory {
	public static Product makeProduct(String kind) {
		switch (kind) {
			case "pa":
				return new ProductA();
			case "pb":
				return new ProductB();
		}
		return null;
	}
}

測試

public class Test {
	public static void main(String[] args) {
		Product pa = SimpleFactory.makeProduct("pa");
		pa.show();
		Product pb = SimpleFactory.makeProduct("pb");
		pb.show();
	}
}

2.3.2 工廠方法

簡單來說就算具體的工廠產生具體的產品。好處是靈活性增強,對於新產品的建立,只需多寫一個相應的工廠類。缺點是類的個數容易過多,增加複雜度,增加了系統的抽象性和理解難度.

// 產品介面
public interface Product {
	void show();
}
public class ProductA implements Product{

	@Override
	public void show() {
		System.out.println("ProductA");
	}
}
public class ProductB implements Product {
	@Override
	public void show() {
		System.out.println("ProductB");
	}
}

public interface AbstractFactory {
	public Product newProduct();
}
public class ConcreteFactoryA implements AbstractFactory {
	@Override
	public Product newProduct() {
		System.out.println("具體工廠A生成-->具體產品A...");
		return new ProductA();
	}
}

public class ConcreteFactoryB implements AbstractFactory {
	@Override
	public Product newProduct() {
		System.out.println("具體工廠B生成-->具體產品B...");
		return new ProductB();
	}
}

public class Test {
	public static void main(String[] args) {
	   //具體的應用中工廠的選擇為動態的
		ConcreteFactoryA cfA= new ConcreteFactoryA();
		Product product = cfA.newProduct();
		product.show();
	}
}

2.4 抽象工廠

定義:是一種為訪問類提供一個建立一組相關或相互依賴物件的介面,且訪問類無須指定所要產品的具體類就能得到同族的不同等級的產品的模式結構。

抽象工廠模式的結構同工廠方法模式的結構相似,不同的是其產品的種類不止一個,所以建立產品的方法也不止一個。

注:此模式實現程式碼見原文

2.5 建造者模式

定義:指將一個複雜物件的構造與它的表示分離,使同樣的構建過程可以建立不同的表示,這樣的設計模式被稱為建造者模式。

優點

  • 封裝性好,構建和表示分離。
  • 擴充套件性好,各個具體的建造者相互獨立,有利於系統的解耦。
  • 客戶端不必知道產品內部組成的細節,建造者可以對建立過程逐步細化,而不對其它模組產生任何影響,便於控制細節風險。

模式實現

1.產品角色:包含多個組成部件的複雜物件。

class Product {
    private String partA;
    private String partB;
    private String partC;
    public void setPartA(String partA) {
        this.partA = partA;
    }
    public void setPartB(String partB) {
        this.partB = partB;
    }
    public void setPartC(String partC) {
        this.partC = partC;
    }

    @Override
    public String toString() {
        return "Product{" +
                "partA='" + partA + '\'' +
                ", partB='" + partB + '\'' +
                ", partC='" + partC + '\'' +
                '}';
    }
}

2.抽象建造者:包含建立產品各個子部件的抽象方法。

abstract class Builder {
    //建立產品物件
    protected Product product = new Product();
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract void buildPartC();
    //返回產品物件
    public Product getResult() {
        return product;
    }
}

3.具體建造者:實現了抽象建造者介面。

public class ConcreteBuilder extends Builder {
    @Override
	public void buildPartA() {
        product.setPartA("建造 PartA");
    }
	@Override
    public void buildPartB() {
        product.setPartB("建造 PartB");
    }
	@Override
    public void buildPartC() {
        product.setPartC("建造 PartC");
    }
}

4.指揮者:呼叫建造者中的方法完成複雜物件的建立。

class Director {
    private Builder builder;
    public Director(Builder builder) {
        this.builder = builder;
    }
    //產品構建與組裝方法
    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}

5.測試

public class Test {
	public static void main(String[] args) {
		Builder builder = new ConcreteBuilder();
		Director director = new Director(builder);
		Product product = director.construct();
		System.out.println(product);
	}
}