国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

好久不見,Java設(shè)計(jì)模式

alexnevsky / 1731人閱讀

摘要:享元模式享元模式盡可能的讓用戶復(fù)用已經(jīng)有的對(duì)象,從而避免造成反復(fù)創(chuàng)建對(duì)象的資源浪費(fèi)。享元模式要求大部分的對(duì)象可以外部化。

引子

設(shè)計(jì)模式是很多程序員總結(jié)出來的最佳實(shí)踐。曾經(jīng)在剛開始寫項(xiàng)目的時(shí)候?qū)W習(xí)過設(shè)計(jì)模式,在開發(fā)過程中,也主動(dòng)或者被動(dòng)的使用過。現(xiàn)在寫代碼雖說不會(huì)特意明確在用哪種設(shè)計(jì)模式,但潛移默化的寫出來公認(rèn)的最佳實(shí)踐代碼,畢竟看的比較清爽。為什么再看一遍設(shè)計(jì)模式,主要有幾個(gè)原因:第一,很多優(yōu)秀的源碼基本都使用了設(shè)計(jì)模式,明確設(shè)計(jì)模式能夠更好的看源碼。第二,很多中間件設(shè)計(jì)理念也是基于設(shè)計(jì)模式的,還有其他的語(yǔ)言,都有自己的設(shè)計(jì)最佳實(shí)踐。對(duì)于我來說,設(shè)計(jì)模式始于java,不止于java。第三,有了這種規(guī)范,可以更好的和他人溝通,言簡(jiǎn)意賅。

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

很多優(yōu)秀的文章和書籍都講的很明白了,我說下自己的體會(huì)。
1.單一職責(zé)原則,就是一個(gè)類只負(fù)責(zé)做一件事情。這樣就可以做到解耦合的效果,讓代碼看起來比較清爽,也體現(xiàn)了java的封裝性。還有個(gè)原則叫迪米特法則,就是一個(gè)對(duì)象對(duì)另一個(gè)對(duì)象有盡量少的了解,說的也是解耦合的事情。
2.里氏替換原則和依賴導(dǎo)致原則,說的是繼承的事情。父類可以做的事情,子類都可以去做,子類可以盡量去依賴父類去做事情;但是反過來,父類不能依賴子類去做一些事情。體現(xiàn)了java的繼承特性。
3.接口隔離原則,接口也應(yīng)該盡可能的隔離開來。其實(shí)類寫多了,的確耦合性低,為了讓他們交流起來,用的最多的就是接口,畢竟只需要知道做什么,怎么做,去訪問那個(gè)具體的類吧。
4.開閉原則,對(duì)修改關(guān)閉,對(duì)拓展開放。就是代碼需要有很好的延展性,對(duì)原有代碼結(jié)構(gòu)不能破壞。

創(chuàng)建者模式

創(chuàng)建者模式就是為了用優(yōu)雅的方式創(chuàng)建我們使用的類。

1.簡(jiǎn)單工廠模式

這個(gè)用的比較少,就是有個(gè)工廠,告訴你我要什么東西,你造好了給我就行。比如說:

public interface Ball {
    public String create();
}
public class Soccer implements Ball {
    @Override
    public String create() {
        return "give you a soccer";
    }
}
public class BasketBall implements Ball {
    @Override
    public String create() {
        return "give you a basketBall";
    }
}
public class EasyBallFactory  {
    public static Ball createBall(String name){
        if (name.equals("basketball")){
            return new BasketBall();
        }else if(name.equals("soccer")){
            return new Soccer();
        }else {
            return null;
        }
    }
    public static void main(String[] args) {
        Ball soccer = EasyBallFactory.createBall("soccer");
        Ball basketBall = EasyBallFactory.createBall("basketball");
        System.out.println(soccer.create()); //give you a soccer
        System.out.println(basketBall.create()); //give you a basketBall
    }
}
2.工廠模式

這個(gè)其實(shí)和簡(jiǎn)單工廠模式差不太多,就是將工廠繼續(xù)拆分,比如說剛剛EasyBallFactory是一個(gè)總工廠,我們現(xiàn)在拆分成SoccerFactory和BasketBallFactory分別生產(chǎn)足球和籃球。某個(gè)工廠內(nèi)部可以根據(jù)需求生產(chǎn)不同的產(chǎn)品,比如說soccer可以生產(chǎn)不同大小的出來。

public interface BallFactory {
    public Ball create();
}
public class SoccerFactory implements BallFactory {
    @Override
    public Ball create() {
        //do something
        return null;
    }
}
public class BasketBallFactory implements BallFactory {
    @Override
    public Ball create() {
        //do something
        return null;
    }
}
3.抽象工廠模式

抽象工廠模式主要設(shè)計(jì)產(chǎn)品組的概念,就是某一個(gè)工廠生產(chǎn)出配套的一系列產(chǎn)品。例如,在生產(chǎn)足球的同時(shí),SoccerFactory還可以生產(chǎn)與之配套的足球雜志。

public interface Journal {
    public String create();
}
public class SoccerJournal implements Journal{
    @Override
    public String create() {
        return "give you a Soccer Journal...";
    }
}
public class SoccerFactory implements BallFactory {
    @Override
    public Ball create() {
        return new Soccer();
    }
    public Journal createJournal(){
        return new SoccerJournal();
    }
}
4.單例模式

單例模式有很多種形式,最佳實(shí)踐應(yīng)該是兩重判斷,保證只new出來一個(gè)。單例可以說是非常普遍的設(shè)計(jì)模式了。單例就是指在服務(wù)容器的生命周期中只能有這么一個(gè)。比如說Servlet、Spring中注入的Bean等等都是單例的。

public class ShiroUtils {
    public  static Session session;
    public static Session getSession() {
        if (session == null){
            synchronized(ShiroUtils.class){
                if (session == null){
                    session = SecurityUtils.getSubject().getSession();
                }
            }
        }
        return session;
    }
}
5.建造者模式

將一個(gè)復(fù)雜對(duì)象分布創(chuàng)建。如果一個(gè)超大的類的屬性特別多,我們可以把屬性分門別類,不同屬性組成一個(gè)稍微小一點(diǎn)的類,再把好幾個(gè)稍微小點(diǎn)的類竄起來。比方說一個(gè)電腦,可以分成不同的稍微小點(diǎn)的部分CPU、主板、顯示器。CPU、主板、顯示器分別有更多的組件,不再細(xì)分。

@Data
public class Computer{
    private CPU cpu;//cpu 是個(gè)接口,有不同實(shí)現(xiàn)如InterCPU AMDCPU 等等
    private MainBoard mainBoard;//mainBoard 是個(gè)接口,有不同的實(shí)現(xiàn)
    private DisPlayer disPlayer;//disPlayer 是個(gè)接口,有不同的實(shí)現(xiàn)
}
public abstract class Builder { 
    abstract void buildCPU(); 
    abstract void buildMainBoard(); 
    abstract void buildDisPlayer(); 
    abstract Computer createComputer(); 
} 
public class XiaoMiBuilder extends Builder{
    private Computer computer = new Computer();
    @Override
    void buildCPU() {
        computer.setCpu(new InterCPU());
    }
    @Override
    void buildMainBoard() {
        computer.setMainBoard(new AMainBoard());
    }
    @Override
    void buildDisPlayer() {
        computer.setDisPlayer(new ADisPlayer());
    }
    @Override
    Computer createComputer() {
        return computer;
    }
}

SpringBoot實(shí)現(xiàn)了0配置,幾乎所有的配置都寫到了java代碼中,大量的配置不得不讓配置類采用建造者模式,這樣層次比較清晰。

6.原型模式

原型模式用的比較少,用于創(chuàng)建重復(fù)對(duì)象。需要實(shí)現(xiàn)Cloneable 可以選擇重寫clone()方法。clone分為淺克隆和深克隆。淺克隆只是克隆引用,對(duì)象還是一個(gè)。深克隆是對(duì)象也新創(chuàng)建了一個(gè),如下:

@Data
@Builder
public class User implements Cloneable{
    private String name;
    private int age;
    @Override
    protected User clone() throws CloneNotSupportedException {
        return new User(this.name,this.age);
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        User user1 = new User("pjjlt",25);
        User user2 = user1.clone();
        user1.setAge(18);
        System.out.println(user2.getAge()); //25
    }
}
結(jié)構(gòu)型模式

上面的設(shè)計(jì)模式可以幫助我們非常優(yōu)雅的創(chuàng)建出來對(duì)象,下面看幾個(gè)對(duì)象關(guān)系之間的模型。

7.代理模式

Spring的AOP用的是動(dòng)態(tài)代理,何為動(dòng)態(tài)不看了,用過Spring的小伙伴都知道吧。單純看一下最基礎(chǔ)代理模式是什么樣的。代理就是,一個(gè)對(duì)象輔助另一個(gè)對(duì)象去做某件事,同時(shí)還可以增加一點(diǎn)輔助功能。例如,你買車,的確是你花錢把車買到了,但是你不可能直接去和廠家談吧,你應(yīng)該通過4S店購(gòu)買,同時(shí)4S店幫助你入保險(xiǎn)扣稅等操作,最終你才得到了你想要的車。

public interface Buy {
    public void buyCar();
}
public class People implements Buy {
    @Override
    public void buyCar() {
        System.out.println("you get a car");
    }
}
public class ProxyPeople implements Buy{
    private People people;
    public ProxyPeople(People people){
        this.people=people;
    }
    @Override
    public void buyCar() {
        System.out.println("4s店幫你納稅、上保險(xiǎn)...");
        people.buyCar();
    }
    public static void main(String[] args) {
        Buy buy = new ProxyPeople(new People());
        buy.buyCar();
    }
}
//輸出:
4s店幫你納稅、上保險(xiǎn)...
you get a car
8.適配器模式

適配器,顧名思義,是讓兩個(gè)不兼容的東西可以一起工作。例如插座的電源是220V,手機(jī)直接給他220V 50HZ的交流電我相信一般都會(huì)直接炸了(除了諾基亞...)手機(jī)充電器就進(jìn)行了適配,將電壓變小,交流電變成直流電。除了這種需要改變屬性的操作(比較好說,不舉例子了),適配器還用于在接口繼承方面。假設(shè)一個(gè)頂級(jí)接口有一大堆方法需要實(shí)現(xiàn)類實(shí)現(xiàn),我新寫了個(gè)類只是想選擇的實(shí)現(xiàn)一兩個(gè)接口,那其他的方法我是不是都需要實(shí)現(xiàn)一下,即使是空實(shí)現(xiàn)(單純實(shí)現(xiàn),不進(jìn)行任何邏輯操作),這是我們就需要一個(gè)適配器類,空實(shí)現(xiàn)那些方法,我的新類只需要繼承這個(gè)適配器類就好了,要是想實(shí)現(xiàn)某個(gè)方法,只需要重寫掉配置類中對(duì)應(yīng)的方法就好。這種模式基本都會(huì)用到,畢竟誰(shuí)的代碼還沒個(gè)頂級(jí)接口啊。

public interface ATopIntf {
    public void one();
    public void two();
    public void three();
}
public class Adapter implements ATopIntf {
    @Override
    public void one() { }
    @Override
    public void two() { }
    @Override
    public void three() { }
}
public class You extends Adapter {
    @Override
    public void one() {
        super.one();
        System.out.println("one");
    }
}
9.橋接模式

就是用于抽象化和實(shí)現(xiàn)化的解耦。又是解耦,貌似設(shè)計(jì)模式就是教我們?nèi)绾蝺?yōu)雅的解耦。提高了代碼的拓展性,并且可以實(shí)現(xiàn)代碼的動(dòng)態(tài)切換。
最開始的Ball、Soccer、BasketBall接著用,增加新的類

public  class BallCut {
    private Ball ball;
    public Ball getBall() {
        return ball;
    }
    public void setBall(Ball ball) {
        this.ball = ball;
    }
    public void create(){
         System.out.println(ball.create());
    }
    public static void main(String[] args) {
        BallCut ballCut = new BallCut();
        ballCut.setBall(new Soccer());
        ballCut.create(); //give you a soccer
        ballCut.setBall(new BasketBall());
        ballCut.create(); //give you a basketBall
    }
}
10.裝飾模式

一個(gè)裝飾類,在原來類的基礎(chǔ)上增加一點(diǎn)功能。是不是和代理模式很像,我甚至可以將整個(gè)代碼搬過來照樣可以說的通的。這兩個(gè)模式意思上有點(diǎn)差別,代理模式是原對(duì)象做不了那件事,必須讓代理對(duì)象去做,主導(dǎo)側(cè)重于代理對(duì)象,比如說買車。裝飾模式是說,就是讓原對(duì)象直接去做這件事,只是功能上增強(qiáng)一點(diǎn),主導(dǎo)在于原對(duì)象。比如說炒菜的時(shí)候撒點(diǎn)鹽。

11.外觀模式

又稱門面模式,就是一個(gè)門面,一個(gè)操作無(wú)需讓對(duì)象知道其內(nèi)部實(shí)現(xiàn)的復(fù)雜度,盡量讓用戶感知到是非常簡(jiǎn)單的。這就是為什么我們controller層盡量(或者說一定)少些業(yè)務(wù)邏輯,讓controller層只是起到一個(gè)傳參和通用性參數(shù)校驗(yàn)的功能,剩下的全交給service去做吧。我們還需要在代碼中不斷將“長(zhǎng)得”特別長(zhǎng)的代碼封裝成一個(gè)方法,“讓處處都有好看的外觀”。看一下我們?cè)鴮戇^的代碼,這里只起到了傳參的作用,究竟這個(gè)足球是怎么創(chuàng)建出來的,客戶端不必?fù)?dān)心。

   public static void main(String[] args) {
        Ball soccer = EasyBallFactory.createBall("soccer");
        System.out.println(soccer.create()); //give you a soccer
    }
12.組合模式

組合模式是將存在某種包含關(guān)系的數(shù)據(jù)組織在一起,典型的例子就是樹狀結(jié)構(gòu)。例如菜單功能,一個(gè)菜單除了自己該有的屬性,還可能包含子菜單,創(chuàng)建的時(shí)候可以使用遞歸的方法。

@Data
public class Menu{
    private String name;
    private int type;
    private List childMenus;
}
13.享元模式

享元模式盡可能的讓用戶復(fù)用已經(jīng)有的對(duì)象,從而避免造成反復(fù)創(chuàng)建對(duì)象的資源浪費(fèi)。首先就會(huì)想到數(shù)據(jù)庫(kù)連接池還有String常量池,延伸一下,幾乎所有和緩存有關(guān)的代碼,多少都會(huì)用到享元模式。享元模式要求大部分的對(duì)象可以外部化。這邊要說兩個(gè)概念,享元模式對(duì)象的屬性可以分為兩個(gè)部分,內(nèi)部狀態(tài)和外部狀態(tài),內(nèi)部狀態(tài)是指不會(huì)隨環(huán)境而改變的值,比如說個(gè)人信息,外部狀態(tài)是指隨環(huán)境改變的值,不能進(jìn)行共享的信息,如某大學(xué)生選修的課程。

public abstract class Flyweight {
    //內(nèi)部狀態(tài)
    private String name;
    private String age;
    //外部狀態(tài)
    private final String subject;
    protected Flyweight(String subject) {
        this.subject = subject;
    }
    //行為
    public abstract void exam();
    public String getSubject() {
        return subject;
    }
}
public class RealFlyweight extends Flyweight {
    @Override
    public void exam() {
        System.out.println(this.getSubject()+" is examing...");
    }
    public RealFlyweight(String subject){
        super(subject);
    }
}
public class FlyweightFactory {
    //定義一個(gè)池子
    private static HashMap pool= new HashMap();
    public static Flyweight getFlyweight(String subject){
        Flyweight flyweight =null;
        if (pool.containsKey(subject)){
            flyweight=pool.get(subject);
        }else {
            flyweight = new RealFlyweight(subject);
            pool.put(subject,flyweight);
        }
        return flyweight;
    }
    public static void main(String[] args) {
        System.out.println(pool.size());//0
        getFlyweight("math");
        System.out.println(pool.size());//1
        getFlyweight("english");
        System.out.println(pool.size());//2
        getFlyweight("math");
        System.out.println(pool.size());//2
    }
}
行為型模式

創(chuàng)建了對(duì)象,對(duì)象之間有了結(jié)構(gòu)關(guān)系,就要看下怎么更加優(yōu)雅的相互作用了。

14.策略模式

定義一組算法, 將每個(gè)算法都封裝起來, 并且使它們之間可以互換。可以說是一組算法的封裝,根據(jù)客戶端給出的不同要求,進(jìn)行不同的運(yùn)算。比如下面這個(gè)簡(jiǎn)易計(jì)算器。

public interface Strategy {
   public int doOperation(int num1, int num2);
}
public class OperationAdd implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 + num2;
   }
}
public class OperationSubstract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}
public class Context {
   private Strategy strategy;
   public Context(Strategy strategy){
      this.strategy = strategy;
   }
   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}
public class StrategyPatternDemo {
   public static void main(String[] args) {
      Context context = new Context(new OperationAdd());    
      System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
      context = new Context(new OperationSubstract());      
      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
   }
}
15.觀察者模式

定義了一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象(被觀察者)狀態(tài)改變的時(shí)候,所有依賴于該對(duì)象的觀察者都會(huì)被通知,從而進(jìn)行相關(guān)操作。很多中間件都依賴于觀察者模式,例如RabbitMQ,還有那些事件驅(qū)動(dòng)模型(好像node就是)。下面舉個(gè)例子,被觀察者是監(jiān)考老師,考試時(shí)間結(jié)束,通知所有觀察者學(xué)生上交試卷。

@Data
public class Student {
    private String name;
    public Student(String name){
        this.name=name;
    }
    public void dosomething(){
        System.out.println(getName()+"交卷了");
    }
}
public class Teacher {
    private Set students = new HashSet<>();
    public void addStudent(Student student){
        students.add(student);
    }
    public void removeStudent(Student student){
        students.remove(student);
    }
    public void doNotify(){
        for(Student student:students){
            student.dosomething();
        }
    }
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        Student student = new Student("張三");
        Student student1 = new Student("李四");
        teacher.addStudent(student);
        teacher.addStudent(student1);
        teacher.doNotify();
    }
}
16.責(zé)任鏈模式

責(zé)任鏈模式為請(qǐng)求創(chuàng)建一個(gè)接收者對(duì)象的鏈,對(duì)發(fā)送者和接受者進(jìn)行解耦合。filter鏈就是責(zé)任鏈模式。

public abstract class Handler {
    //下一個(gè)處理者
    private Handler nextHandler;
    public final Response handleMessage(Request request){
        Response response =null;
        if (this.getHandlerLevel().equals(request.getRequestLevel())){
            response = this.echo(request);
        }else {
            if (this.nextHandler!=null){
                //傳遞給下一個(gè)
                response = this.nextHandler.handleMessage(request);
            }else {
                response =new Response()
            }
        }
        return response;
    }
    public Handler getNextHandler() {
        return nextHandler;
    }
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
    protected abstract Level getHandlerLevel();
    protected abstract Response echo(Request request);
}
17.模板方式模式

一個(gè)抽象類公開定義了執(zhí)行它的方法的方式/模板。它的子類可以按需要重寫方法實(shí)現(xiàn),但調(diào)用將以抽象類中定義的方式進(jìn)行。SpringBoot為用戶封裝了很多繼承代碼,都用到了模板方式,例如那一堆XXXtemplate。

public abstract class DBTemplate {
    abstract void open();
    abstract void select();
    abstract void close();
    //一個(gè)搜索模板
    public final void selectTemplate(){
        open();
        select();
        close();
    }
}
public class MysqlDB extends DBTemplate {
    @Override
    void open() {
        System.out.println("Mysql open...");
    }
    @Override
    void select() {
        System.out.println("Mysql select...");
    }
    @Override
    void close() {
        System.out.println("Mysql close...");
    }

    public static void main(String[] args) {
        DBTemplate mysql = new MysqlDB();
        mysql.selectTemplate();
    }
}
18.狀態(tài)模式

簡(jiǎn)單來說,就是一個(gè)對(duì)象有不同的狀態(tài),根據(jù)狀態(tài)不同,可能有不同的行為。

public interface State {
   public void doAction(Context context);
}
public class StartState implements State {
   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this); 
   }
   public String toString(){
      return "Start State";
   }
}
public class StopState implements State {
   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      context.setState(this); 
   }
   public String toString(){
      return "Stop State";
   }
}
public class Context {
   private State state;
   public Context(){
      state = null;
   }
   public void setState(State state){
      this.state = state;     
   }
   public State getState(){
      return state;
   }
}
public class StatePatternDemo {
   public static void main(String[] args) {
      Context context = new Context();
      StartState startState = new StartState();
      startState.doAction(context);
      System.out.println(context.getState().toString());
      StopState stopState = new StopState();
      stopState.doAction(context);
      System.out.println(context.getState().toString());
   }
}
19.迭代器模式

提供一個(gè)方法,可以順序訪問一個(gè)對(duì)象內(nèi)部的各個(gè)元素,不需要知道內(nèi)部構(gòu)造。現(xiàn)在基本很少自己實(shí)現(xiàn)迭代器了,基本成熟的框架或者強(qiáng)大的JDK都會(huì)給出訪問的方法,比如說java中iterator。這樣做主要是進(jìn)一步封裝對(duì)象內(nèi)部的結(jié)構(gòu),讓行為和結(jié)構(gòu)想耦合。這個(gè)不舉例子了,用過iterator這個(gè)的小伙伴應(yīng)該都清楚,就是不停的next,去訪問下一個(gè)元素。

20.命令模式

命令模式是將請(qǐng)求以命令的形式包裹在對(duì)象中,并傳遞給對(duì)象,調(diào)用對(duì)象尋找到處理該命令的合適的對(duì)象,并將該命令傳遞給相應(yīng)的對(duì)象,該對(duì)象執(zhí)行。簡(jiǎn)單點(diǎn)說就是不同請(qǐng)求都封裝成一個(gè)對(duì)象,不同的請(qǐng)求調(diào)用不同的執(zhí)行者。

//真正干活的對(duì)象
public class Receiver {
    public void doSomething(){
        System.out.println("Receiver干活");
    }
}
//命令對(duì)象
public abstract class Command {
    public abstract void exectue();
}
//命令實(shí)現(xiàn)類
public class ConcreteComand extends Command{
    //干活那個(gè)
    private Receiver receiver;
    public ConcreteComand(Receiver receiver) {
        this.receiver = receiver;
    }
    @Override
    public void exectue() {
        this.receiver.doSomething();
    }

    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Command command =new ConcreteComand(receiver);
        command.exectue();//Receiver干活
    }
}
21.備忘錄模式

相當(dāng)于做一個(gè)快照,在不破壞對(duì)象本身結(jié)構(gòu)的情況下,記錄對(duì)象的一個(gè)狀態(tài),合適的時(shí)候可以恢復(fù)到這種狀態(tài)。數(shù)據(jù)庫(kù)做事務(wù)回滾的時(shí)候就用了這種方式。這里需要注意的是,對(duì)象不與備忘錄本身耦合,而是跟備忘錄管理類耦合(就是List<備忘錄>),這個(gè)好理解,畢竟快照不止一個(gè)嘛。

@Data//備忘錄
public class Memento {
   private String state; 
}
@Data //某對(duì)象
public class Originator {
   private String state;
   public Memento saveStateToMemento(){
      return new Memento(state);
   }
   public void getStateFromMemento(Memento Memento){
      state = Memento.getState();
   }
}
//備忘錄管理類
public class CareTaker {
   private List mementoList = new ArrayList();
   public void add(Memento state){
      mementoList.add(state);
   }
   public Memento get(int index){
      return mementoList.get(index);
   }
   public static void main(String[] args) {
      Originator originator = new Originator();
      CareTaker careTaker = new CareTaker();
      originator.setState("State #1");
      originator.setState("State #2");
      careTaker.add(originator.saveStateToMemento());
      originator.setState("State #3");
      careTaker.add(originator.saveStateToMemento());
      originator.setState("State #4");
      System.out.println("Current State: " + originator.getState());    
      originator.getStateFromMemento(careTaker.get(0));
      System.out.println("First saved State: " + originator.getState());
      originator.getStateFromMemento(careTaker.get(1));
      System.out.println("Second saved State: " + originator.getState());
   }
}
22.訪問者模式

當(dāng)對(duì)特定角色進(jìn)行訪問的時(shí)候,需要通過訪問者進(jìn)行訪問。一個(gè)對(duì)象不太方便被你直接訪問的時(shí)候,你需要將自己的引用交給訪問者,通過訪問者去訪問該對(duì)象。比如說,化學(xué)課,想看一個(gè)細(xì)胞結(jié)構(gòu),由于肉眼無(wú)法直接看到微觀世界的玩意,需要通過顯微鏡間接訪問。

23.中介者模式

降低對(duì)象或者說事物之間通訊的復(fù)雜性,降低耦合。比如說分布式系統(tǒng)中,不是需要實(shí)時(shí)反饋的操作,我們無(wú)需直接對(duì)接,只需將想做的事告訴中間件,中間件告訴另外一個(gè)系統(tǒng)。比如說,訪問(用戶點(diǎn)擊)一條新聞操作,同時(shí)需要記錄是誰(shuí)訪問了什么新聞,同時(shí)給新聞瀏覽次數(shù)加1,還要實(shí)時(shí)更新用戶喜好...總之要更新n個(gè)數(shù)據(jù)庫(kù)表,甚至還要操作像ES,Mongo等多個(gè)中間件數(shù)據(jù)。但是對(duì)于用戶來說,我只是做了一個(gè)點(diǎn)擊操作,希望得到的結(jié)果就是看條新聞啊,你這么多操作,搞這么慢,用戶體驗(yàn)很差啊,而且并發(fā)量也很低,那不如做成兩個(gè)小系統(tǒng),A系統(tǒng),拉取新聞,推送,并組裝一個(gè)信息扔給MQ中間件,ok,結(jié)束,用戶看到新聞。然后B系統(tǒng)監(jiān)聽,得到這個(gè)消息,進(jìn)行各種更新,這里,這個(gè)中間件就是我們的中介。再比如說,MVC中的控制層就是展示層和模型層的中介。再比如說,下面這個(gè)聊天室:

public class ChatRoom {
   public static void showMessage(User user, String message){
      System.out.println(new Date().toString()
         + " [" + user.getName() +"] : " + message);
   }
}
@Data
public class User {
   private String name;
   public User(String name){
      this.name  = name;
   }
   public void sendMessage(String message){
      ChatRoom.showMessage(this,message);
   }
   public static void main(String[] args) {
      User robert = new User("Robert");
      User john = new User("John");
 
      robert.sendMessage("Hi! John!");
      john.sendMessage("Hello! Robert!");
   }
}
24.解釋器模式

構(gòu)建一種翻譯方式,將某種語(yǔ)言或描述翻譯成我們很好理解的語(yǔ)言或者描述。這里很好理解的意思是看得懂,看的快。本來我也想舉什么編譯器這種高大上的,將底層語(yǔ)言甚至機(jī)械語(yǔ)言和我們使用的高級(jí)編程語(yǔ)言。后來想了想,其實(shí)Map就可以看作一個(gè)很好的編譯器,key你可以存放一個(gè)非常小的字符串,value理論上你可以存放任何東西,所以代碼就不寫了。

結(jié)束語(yǔ)

嗚呼,廢了好長(zhǎng)的時(shí)間,終于把這些設(shè)計(jì)模式有回顧了一遍,感覺對(duì)他們其中的某些有了更深刻的理解吧。就把這篇文章當(dāng)作自己的一個(gè)小字典吧,將來需要什么看什么,點(diǎn)看看一看,順便可以繼續(xù)豐富下內(nèi)容。有些東西就該自己去記錄一下,畢竟好記性不如爛筆頭嘛。又快十一點(diǎn)了,睡覺...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/75301.html

相關(guān)文章

  • AJAX的出現(xiàn)與跨域處理

    摘要:屬性是此次響應(yīng)的文本內(nèi)容。我們可以通過屬性,指定這個(gè)事件的回調(diào)函數(shù),對(duì)不同狀態(tài)進(jìn)行不同處理。尤其是當(dāng)狀態(tài)變?yōu)榈臅r(shí)候,表示通信成功,這時(shí)回調(diào)函數(shù)就可以處理服務(wù)器傳送回來的數(shù)據(jù)。由于臨時(shí)的服務(wù)器維護(hù)或者過載,服務(wù)器當(dāng)前無(wú)法處理請(qǐng)求。 XMLHttpRequest JSON AJAX CORS 四個(gè)名詞來開會(huì) 如何發(fā)請(qǐng)求 在前端的世界里也逛蕩了不少日子了,目前已經(jīng)get到大約5種發(fā)起請(qǐng)求...

    RancherLabs 評(píng)論0 收藏0
  • 傻瓜式學(xué)Python3——列表

    摘要:列表是編程中使用頻率極高的數(shù)據(jù)結(jié)構(gòu),由一系列按特定順序排列的元素組成,用表示,逗號(hào)分隔元素,類似中的數(shù)組。由于列表包含多個(gè)元素,所以通常命名為復(fù)數(shù)形式,如,等。使用切片裁剪獲取子列表使用列表名裁剪獲取對(duì)應(yīng)索引區(qū)間的子列。 前言: 好久不見,突然發(fā)覺好久沒寫博客了,最近迷上了 Python 無(wú)法自拔,了解了一下,Python 簡(jiǎn)單易學(xué),尤其是接觸過 java 的人,入門 Python 更...

    Andrman 評(píng)論0 收藏0
  • 筆記 - 收藏集 - 掘金

    摘要:目錄如何用提高效率后端掘金經(jīng)常有人說我應(yīng)該學(xué)一門語(yǔ)言,比如之類,但是卻不知道如何入門。本文將通過我是如何開發(fā)公司年會(huì)抽獎(jiǎng)系統(tǒng)的后端掘金需求出現(xiàn)年會(huì)將近,而年會(huì)抽獎(jiǎng)環(huán)節(jié)必不可少,但是抽獎(jiǎng)系統(tǒng)卻還沒有。 云盤一個(gè)個(gè)倒下怎么辦?無(wú)需編碼,手把手教你搭建至尊私享云盤 - 工具資源 - 掘金微盤掛了,360倒了,百度云盤也立了Flag。能讓我們?cè)谠贫藘?chǔ)存分享文件的服務(wù)越來越少了。 買一堆移動(dòng)硬盤...

    Alex 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<