Next, we'll look at examples of how I use STRATEGY in Javascript, and how it is used by the real library, to break it down into small pieces.
// Greeter - , . // var Greeter = function(strategy) { this.strategy = strategy; }; // Greeter greet, // // , Greeter.prototype.greet = function() { return this.strategy(); }; // , // // : var politeGreetingStrategy = function() { console.log("Hello."); }; var friendlyGreetingStrategy = function() { console.log("Hey!"); }; var boredGreetingStrategy = function() { console.log("sup."); }; // ! var politeGreeter = new Greeter(politeGreetingStrategy); var friendlyGreeter = new Greeter(friendlyGreetingStrategy); var boredGreeter = new Greeter(boredGreetingStrategy); console.log(politeGreeter.greet()); //=> Hello. console.log(friendlyGreeter.greet()); //=> Hey! console.log(boredGreeter.greet()); //=> sup.
There is an error in this code (thanks to bashtannik ). Since the algorithms of the strategies already have the output in the console, and the greet method returns a function that returns nothing - the last three lines should be replaced by politeGreeter.greet(); //=> Hello. friendlyGreeter.greet(); //=> Hey! boredGreeter.greet(); //=> sup.
var Greeter = function(strategy) { this.strategy = strategy; };
// Javascript // , // , // . // , var Strategy = function() {}; Strategy.prototype.execute = function() { throw new Error('Strategy#execute needs to be overridden.') }; // // `Strategy`. // , , // `execute` var GreetingStrategy = function() {}; GreetingStrategy.prototype = Object.create(Strategy.prototype); // `execute`, // `Strategy` . // , . // (Template Method). // . GreetingStrategy.prototype.execute = function() { return this.sayHi() + this.sayBye(); }; GreetingStrategy.prototype.sayHi = function() { return "Hello, "; }; GreetingStrategy.prototype.sayBye = function() { return "Goodbye."; }; // . // - `Greeter`. Greeter.prototype.greet = function() { return this.strategy.execute(); }; var greeter = new Greeter(new GreetingStrategy()); greeter.greet() //=> 'Hello, Goodbye.'
We defined Strategy as an object (or class) with the execute method. The client can use any strategy that fits this class.
// GreetingStrategy#execute . // , , // ( `execute`) var PoliteGreetingStrategy = function() {}; PoliteGreetingStrategy.prototype = Object.create(GreetingStrategy.prototype); PoliteGreetingStrategy.prototype.sayHi = function() { return "Welcome sir, "; }; var FriendlyGreetingStrategy = function() {}; FriendlyGreetingStrategy.prototype = Object.create(GreetingStrategy.prototype); FriendlyGreetingStrategy.prototype.sayHi = function() { return "Hey, "; }; var BoredGreetingStrategy = function() {}; BoredGreetingStrategy.prototype = Object.create(GreetingStrategy.prototype); BoredGreetingStrategy.prototype.sayHi = function() { return "sup, "; }; var politeGreeter = new Greeter(new PoliteGreetingStrategy()); var friendlyGreeter = new Greeter(new FriendlyGreetingStrategy()); var boredGreeter = new Greeter(new BoredGreetingStrategy()); politeGreeter.greet(); //=> 'Welcome sir, Goodbye.' friendlyGreeter.greet(); //=> 'Hey, Goodbye.' boredGreeter.greet(); //=> 'sup, Goodbye.'
By defining the execute method, GreetingStrategy creates a family of algorithms . In the above fragment, we took advantage of this by creating several varieties of them.
var greeters = [ new Greeter(new BoredGreetingStrategy()), new Greeter(new PoliteGreetingStrategy()), new Greeter(new FriendlyGreetingStrategy()), ]; greeters.forEach(function(greeter) { // `greeter` // . // `greet`, // . greeter.greet(); });
// http://passportjs.org var passport = require('passport') // npm-. // . , LocalStrategy = require('passport-local').Strategy , FacebookStrategy = require('passport-facebook').Strategy; // Passport . passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username }, function (err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: 'Incorrect username.' }); } if (!user.validPassword(password)) { return done(null, false, { message: 'Incorrect password.' }); } return done(null, user); }); } )); // , Facebook passport.use(new FacebookStrategy({ clientID: FACEBOOK_APP_ID, clientSecret: FACEBOOK_APP_SECRET, callbackURL: "http://www.example.com/auth/facebook/callback" }, function(accessToken, refreshToken, profile, done) { User.findOrCreate(..., function(err, user) { if (err) { return done(err); } done(null, user); }); } ));
The Passport.js library itself contains only a couple of simple authentication mechanisms. There is nothing in it but them and the Context . This architecture allows third-party programmers to easily implement their own authentication mechanisms without cluttering up the project.
Source: https://habr.com/ru/post/191480/