Sök…


Observera mönster

Observer- mönstret används för händelsehantering och delegering. Ett ämne har en samling observatörer. Ämnet meddelar sedan dessa observatörer när en händelse inträffar. Om du någonsin har använt addEventListener du använt Observer-mönstret.

function Subject() {
    this.observers = []; // Observers listening to the subject
    
    this.registerObserver = function(observer) {
        // Add an observer if it isn't already being tracked
        if (this.observers.indexOf(observer) === -1) {
            this.observers.push(observer);
        }
    };

    this.unregisterObserver = function(observer) {
        // Removes a previously registered observer
        var index = this.observers.indexOf(observer);
        if (index > -1) {
            this.observers.splice(index, 1);
        }
    };

    this.notifyObservers = function(message) {
        // Send a message to all observers
        this.observers.forEach(function(observer) {
            observer.notify(message);
        });
    };
}

function Observer() {
    this.notify = function(message) {
        // Every observer must implement this function
    };
}

Exempel på användning:

function Employee(name) {
    this.name = name;

    // Implement `notify` so the subject can pass us messages
    this.notify = function(meetingTime) {
        console.log(this.name + ': There is a meeting at ' + meetingTime);
    };
}

var bob = new Employee('Bob');
var jane = new Employee('Jane');
var meetingAlerts = new Subject();
meetingAlerts.registerObserver(bob);
meetingAlerts.registerObserver(jane);
meetingAlerts.notifyObservers('4pm');

// Output:
// Bob: There is a meeting at 4pm
// Jane: There is a meeting at 4pm

Medlarmönster

Tänk på medlarmönstret som flygkontrolltornet som styr flyg i luften: det leder detta plan att landa nu, det andra att vänta, och det tredje att ta av, etc. Inget flygplan får dock någonsin tala med sina kamrater .

Så fungerar medlaren, det fungerar som ett kommunikationsnav mellan olika moduler, på så sätt minskar du modulberoendet på varandra, ökar lös koppling och därmed bärbarhet.

Detta Chatroom-exempel förklarar hur medlarmönster fungerar:

// each participant is just a module that wants to talk to other modules(other participants)
var Participant = function(name) {
    this.name = name;
    this.chatroom = null;
};
 // each participant has method for talking, and also listening to other participants
Participant.prototype = {
    send: function(message, to) {
        this.chatroom.send(message, this, to);
    },
    receive: function(message, from) {
        log.add(from.name + " to " + this.name + ": " + message);
    }
};

 // chatroom is the Mediator: it is the hub where participants send messages to, and receive messages from
var Chatroom = function() {
    var participants = {};
 
    return {
 
        register: function(participant) {
            participants[participant.name] = participant;
            participant.chatroom = this;
        },
 
        send: function(message, from) {
            for (key in participants) {   
                if (participants[key] !== from) {//you cant message yourself !
                    participants[key].receive(message, from);
                }
            }
        }

    };
};
 
// log helper
 
var log = (function() {
    var log = "";
 
    return {
        add: function(msg) { log += msg + "\n"; },
        show: function() { alert(log); log = ""; }
    }
})();
 
function run() {
    var yoko = new Participant("Yoko");
    var john = new Participant("John");
    var paul = new Participant("Paul");
    var ringo = new Participant("Ringo");
 
    var chatroom = new Chatroom();
    chatroom.register(yoko);
    chatroom.register(john);
    chatroom.register(paul);
    chatroom.register(ringo);
 
    yoko.send("All you need is love.");
    yoko.send("I love you John.");        
    paul.send("Ha, I heard that!");
 
    log.show();
}

Kommando

Kommandomönstret kapslar parametrar till en metod, aktuellt objekttillstånd och vilken metod som ska ringas. Det är användbart att dela in allt som behövs för att kalla en metod vid ett senare tillfälle. Det kan användas för att utfärda ett "kommando" och senare bestämma vilket kodstycke som ska användas för att utföra kommandot.

Det finns tre komponenter i detta mönster:

  1. Kommandomeddelandet - själva kommandot, inklusive metodnamn, parametrar och tillstånd
  2. Invoker - den del som instruerar kommandot att utföra sina instruktioner. Det kan vara en tidsbestämd händelse, användarinteraktion, ett steg i en process, återuppringning eller något sätt som behövs för att köra kommandot.
  3. Mottagare - målet för kommandot exekvering.

Kommandomeddelandet som en matris

var aCommand = new Array();
aCommand.push(new Instructions().DoThis);  //Method to execute
aCommand.push("String Argument");  //string argument
aCommand.push(777);                //integer argument
aCommand.push(new Object {} );     //object argument
aCommand.push(new Array() );       //array argument

Konstruktör för kommandoklassen

class DoThis {
    constructor( stringArg, numArg, objectArg, arrayArg ) {
        this._stringArg = stringArg;
        this._numArg = numArg;
        this._objectArg = objectArg;
        this._arrayArg = arrayArg;
    }
    Execute() {
       var receiver = new Instructions();
       receiver.DoThis(this._stringArg, this._numArg, this._objectArg, this._arrayArg );
    }
}     

invoker

aCommand.Execute();  

Kan åberopa:

  • omedelbart
  • som svar på en händelse
  • i en sekvens av utförandet
  • som ett återuppringningssvar eller i ett löfte
  • i slutet av en händelsslinga
  • på något annat sätt som krävs för att åberopa en metod

Mottagare

class Instructions {
    DoThis( stringArg, numArg, objectArg, arrayArg ) {
        console.log( `${stringArg}, ${numArg}, ${objectArg}, ${arrayArg}` );
    }
}

En klient genererar ett kommando, skickar det till en invokare som antingen kör det omedelbart eller fördröjer kommandot, och sedan fungerar kommandot på en mottagare. Kommandomönstret är mycket användbart när det används med följeslagarmönster för att skapa meddelandemönster.

iterator

Ett iteratormönster tillhandahåller en enkel metod för att i tur och ordning välja nästa objekt i en samling.


Fast samling

class BeverageForPizza {
    constructor(preferenceRank) {
        this.beverageList = beverageList;
        this.pointer = 0;
    }
    next() {
        return this.beverageList[this.pointer++];
    }

var withPepperoni = new BeverageForPizza(["Cola", "Water", "Beer"]);
withPepperoni.next(); //Cola
withPepperoni.next(); //Water
withPepperoni.next(); //Beer

I ECMAScript 2015 är iteratorer en inbyggd som en metod som returnerar gjort och värde. gjort är sant när iteratorn är i slutet av samlingen

function preferredBeverage(beverage){
    if( beverage == "Beer" ){
        return true;
    } else {
        return false;
    }
}
var withPepperoni = new BeverageForPizza(["Cola", "Water", "Beer", "Orange Juice"]);
for( var bevToOrder of withPepperoni ){
    if( preferredBeverage( bevToOrder ) {
        bevToOrder.done; //false, because "Beer" isn't the final collection item
        return bevToOrder; //"Beer"
    }
}

Som generator

class FibonacciIterator {
    constructor() {
        this.previous = 1;
        this.beforePrevious = 1;
    }
    next() {
        var current = this.previous + this.beforePrevious;
        this.beforePrevious = this.previous;
        this.previous = current;
        return current;
    }
}

var fib = new FibonacciIterator();
fib.next(); //2
fib.next(); //3
fib.next(); //5

I ECMAScript 2015

function* FibonacciGenerator() {  //asterisk informs javascript of generator 
    var previous = 1;
    var beforePrevious = 1;
    while(true) {
        var current = previous + beforePrevious;
        beforePrevious = previous;
        previous = current;
        yield current;  //This is like return but 
                        //keeps the current state of the function
                        // i.e it remembers its place between calls
    }
}

var fib = FibonacciGenerator();
fib.next().value; //2
fib.next().value; //3
fib.next().value; //5
fib.next().done; //false


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow