天天5分鐘-結構型模式(二)

橋接模式

橋接模式的目標是將抽象與實現解耦,使得二者能夠獨立地變化。橋接模式經過在公共接口和實現中使用繼承來達到目的。java

好比手機能夠有多個品牌,那麼能夠把手機抽象出來;每一個手機能夠有多種實現,好比顏色不一樣、尺寸不一樣、性能不一樣和系統不一樣等等。安全

Abstraction: 抽象類運維

Implementation: 抽象的實現類ide

Refined: 擴充的抽象類性能

Specific Implementation: 具體實現類。測試

橋接模式UML類圖

橋接模式

Abstractionthis

public abstract class AbstractionPhone {
    Implementor implementor;

    public Implementor getImplementorAppearance() {
        return implementor;
    }

    public void setImplementorAppearance(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

Refinedspa

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();
    }
}

Implementorcode

public abstract class Implementor {
    public abstract void operation();
}

Concrete Implementorcomponent

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: 複合節點,該結點包括複合結點的子節點或者葉子結點的子結點

組合模式UML類圖

組合模式

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: 子系統中定義的類

門面模式UML類圖

門面模式

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: 享元工廠類

享元模式UML類圖

享元模式

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
    }
}

相關文章
相關標籤/搜索