- Factory Method 工廠方法
模式定義:
定義一個用于創建對象的接口,讓子類決定實例化哪一個類。Factory Method使得一個類的實例化延遲(目的:解耦,手段:虛函數)到子類。
組件:
抽象工廠(AbstractFactory):提供了創建產品的接口,調用者通過它訪問具體工廠的工廠方法 newProduct() 來創建產品。
具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的創建。
抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能。
具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它同具體工廠之間一一對應。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/16-21:36
*/
public class FactoryMethod {
public static void main(String[] args) {
ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
Product product = concreteFactory1.newProduct();
product.show();
System.out.println("-------------------------------------------");
ConcreteFactory2 concreteFactory2 = new ConcreteFactory2();
Product product2 = concreteFactory2.newProduct();
product2.show();
}
}
abstract class Product {//定義了產品的規范,描述了產品的主要特性和功能
abstract void show();
}
class ConcreteProductA extends Product { //具體產品ProductA
@Override
void show() {
System.out.println("ConcreteProductA");
}
}
class ConcreteProductB extends Product { //具體產品ProductB
@Override
void show() {
System.out.println("ConcreteProductB");
}
}
abstract class AbstractFactory{ //提供了創建產品的抽象
abstract Product newProduct();
}
class ConcreteFactory1 extends AbstractFactory{ //實現抽象工廠中的抽象方法,完成具體產品的創建。
@Override
Product newProduct() {
return new ConcreteProductA();
}
}
class ConcreteFactory2 extends AbstractFactory{//實現抽象工廠中的抽象方法,完成具體產品的創建。
@Override
Product newProduct() {
return new ConcreteProductB();
}
}
//輸出結果:
ConcreteProductA
-------------------------------------------
ConcreteProductB
工廠方法模式的優點:
用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建過程;
在系統增加新的產品時只需要添加具體產品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;工廠方法模式的缺點:
每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的復雜度。
- AbstractFactory 抽象工廠
模式定義:
定義一個接口,讓該借口負責創建一系列“相關或者相互依賴的對象”,無需指定它們具體的類。
抽象工廠模式是工廠方法模式的升級版本,工廠方法模式只生產一個等級的產品,而抽象工廠模式可生產多個等級的產品。
使用抽象工廠模式條件:
系統中有多個產品族,每個具體工廠創建同一族但屬于不同等級結構的產品。
系統一次只可能消費其中某一族產品,即同族的產品一起使用。
組件:
抽象工廠(AbstractFactory):提供了創建產品的接口,它包含多個創建產品的方法 newProduct(),可以創建多個不同等級的產品。
具體工廠(ConcreteFactory):主要是實現抽象工廠中的多個抽象方法,完成具體產品的創建。
抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。
具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它 同具體工廠之間是多對一的關系。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/16-22:38
*/
public class AbstractFactory {
public static void main(String[] args) {
ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
concreteFactory1.newProduct1().show();
concreteFactory1.newProduct2().show();
System.out.println("-----------------------------------------");
ConcreteFactory2 concreteFactory2 = new ConcreteFactory2();
concreteFactory2.newProduct1().show();
concreteFactory2.newProduct2().show();
}
}
//中國 飛機:J20 航母:遼寧艦
//美國 飛機:F22 航母:福特級航母
abstract class Product1 { //飛機
abstract void show();
}
class ConcreteProduct11 extends Product1 {//中國飛機
@Override
void show() {
System.out.println("中國 飛機:J20");
}
}
class ConcreteProduct12 extends Product1 {//美國飛機:F22
@Override
void show() {
System.out.println("美國 飛機:F22 ");
}
}
abstract class Product2 { //航母
abstract void show();
}
class ConcreteProduct21 extends Product2 {//中國 航母:遼寧艦
@Override
void show() {
System.out.println("中國 航母:遼寧艦");
}
}
class ConcreteProduct22 extends Product2 {//美國 航母:福特級航母
@Override
void show() {
System.out.println("美國 航母:福特級航母 ");
}
}
abstract class Factory {
abstract Product1 newProduct1();
abstract Product2 newProduct2();
}
class ConcreteFactory1 extends Factory {//中國
@Override
Product1 newProduct1() {
return new ConcreteProduct11();
}
@Override
Product2 newProduct2() {
return new ConcreteProduct21();
}
}
class ConcreteFactory2 extends Factory {//美國
@Override
Product1 newProduct1() {
return new ConcreteProduct12();
}
@Override
Product2 newProduct2() {
return new ConcreteProduct22();
}
}
//輸出結果:
中國 飛機:J20
中國 航母:遼寧艦
-----------------------------------------
美國 飛機:F22
美國 航母:福特級航母
抽象工廠模式除了具有工廠方法模式的優點外,其他主要優點如下:
可以在類的內部對產品族中相關聯的多等級產品共同管理,而不必專門引入多個新的類來進行管理。
當增加一個新的產品族時不需要修改原代碼,滿足開閉原則。抽象工廠模式缺點:
當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改。
- Prototype 原型模式
模式定義:
使用原型實例指定創建對象的種類,然后通過拷貝這些原型來創建新的對象
原型模式組件:
抽象原型類:規定了具體原型對象必須實現的接口。
具體原型類:實現抽象原型類的 clone() 方法,它是可被復制的對象。
訪問類:使用具體原型類中的 clone() 方法來復制新的對象。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/17-21:48
*/
public class Prototype {
public static void main(String[] args) throws CloneNotSupportedException {
Realizetype realizetype = new Realizetype();
Realizetype clone = (Realizetype)realizetype.clonePrototype();
System.out.println("realizetype==clone? "+ (realizetype==clone));
}
}
abstract class AbstractPrototype implements Cloneable{
abstract Object clonePrototype() throws CloneNotSupportedException;
}
class Realizetype extends AbstractPrototype{
Realizetype(){
System.out.println("Real King of Monkey");
}
Object clonePrototype() throws CloneNotSupportedException {
System.out.println("fake King of Monkey");
return (Realizetype)super.clone();
}
}
//輸出結果:
Real King of Monkey
fake King of Monkey
realizetype==clone? false
用一個已經創建的實例作為原型,通過復制該原型對象來創建一個和原型相同或相似的新對象。
在這里,原型實例指定了要創建的對象的種類。用這種方式創建對象非常高效,根本無須知道對象創建的細節。
- Builder 構建器
模式定義:
將一個復雜對象的構建與其表示相分離,使得同樣的構建過程(穩定)可以創建不同的表示(變化)。
建造者(Builder)模式組件:
產品角色(Product):它是包含多個組成部件的復雜對象,由具體建造者來創建其各個滅部件。
抽象建造者(Builder):它是一個包含創建產品各個子部件的抽象方法的接口,通常還包含一個返回復雜產品的方法 getResult()。
具體建造者(ConcreteBuilder):實現 Builder接口,完成復雜產品的各個部件的具體創建方法。
指揮者(Director):它調用建造者對象中的部件構造與裝配方法完成復雜對象的創建,在指揮者中不涉及具體產品的信息。
package com.lillcol.designmodel;
/**
* @author lillcol
* 2019/6/17-22:32
*/
//組裝電腦
public abstract class Builder {
Product product = new Product();
abstract void buyKey();
abstract void buyMouse();
abstract Product returnComputer();
}
class ConcreteBuilder1 extends Builder {
@Override
void buyKey() {
product.setKey("ConcreteBuilder1 key :雙飛燕無線鼠標");
}
@Override
void buyMouse() {
product.setMouse("ConcreteBuilder1 mouse :雙飛燕機械鍵盤");
}
@Override
Product returnComputer() {
return product;
}
}
class ConcreteBuilder2 extends Builder {
@Override
void buyKey() {
product.setKey("ConcreteBuilder1 key :無線鼠標");
}
@Override
void buyMouse() {
product.setMouse("ConcreteBuilder1 mouse :雷柏機械鍵盤");
}
@Override
Product returnComputer() {
return product;
}
}
class Product {
String key;
String mouse;
public void setKey(String key) {
this.key = key;
}
public void setMouse(String mouse) {
this.mouse = mouse;
}
public void show() {
System.out.println(key + " " + mouse);
}
}
class Director {
Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Product construct() {
builder.buyKey();
builder.buyMouse();
return builder.returnComputer();
}
}
class BuilderTest {
public static void main(String[] args) {
ConcreteBuilder1 concreteBuilder1 = new ConcreteBuilder1();
Director dirctor = new Director(concreteBuilder1);
Product product = dirctor.construct();
product.show();
System.out.println("-----------------");
ConcreteBuilder2 concreteBuilder2 = new ConcreteBuilder2();
Director dirctor2 = new Director(concreteBuilder2);
Product product2 = dirctor2.construct();
product2.show();
}
}
//輸出結果:
ConcreteBuilder1 key :雙飛燕無線鼠標 ConcreteBuilder1 mouse :雙飛燕機械鍵盤
-----------------
ConcreteBuilder1 key :無線鼠標 ConcreteBuilder1 mouse :雷柏機械鍵盤
優點:
- 各個具體的建造者相互獨立,有利于系統的擴展。
- 客戶端不必知道產品內部組成的細節,便于控制細節風險。
缺點:
- 產品的組成部分必須相同,這限制了其使用范圍。
- 如果產品的內部變化復雜,該模式會增加很多的建造者類。
參考文檔:
http://c.biancheng.net/view/1364.html
李建忠23中設計模式