設(shè)計(jì)模式

設(shè)計(jì)原則

原則 內(nèi)容 備注
開閉原則 對修改關(guān)閉,對擴(kuò)展開放。也就是說盡量通過擴(kuò)展之前的模塊實(shí)現(xiàn)新的需求而不要對之前的代碼進(jìn)行更改。
里氏替換原則 子類可以擴(kuò)展父類的功能,但是不能改變原有的功能。也就是可以增加方法,但是不要重寫方法。
單一職責(zé)原則 一個類不應(yīng)該承擔(dān)太多職責(zé),最好就只負(fù)責(zé)一件事
依賴倒置原則 高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴抽象。簡單的說就是面向接口編程。
接口隔離原則 一個類依賴的接口盡可能小,而不要依賴他本身不使用的方法。
迪米特法則 如果兩個軟件實(shí)體無須直接通信,那么就不應(yīng)當(dāng)發(fā)生直接的相互調(diào)用,可以通過第三方轉(zhuǎn)發(fā)該調(diào)用。
合成復(fù)用原則 在軟件復(fù)用時,要盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來實(shí)現(xiàn),其次才考慮使用繼承關(guān)系來實(shí)現(xiàn)。

Java的23種設(shè)計(jì)模式

創(chuàng)建型模式

它的主要特點(diǎn)是“將對象的創(chuàng)建與使用分離”。這樣可以降低系統(tǒng)的耦合度,使用者不需要關(guān)注對象的創(chuàng)建細(xì)節(jié),對象的創(chuàng)建由相關(guān)的工廠來完成。

單例模式

指一個類只有一個實(shí)例,且該類能自行創(chuàng)建這個實(shí)例的一種模式。

懶漢式單例實(shí)現(xiàn)
public class LazySingleton {
  private static volatile LazySingleton instance = null;
  
  private LazySingleton() {}   
  
  // 第一次使用的時候再去創(chuàng)建,增加了線程同步
  public static LazySingleton getInstance() {
    if (instance == null) {
      synchronized(LazySingleton.class){
        if(instance == null){
          instance = new LazySingleton();
        }
      }
    }
    return instance;
  }
}
餓漢式單例實(shí)現(xiàn)
public class HungrySingleton {
  // 在類加載時就創(chuàng)建好這個對象了
  private static final HungrySingleton instance = new HungrySingleton();
  
  private HungrySingleton() {}
  
  public static HungrySingleton getInstance() {
    return instance;
  }
}
靜態(tài)內(nèi)部類實(shí)現(xiàn)
// 利用了classloader機(jī)制來保證初始化 instance 時只有一個線程,線程安全
public class SingletonInStaticInnerClass {
  // 靜態(tài)內(nèi)部類
  private static class InnerClass {
    private final static SingletonInStaticInnerClass INSTANCE = new SingletonInStaticInnerClass();
  }
  
  private SingletonDemoInStaticInnerClass() {}
  
  // 公關(guān)獲取實(shí)例方法(線程安全,延遲加載)
  public static SingletonDemoInStaticInnerClass getInstance() {
    return InnerClass.INSTANCE;
  }
}

工廠模式

定義一個創(chuàng)建產(chǎn)品對象的工廠接口,將產(chǎn)品對象的實(shí)際創(chuàng)建工作推遲到具體子工廠類當(dāng)中。這滿足創(chuàng)建型模式中所要求的“創(chuàng)建與使用相分離”的特點(diǎn)。

簡單工廠模式
interface Car {
  void drive();
}

class ACar implements Car {
  @Override
  void drive(){
  }
}

class BCar implements Car {
  @Override
  void drive(){
  }
}

class CarFactory {
  // 通過名字就能獲取一個對應(yīng)的對象
  public static Car makeCar(String carName) {
    switch(carName) {
      "ACar": return new ACar(); break;
      "BCar": return new BCar(); break;
      default: return null;
    }
  }
}
工廠方法模式
interface Car {
  void drive();
}

class ACar implements Car {
  @Override
  void drive(){
  }
}

class BCar implements Car {
  @Override
  void drive(){
  }
}

interface CarFactory {
  Car makeCar();
}

class ACarFactory implements CarFactory {
  @Override
  Car makeCar() {
    return ACar();
  }
}

class BCarFactory implements CarFactory {
  @Override
  Car makeCar() {
    return BCar();
  }
}

// 使用的時候大概這樣用
class Test {
  void test() {
    CarFactory carFactory = new ACarFactory();
    Car car = carFactory.makeCar();
    car.drive();
  }
}
抽象工廠模式
interface Screen {
  void output();
}

class HpScreen implements Screen {
  @Override
  void output(){
  }
}

class MiScreen implements Screen {
  @Override
  void output(){
  }
}

interface Keyboard {
  void input();
}

class HpKeyboard implements Keyboard {
  @Override
  void input() {
  }
}

class MiKeyboard implements Keyboard {
  @Override
  void input() {
  }
}

interface CompterPartFactory {
  Screen makeScreen();
  
  Keyboard makeKeyboard();
}

// 為了創(chuàng)建一個可以生成同品牌不同類型的產(chǎn)品的工廠
class HpCompterPartFactory implements CompterPartFactory {
  @Override
  Screen makeScreen() {
    return HpScreen();
  }
  
  @Override
  Keyboard makeKeyboard() {
    return HpKeyboard();
  }
}

class MiCompterPartFactory implements CompterPartFactory {
  @Override
  Screen makeScreen() {
    return MiScreen();
  }
  
  @Override
  Keyboard makeKeyboard() {
    return MiKeyboard();
  }
}

建造者模式

指將一個復(fù)雜對象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過程可以創(chuàng)建不同的表示,這樣的設(shè)計(jì)模式被稱為建造者模式。它是將一個復(fù)雜的對象分解為多個簡單的對象,然后一步一步構(gòu)建而成。它將變與不變相分離,即產(chǎn)品的組成部分是不變的,但每一部分是可以靈活選擇的。

public class NewComputer {
  
  private String cpu;
  private String screen;
  private String memory;
  private String mainboard;
  
  private NewComputer(Builder builder) {
    cpu = builder.cpu;
    screen = builder.screen;
    memory = builder.memory;
    mainboard = builder.mainboard;
  }
  
  public static final class Builder {
    
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;
      
    public Builder cpu(String cpu) {
      this.cpu = cpu;
      return this;
    }
    
    public Builder screen(String screen) {
      this.screen = screen;
      return this;
    }
    
    public Builder memory(String memory) {
      this.memory = memory;
      return this;
    }
    
    public Builder mainboard(String mainboard) {
      this.mainboard = mainboard;
      return this;
    }
    
    public NewComputer build() {
      return new NewComputer(this);
    }
  }
}

原型模式

用一個已經(jīng)創(chuàng)建的實(shí)例作為原型,通過復(fù)制該原型對象來創(chuàng)建一個和原型相同或相似的新對象。也就是我們說的深克隆和淺克隆這些。

結(jié)構(gòu)型模式

結(jié)構(gòu)型模式描述如何將類或?qū)ο蟀茨撤N布局組成更大的結(jié)構(gòu)。它分為類結(jié)構(gòu)型模式和對象結(jié)構(gòu)型模式,前者采用繼承機(jī)制來組織接口和類,后者釆用組合或聚合來組合對象。

代理模式

由于某些原因需要給某對象提供一個代理以控制對該對象的訪問。這時,訪問對象不適合或者不能直接引用目標(biāo)對象,代理對象作為訪問對象和目標(biāo)對象之間的中介。(為了控制被代理對象,以防止直接調(diào)用被代理對象的其他方法)。

靜態(tài)代理
interface Request {
  void request();
}

class GetInfoRequest implements Request {
  @Override
  void request(){
  }
}

class ProxyRequest implements Request {
  
  Request realRequest;
  
  ProxyRequest(Request realRequest){
    this.realRequest = realRequest;
  }
  
  @Override
  void request(){
    // doSomething before
    realRequest.request();
    // doSomething after
  }
}

class Test {
  void test() {
    Request realRequest = new GetInfoRequest();
    Request proxyRequest = new ProxyRequest(realRequest);
    proxyRequest.request();
  }
}
動態(tài)代理
interface Request {
  void request();
}

class GetInfoRequest implements Request {
  @Override
  public void request() {
  }
}

class ProxyFactory {
  private Object target;
  
  public ProxyFactory(Object target) {
    this.target = target;
  }
  
  public Object getProxyInstance() {
    return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                                  target.getClass().getInterfaces(),
                                  new InvocationHandler() {
                                    @Override
                                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 // doSomething before
                 Object objectReturnVal = method.invoke(target, args);
                 // doSomething after
                 return objectReturnVal;
             }
         });
    }
}

class Test {
  void test(){
    Request realRequest = new GetInfoRequest();
    ProxyFactory proxyFactory = new ProxyFactory(realRequest);
    Request proxyRequest = (Request) proxyFactory.getProxyInstance();
    proxyRequest.request();
  }
}

適配器模式

將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類能一起工作

類適配器模式
class LinuxUtil {
    void handleElectricOnLinux() {
        // 處理Linux電量相關(guān)
    }
}

interface IAdapter {
    void handleElectric();
}

class AndroidAdapter extends LinuxUtil implements IAdapter {
    @Override
    public void handleElectric() {
        // 調(diào)用,增強(qiáng),重寫這個能力
        super.handleElectricOnLinux();
    }
}

class AndroidUtil {
    void handleElectricOnAndroid(IAdapter adapter) {
        adapter.handleElectric();
    }
}

class Test {
    void test() {
        AndroidUtil androidUtil = new AndroidUtil();
        AndroidAdapter androidAdapter = new AndroidAdapter();
        androidUtil.handleElectricOnAndroid(androidAdapter);
    }
}
對象適配器模式
// 將Model適配到ListView上面去
class ListViewModel {
  public List<Object> datas = new ArrayList<>();
}

interface IAdapter {
  View getViewByPosition(int position);
  int getViewCount();
}

class ListAdapter implements IAdapter {
  
  public ListViewModel listViewModel;
  
  public ListAdapter(ListViewModel listViewModel) {
    this.listViewModel = listViewModel;
  }
  
  private View buildView(Object obj) {
    return null;
  }

  @Override
  public View getViewByPosition(int position) {
    return buildView(listViewModel.datas.get(position));
  }

  @Override
  public int getViewCount() {
    return listViewModel.datas.size();
  }
}

class ListView {
  public List<View> getChildren(IAdapter iAdapter) {
    List<View> views = new ArrayList<>();
    for (int position = 0; position < iAdapter.getViewCount(); position++) {
      views.add(iAdapter.getViewByPosition(position));
    }
    return views;
  }
}

class Test {
  void test(){
    ListViewModel listViewModel = new ListViewModel();
    ListAdapter listAdapter = new ListAdapter(listViewModel);
    ListView listView = new ListView();
    listView.getChildren(listAdapter);
  }
}

橋接模式

將抽象與實(shí)現(xiàn)分離,使它們可以獨(dú)立變化。它是用組合關(guān)系代替繼承關(guān)系來實(shí)現(xiàn),從而降低了抽象和實(shí)現(xiàn)這兩個可變維度的耦合度。

interface Brand {
  String getBrandName();
  void call();// 感覺關(guān)鍵還是在這個方法上
}

class MiBrand implements Brand {

  @Override
  public String getBrandName() {
    return "Mi";
  }

  @Override
  public void call() {
  }
}

class HwBrand implements Brand {

  @Override
  public String getBrandName() {
    return "Hw";
  }

  @Override
  public void call() {
  }
}

class BasePhone {
  Brand brand;

  public BasePhone(Brand brand) {
    this.brand = brand;
  }

  protected void call() {
    this.brand.call();
    
  }
}

class FoldedPhone extends BasePhone {

  public FoldedPhone(Brand brand) {
    super(brand);
  }

  @Override
  protected void call() {
    // do Something
    super.call();
  }
}

class Test {
  void test() {
    FoldedPhone foldedPhone = new FoldedPhone(new MiBrand());
    foldedPhone.call();
  }
}

裝飾器模式

指在不改變現(xiàn)有對象結(jié)構(gòu)的情況下,動態(tài)地給該對象增加一些職責(zé)(即增加其額外功能)的模式,它屬于對象結(jié)構(gòu)型模式。
注意:裝飾器模式在實(shí)現(xiàn)上和代理模式有一定相似之處,但是目的不同。代理模式是用于控制使用對象,而裝飾器模式是為了擴(kuò)充能力。

interface FriedChicken {
  void makeFriedChicken();
}

class KFC extends FriedChicken {
  @Override
  public void makeFriedChicken() {
  
  }
}

class McDonald extends FriedChicken {
  @Override
  public void makeFriedChicken() {
  
  }
}

class FriedChickenCheckDecorator implements FriedChicken {
  
  // 內(nèi)部維護(hù)一個炸雞類
  private FriedChicken friedChicken;
    
  // 通過構(gòu)造方法把需要裝飾的炸雞類傳進(jìn)來
  public FriedChickenDecorator(FriedChicken friedChicken) {
    this.friedChicken = friedChicken;
  }
  
  @Override
  public void makeFriedChicken() {
    this.friedChicken.makeFriedChicken();
    // do check
  }
}

class Test {
  void test() {
    FriedChicken kfc = new KFC();
    FriedChicken kfcWithCheck = new FriedChickenCheckDecorator(kfc);
    kfc.makeFriedChicken();
  }
}

外觀模式

外觀(Facade)模式又叫作門面模式,是一種通過為多個復(fù)雜的子系統(tǒng)提供一個一致的接口,而使這些子系統(tǒng)更加容易被訪問的模式。

abstract class AbstractWorker {
  
  String name;
  
  AbstractWorker(String name) {
    this.name = name;
  }
  
  abstract void doWork();
}

class ProjectManager extends AbstractWorker {
  
  ProjectManager() {
    super("項(xiàng)目經(jīng)理");
  }

  @Override
  void doWork() {
    // 制定項(xiàng)目計(jì)劃
  }
}

class DevelopmentEngineer extends AbstractWorker {

  DevelopmentEngineer() {
    super("碼農(nóng)");
  }

  @Override
  void doWork() {
    // 編碼
  }
}

class QualityAssurance extends AbstractWorker {

  QualityAssurance() {
    super("測試狗");
  }

  @Override
  void doWork() {
    // 測試
  }
}

// 外觀類
class Project {

  private AbstractWorker projectManager;
  private AbstractWorker developmentEngineer;
  private AbstractWorker qualityAssurance;

  public Project(AbstractWorker projectManager, 
                 AbstractWorker developmentEngineer, 
                 AbstractWorker qualityAssurance) {
    this.projectManager = projectManager;
    this.developmentEngineer = developmentEngineer;
    this.qualityAssurance = qualityAssurance;
  }
  
  public void develop() {
    projectManager.doWork();
    developmentEngineer.doWork();
    qualityAssurance.doWork();
  }
  
}

享元模式

享元模式的定義:運(yùn)用共享技術(shù)來有效地支持大量細(xì)粒度對象的復(fù)用。它通過共享已經(jīng)存在的對象來大幅度減少需要創(chuàng)建的對象數(shù)量、避免大量相似類的開銷,從而提高系統(tǒng)資源的利用率。

//外部狀態(tài),非享元角色
public class User {
  
  private String name;
  
  public User(String name) {
    this.name=name;
  }
  
  public String getName() {
    return name;
  }
  
}

public abstract class WebSite {
  abstract void use(User user);
}

// 具體的網(wǎng)站類型
public class ConcreateWebSite extends WebSite{
  // 共享的部分 內(nèi)部狀態(tài)
  public static String type;
  
  // 構(gòu)造
  public ConcreateWebSite(String type){
    this.type=type;
  }
  
  @Override
  void use(User user) {
    System.out.println(user.getName()+"正在使用,"+"發(fā)布形式是"+type);
  }
}

//工廠類
public class WebSiteFactory {

  // 集合,充當(dāng)池作用
  HashMap<String,ConcreateWebSite> pool=new HashMap<>();

  // 根據(jù)網(wǎng)站類型 返回網(wǎng)站 如果沒有則創(chuàng)建
  public WebSite getWebSiteCategory(String type){
    if (!pool.containsKey(type)){
      pool.put(type,new ConcreateWebSite(type));
    }
    // 返回的是子類 需要變成父類
    return (WebSite) pool.get(type);
  }

  // 查看網(wǎng)站的個數(shù)
  public int getSite(){
    return pool.size();
  }
}

class Test {
  void test() {
    // 創(chuàng)建工廠類
    WebSiteFactory factory=new WebSiteFactory();

    // 客戶需要以網(wǎng)站形式發(fā)布
    WebSite webSite1 = factory.getWebSiteCategory("網(wǎng)站");
    webSite1.use(new User("小明"));

    // 以博客的形式發(fā)布
    WebSite webSite2 = factory.getWebSiteCategory("博客");
    webSite2.use(new User("小李"));

    WebSite webSite3 = factory.getWebSiteCategory("博客");
    webSite3.use(new User("小藝"));
  }
}

組合模式

組合模式的定義是一種將對象組合成樹狀的層次結(jié)構(gòu)的模式,用來表示“整體-部分”的關(guān)系,使用戶對單個對象和組合對象具有一致的訪問性。

//抽象構(gòu)件
interface Component {
  public void add(Component c);
  public void remove(Component c);
  public Component getChild(int i);
  public void operation();
}

//樹葉構(gòu)件
class Leaf implements Component {
  private String name;
  public Leaf(String name) {
    this.name = name;
  }
  public void add(Component c) {
  }
  public void remove(Component c) {
  }
  public Component getChild(int i) {
    return null;
  }
  public void operation() {
    System.out.println("樹葉" + name + ":被訪問!");
  }
}

//樹枝構(gòu)件
class Composite implements Component {
  private ArrayList<Component> children = new ArrayList<Component>();
  public void add(Component c) {
    children.add(c);
  }
  public void remove(Component c) {
    children.remove(c);
  }
  public Component getChild(int i) {
    return children.get(i);
  }
  public void operation() {
    for (Object obj : children) {
      ((Component) obj).operation();
    }
  }
}

行為型模式

行為型模式用于描述程序在運(yùn)行時復(fù)雜的流程控制,即描述多個類或?qū)ο笾g怎樣相互協(xié)作共同完成單個對象都無法單獨(dú)完成的任務(wù),它涉及算法與對象間職責(zé)的分配。

模版方法模式

模板方法模式的定義如下:定義一個操作中的算法骨架,而將算法的一些步驟延遲到子類中,使得子類可以不改變該算法結(jié)構(gòu)的情況下重定義該算法的某些特定步驟。

//抽象類
abstract class AbstractClass {
  //模板方法
  public void TemplateMethod() {
    abstractMethod1();
    abstractMethod2();
    SpecificMethod();
  }
  
  //具體方法
  public void SpecificMethod() {
    System.out.println("抽象類中的具體方法被調(diào)用...");
  }
  //抽象方法1
  public abstract void abstractMethod1();
  //抽象方法2
  public abstract void abstractMethod2();
}
//具體子類
class ConcreteClass extends AbstractClass {
  public void abstractMethod1() {
    System.out.println("抽象方法1的實(shí)現(xiàn)被調(diào)用...");
  }
  public void abstractMethod2() {
    System.out.println("抽象方法2的實(shí)現(xiàn)被調(diào)用...");
  }
}

策略模式

策略模式的定義:該模式定義了一系列算法,并將每個算法封裝起來,使它們可以相互替換,且算法的變化不會影響使用算法的客戶。

//抽象策略類
interface Strategy {
  public void strategyMethod();    //策略方法
}

//具體策略類A
class ConcreteStrategyA implements Strategy {
  public void strategyMethod() {
    System.out.println("具體策略A的策略方法被訪問!");
  }
}
//具體策略類B
class ConcreteStrategyB implements Strategy {
  public void strategyMethod() {
    System.out.println("具體策略B的策略方法被訪問!");
  }
}
//環(huán)境類
class Context {
  private Strategy strategy;
  public Strategy getStrategy() {
    return strategy;
  }
  public void setStrategy(Strategy strategy) {
    this.strategy = strategy;
  }
  public void strategyMethod() {
    strategy.strategyMethod();
  }
}

class Test {
  void test() {
    Context c = new Context();
    Strategy s = new ConcreteStrategyA();
    c.setStrategy(s);
    c.strategyMethod();
    s = new ConcreteStrategyB();
    c.setStrategy(s);
    c.strategyMethod();
  }
}

命令模式

命令模式的定義如下:將一個請求封裝為一個對象,使發(fā)出請求的責(zé)任和執(zhí)行請求的責(zé)任分割開。這樣兩者之間通過命令對象進(jìn)行溝通,這樣方便將命令對象進(jìn)行儲存、傳遞、調(diào)用、增加與管理。

//調(diào)用者
class Invoker {
  private Command command;
  public Invoker(Command command) {
    this.command = command;
  }
  public void setCommand(Command command) {
    this.command = command;
  }
  public void call() {
    System.out.println("調(diào)用者執(zhí)行命令command...");
    command.execute();
  }
}
//抽象命令
interface Command {
  public abstract void execute();
}
//具體命令
class ConcreteCommand implements Command {
  private Receiver receiver;
  ConcreteCommand() {
    receiver = new Receiver();
  }
  public void execute() {
    receiver.action();
  }
}
//接收者
class Receiver {
  public void action() {
    System.out.println("接收者的action()方法被調(diào)用...");
  }
}

class Test {
  void test() {
    Command cmd = new ConcreteCommand();
    Invoker ir = new Invoker(cmd);
    System.out.println("客戶訪問調(diào)用者的call()方法...");
    ir.call();
  }
}

責(zé)任鏈模式

責(zé)任鏈模式的定義:為了避免請求發(fā)送者與多個請求處理者耦合在一起,于是將所有請求的處理者通過前一對象記住其下一個對象的引用而連成一條鏈;當(dāng)有請求發(fā)生時,可將請求沿著這條鏈傳遞,直到有對象處理它為止。

//抽象處理者角色
abstract class Handler {
  private Handler next;
  public void setNext(Handler next) {
    this.next = next;
  }
  public Handler getNext() {
    return next;
  }
  //處理請求的方法
  public abstract void handleRequest(String request);
}

//具體處理者角色1
class ConcreteHandler1 extends Handler {
  public void handleRequest(String request) {
    if (request.equals("one")) {
      System.out.println("具體處理者1負(fù)責(zé)處理該請求!");
    } else {
      if (getNext() != null) {
        getNext().handleRequest(request);
      } else {
        System.out.println("沒有人處理該請求!");
      }
    }
  }
}

//具體處理者角色2
class ConcreteHandler2 extends Handler {
  public void handleRequest(String request) {
    if (request.equals("two")) {
      System.out.println("具體處理者2負(fù)責(zé)處理該請求!");
    } else {
      if (getNext() != null) {
        getNext().handleRequest(request);
      } else {
        System.out.println("沒有人處理該請求!");
      }
    }
  }
}

狀態(tài)模式

狀態(tài)模式的定義:對有狀態(tài)的對象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對象中,允許狀態(tài)對象在其內(nèi)部狀態(tài)發(fā)生改變時改變其行為。

// 抽象狀態(tài)類
abstract class OrderState {
    protected OrderContext context;

    public void setContext(OrderContext context) {
        this.context = context;
    }

    public abstract void confirm();

    public abstract void modify();

    public abstract void ship();

    public abstract void complete();
}

// 待處理狀態(tài)類
class PendingState extends OrderState {
    public void confirm() {
        System.out.println("Order confirmed");
        context.setState(new ApprovedState());
    }

    public void modify() {
        System.out.println("Order modified");
    }

    public void ship() {
        System.out.println("Cannot ship an unapproved order");
    }

    public void complete() {
        System.out.println("Cannot complete an unshipped order");
    }
}

// 已審核狀態(tài)類
class ApprovedState extends OrderState {
    public void confirm() {
        System.out.println("Order already confirmed");
    }

    public void modify() {
        System.out.println("Order modified");
        context.setState(new PendingState());
    }

    public void ship() {
        System.out.println("Order shipped");
        context.setState(new ShippedState());
    }

    public void complete() {
        System.out.println("Cannot complete an unshipped order");
    }
}

// 已發(fā)貨狀態(tài)類
class ShippedState extends OrderState {
    public void confirm() {
        System.out.println("Order already confirmed");
    }

    public void modify() {
        System.out.println("Cannot modify a shipped order");
    }

    public void ship() {
        System.out.println("Order already shipped");
    }

    public void complete() {
        System.out.println("Order completed");
        context.setState(new CompletedState());
    }
}

// 已完成狀態(tài)類
class CompletedState extends OrderState {
    public void confirm() {
        System.out.println("Order already confirmed");
    }

    public void modify() {
        System.out.println("Cannot modify a completed order");
    }

    public void ship() {
        System.out.println("Cannot ship a completed order");
    }

    public void complete() {
        System.out.println("Order already completed");
    }
}

// 上下文類
class OrderContext {
    private OrderState state;

    public OrderContext() {
        state = new PendingState();
        state.setContext(this);
    }

    public void setState(OrderState state) {
        this.state = state;
        this.state.setContext(this);
    }

    public void confirm() {
        state.confirm();
    }

    public void modify() {
        state.modify();
    }

    public void ship() {
        state.ship();
    }

    public void complete() {
        state.complete();
    }
}

// 客戶端代碼
public class Client {
    public static void main(String[] args) {
        OrderContext context = new OrderContext();
        context.confirm();
        context.modify();
        context.confirm();
        context.ship();
        context.complete();
    }
}

觀察者模式

觀察者模式的定義:指多個對象間存在一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。

//抽象目標(biāo)
abstract class Subject {
  protected List<Observer> observers = new ArrayList<Observer>();
  //增加觀察者方法
  public void add(Observer observer) {
    observers.add(observer);
  }
  //刪除觀察者方法
  public void remove(Observer observer) {
    observers.remove(observer);
  }
  public abstract void notifyObserver(); //通知觀察者方法
}
//具體目標(biāo)
class ConcreteSubject extends Subject {
  public void notifyObserver() {
    System.out.println("具體目標(biāo)發(fā)生改變...");
    System.out.println("--------------");
    for (Object obs : observers) {
      ((Observer) obs).response();
    }
  }
}
//抽象觀察者
interface Observer {
  void response(); //反應(yīng)
}
//具體觀察者1
class ConcreteObserver1 implements Observer {
  public void response() {
    System.out.println("具體觀察者1作出反應(yīng)!");
  }
}
//具體觀察者2
class ConcreteObserver2 implements Observer {
  public void response() {
    System.out.println("具體觀察者2作出反應(yīng)!");
  }
}

中介者模式

中介者模式的定義:定義一個中介對象來封裝一系列對象之間的交互,它可以使得多個對象之間的交互變得更加靈活、簡單和可擴(kuò)展。中介者模式將多個對象之間的交互轉(zhuǎn)移給一個中介者對象來處理,從而將對象之間的耦合度降低到最低。
注意:觀察者模式是一對多的關(guān)系,而中介者模式是多對多的關(guān)系。

// 抽象中介者類
abstract class Mediator {
    public abstract void sendMessage(User user, String message);
}

// 具體中介者類
class ChatRoom extends Mediator {
    public void sendMessage(User user, String message) {
        System.out.println(user.getName() + " sends message: " + message);
        for (User u : users) {
            if (u != user) {
                u.receiveMessage(message);
            }
        }
    }
}

// 抽象用戶類
abstract class User {
    private String name;
    private Mediator mediator;

    public User(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }

    public String getName() {
        return name;
    }

    public void sendMessage(String message) {
        mediator.sendMessage(this, message);
    }

    public abstract void receiveMessage(String message);
}

// 具體用戶類
class ConcreteUser extends User {
    public ConcreteUser(String name, Mediator mediator) {
        super(name, mediator);
    }

    public void receiveMessage(String message) {
        System.out.println(getName() + " receives message: " + message);
    }
}

// 客戶端代碼
public class Client {
    public static void main(String[] args) {
        Mediator mediator = new ChatRoom();

        User user1 = new ConcreteUser("User1", mediator);
        User user2 = new ConcreteUser("User2", mediator);
        User user3 = new ConcreteUser("User3", mediator);

        user1.sendMessage("Hello, everyone!");
        user2.sendMessage("Hi, User1!");
        user3.sendMessage("Hey, guys!");
    }
}

迭代器模式

迭代器模式的定義:提供一個對象來順序訪問聚合對象中的一系列數(shù)據(jù),而不暴露聚合對象的內(nèi)部表示。

// 抽象聚合
interface Aggregate {
  public void add(Object obj);
  public void remove(Object obj);
  public Iterator getIterator();
}
// 具體聚合
class ConcreteAggregate implements Aggregate {
  private List<Object> list = new ArrayList<Object>();
  public void add(Object obj) {
    list.add(obj);
  }
  public void remove(Object obj) {
    list.remove(obj);
  }
  public Iterator getIterator() {
    return (new ConcreteIterator(list));
  }
}
// 抽象迭代器
interface Iterator {
  Object first();
  Object next();
  boolean hasNext();
}
// 具體迭代器
class ConcreteIterator implements Iterator {
  private List<Object> list = null;
  private int index = -1;
  public ConcreteIterator(List<Object> list) {
    this.list = list;
  }
  public boolean hasNext() {
    if (index < list.size() - 1) {
      return true;
    } else {
      return false;
    }
  }
  public Object first() {
    index = 0;
    Object obj = list.get(index);
    return obj;
  }
  public Object next() {
    Object obj = null;
    if (this.hasNext()) {
      obj = list.get(++index);
    }
    return obj;
  }
}

備忘錄模式

備忘錄模式的定義:在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài),以便以后當(dāng)需要時能將該對象恢復(fù)到原先保存的狀態(tài)。

//備忘錄
class Memento {
  private String state;
  public Memento(String state) {
    this.state = state;
  }
  public void setState(String state) {
    this.state = state;
  }
  public String getState() {
    return state;
  }
}
//發(fā)起人
class Originator {
  private String state;
  public void setState(String state) {
    this.state = state;
  }
  public String getState() {
    return state;
  }
  public Memento createMemento() {
    return new Memento(state);
  }
  public void restoreMemento(Memento m) {
    this.setState(m.getState());
  }
}
//管理者
class Caretaker {
  private Memento memento;
  public void setMemento(Memento m) {
    memento = m;
  }
  public Memento getMemento() {
    return memento;
  }
}

class Test {
  void test() {
    Originator or = new Originator();
    Caretaker cr = new Caretaker();
    or.setState("S0");
    System.out.println("初始狀態(tài):" + or.getState());
    cr.setMemento(or.createMemento()); //保存狀態(tài)
    or.setState("S1");
    System.out.println("新的狀態(tài):" + or.getState());
    or.restoreMemento(cr.getMemento()); //恢復(fù)狀態(tài)
    System.out.println("恢復(fù)狀態(tài):" + or.getState());
  }
}

訪問者模式

訪問者模式的定義:將作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作分離出來封裝成獨(dú)立的類,使其在不改變數(shù)據(jù)結(jié)構(gòu)的前提下可以添加作用于這些元素的新的操作,為數(shù)據(jù)結(jié)構(gòu)中的每個元素提供多種訪問方式。

// 訪問者接口
interface Visitor {
    void visit(ConcreteElementA elementA);
    void visit(ConcreteElementB elementB);
}

// 具體訪問者A
class ConcreteVisitorA implements Visitor {
    public void visit(ConcreteElementA elementA) {
        System.out.println("Visitor A visits Element A");
    }

    public void visit(ConcreteElementB elementB) {
        System.out.println("Visitor A visits Element B");
    }
}

// 具體訪問者B
class ConcreteVisitorB implements Visitor {
    public void visit(ConcreteElementA elementA) {
        System.out.println("Visitor B visits Element A");
    }

    public void visit(ConcreteElementB elementB) {
        System.out.println("Visitor B visits Element B");
    }
}

// 元素接口
interface Element {
    void accept(Visitor visitor);
}

// 具體元素A
class ConcreteElementA implements Element {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationA() {
        System.out.println("Element A operation");
    }
}

// 具體元素B
class ConcreteElementB implements Element {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void operationB() {
        System.out.println("Element B operation");
    }
}

// 對象結(jié)構(gòu)類
class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void attach(Element element) {
        elements.add(element);
    }

    public void detach(Element element) {
        elements.remove(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}

// 客戶端代碼
public class Client {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();

        ConcreteElementA elementA = new ConcreteElementA();
        ConcreteElementB elementB = new ConcreteElementB();

        objectStructure.attach(elementA);
        objectStructure.attach(elementB);

        Visitor visitorA = new ConcreteVisitorA();
        Visitor visitorB = new ConcreteVisitorB();

        elementA.accept(visitorA);
        elementA.accept(visitorB);

        elementB.accept(visitorA);
        elementB.accept(visitorB);
    }
}

解釋器模式

解釋器模式的定義:給分析對象定義一個語言,并定義該語言的文法表示,再設(shè)計(jì)一個解析器來解釋語言中的句子。也就是說,用編譯語言的方式來分析應(yīng)用中的實(shí)例。這種模式實(shí)現(xiàn)了文法表達(dá)式處理的接口,該接口解釋一個特定的上下文。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容