橋接模式的目標是將抽象與實現解耦,使得二者能夠獨立地變化。橋接模式經過在公共接口和實現中使用繼承來達到目的。java
好比手機能夠有多個品牌,那麼能夠把手機抽象出來;每一個手機能夠有多種實現,好比顏色不一樣、尺寸不一樣、性能不一樣和系統不一樣等等。安全
Abstraction:
抽象類運維
Implementation:
抽象的實現類ide
Refined:
擴充的抽象類性能
Specific Implementation:
具體實現類。測試
Abstraction
this
public abstract class AbstractionPhone { Implementor implementor; public Implementor getImplementorAppearance() { return implementor; } public void setImplementorAppearance(Implementor implementor) { this.implementor = implementor; } public abstract void operation(); }
Refined
spa
public class RefineAbstractionOnePlus extends AbstractionPhone { @Override public void operation() { System.out.println("一加手機"); implementor.operation(); } }
public class RefinedAbstractionPhoneApple extends AbstractionPhone { @Override public void operation() { System.out.println("蘋果手機"); implementor.operation(); } }
Implementor
code
public abstract class Implementor { public abstract void operation(); }
Concrete Implementor
component
public class ConcreteImplementorColor extends Implementor { @Override public void operation() { System.out.println("手機有關顏色的實現"); } }
public class ConcreteImplementorSize extends Implementor { @Override public void operation() { System.out.println("有關手機尺寸大小的實現"); } }
Client
public class Client { public static void main(String[] args) { AbstractionPhone phone = new RefineAbstractionOnePlus(); phone.setImplementorAppearance(new ConcreteImplementorColor()); phone.operation(); phone.setImplementorAppearance(new ConcreteImplementorSize()); phone.operation(); } }
組合模式顧名思義就是把一組對象組合成一個複雜的單一總體,好比把對象組合成樹形或者圖形結構。
最簡單常見的就是公司裏面的人員分佈,全部的員工是很複雜不少的,可是從CEO到最底層的員工會造成一個樹結構。
Component:
抽象結點
Leaf:
葉子結點
Composite:
複合節點,該結點包括複合結點的子節點或者葉子結點的子結點
Component
public abstract class ComponentEmployee { String name; //名字 String position; //職位 String salary; //薪水 //報告人員狀況 public void report() { String str = "Employee{" + "name='" + name + '\'' + ", position='" + position + '\'' + ", salary='" + salary + '\'' + '}'; System.out.println(str); } public ComponentEmployee(String name, String position, String salary) { this.name = name; this.position = position; this.salary = salary; } //招聘員工 public abstract void addEmployee(ComponentEmployee componentEmployee); //解僱員工 public abstract void deleteEmployee(ComponentEmployee componentEmployee); }
Composite
public class CompositeLeader extends ComponentEmployee { //這裏原本應該是private,而後外部經過get獲取才合適,爲了演示 List<ComponentEmployee> subComponentEmployees; public CompositeLeader(String name, String position, String salary) { super(name, position, salary); //new一個下一層員工的List集合 subComponentEmployees = new ArrayList<>(); } @Override public void addEmployee(ComponentEmployee componentEmployee) { subComponentEmployees.add(componentEmployee); } @Override public void deleteEmployee(ComponentEmployee componentEmployee) { subComponentEmployees.remove(componentEmployee); } @Override public void report() { System.out.println("個人狀況:"); super.report(); System.out.println("我手下員工的狀況"); for (ComponentEmployee e: subComponentEmployees) { e.report(); } } }
Leaf
public class LeafStaff extends ComponentEmployee { public LeafStaff(String name, String position, String salary) { super(name, position, salary); } //手底都沒有員工,增長和刪除操做就空實現,注意這裏的空實現 @Override public void addEmployee(ComponentEmployee componentEmployee) { } @Override public void deleteEmployee(ComponentEmployee componentEmployee) { } @Override public void report() { super.report(); } }
能夠注意到葉子結點裏面有兩個是空實現(由於最底層的員工手下沒有其它員工),這樣是不太安全的作法。很簡單,只要Component
中的兩個抽象方法刪掉便可,而後在Composite
裏面是新增方法,而不是重寫方法。
門面模式的目的是爲複雜的子系統提供單一的統一的接口,這樣客戶端只須要了解結果,沒必要了解各個子系統間是如何運做的。
好比甲方儘管給產品經理提需求,他只要成品,至於說公司的內部是如調配如何完成,客戶一律不理也不必知道。
Facade:
子系統接口
SubSystem:
子系統中定義的類
Facade
public class FacadeLeader { private SubSystemArt subSystemArt = new SubSystemArt(); private SubSystemDevelopment subSystemDevelopment = new SubSystemDevelopment(); private SubSystemOperations subSystemOperations = new SubSystemOperations(); //暴露給外界的方法,外界不知道具體內部是誰來幹,幹什麼 public void needArt() { subSystemArt.art(); } public void needDevelop() { subSystemDevelopment.develop(); } public void needOperation() { subSystemOperations.operate(); } }
SubSystem
public class SubSystemArt { public void art() { System.out.println("美工部門正在畫圖"); } }
public class SubSystemDevelopment { public void develop() { System.out.println("開發部門正在開發"); } }
public class SubSystemOperations { public void operate() { System.out.println("運維部門正在測試!"); } }
Client
public class Client { public static void main(String[] args) { FacadeLeader facadeLeader = new FacadeLeader(); System.out.println("咱們須要這個需求"); facadeLeader.needArt(); facadeLeader.needDevelop(); facadeLeader.needOperation(); } }
享元模式,聽起來很高大上,可是實際上就是共享對象的一種模式。目的是經過在類似對象間的共享狀態來減小內存佔用。
好比王者裏面的小兵在必定時間內攻擊、雙抗,移動速度都是必定的,那麼就是經過享元模式來減小對象的生成,從而使得內存消耗較少。而對於那些打完主宰後的兵,由於不是重複的,因此能夠做爲非共享的狀態。
Flyweight:
抽象享元類
Concrete Flyweight:
與其同伴共享狀態的享元對象
Unshared Concrete Flyweight:
不共享其狀態的享元對象
Flyweight Factory:
享元工廠類
Flyweight
public abstract class FlyweightSoldier { public abstract void play(); }
Concrete Flyweight
public class ConcreteFlyweightNormalSoldier extends FlyweightSoldier { String type; public ConcreteFlyweightNormalSoldier(String type) { this.type = type; } @Override public void play() { System.out.println("生成小兵:" + type); } }
Unshared Concrete Flyweight
public class UnsharedConcreteFlyweightGeneral extends FlyweightSoldier { @Override public void play() { System.out.println("根據不一樣狀況生成的龍"); } }
Flyweight Factory
public class FlyweightFactory { private Hashtable<String, FlyweightSoldier> flyweights = new Hashtable<>(); public ConcreteFlyweightNormalSoldier getSoldier(String key) { if (!flyweights.contains(key)) { flyweights.put(key, new ConcreteFlyweightNormalSoldier(key)); } return (ConcreteFlyweightNormalSoldier) flyweights.get(key); } public UnsharedConcreteFlyweightGeneral getGeneral(String key) { flyweights.put(key, new UnsharedConcreteFlyweightGeneral()); return (UnsharedConcreteFlyweightGeneral) flyweights.get(key); } }
這裏注意了,由於普通小兵是共享的,因此當有key的時候就不用再new一個小兵,直接返回便可;而對於特殊小兵來講,無論是否有key,都會new一個兵put進去。
Client
public class Client { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); for (int i = 0; i < 3; i++) { System.out.println("第" + i + 1 + "波兵線"); factory.getSoldier("近戰兵").play(); factory.getSoldier("弓箭手").play(); factory.getSoldier("法師兵").play(); } //到這裏其實只建立了三個對象 for (int i = 0; i < 2; i++) { System.out.println("第" + i + "波特殊兵線"); factory.getGeneral("減雙抗龍").play(); factory.getGeneral("減攻速龍").play(); } //到這裏建立了7個對象,3 + 4 } }