Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Cyril Chubenko (ViXP) edited this page Nov 13, 2017 · 7 revisions

Problem

The client needs to operate the object (or family of objects) during runtime, as well as to cancel the operations one-by-one or all at once, by using the simple interface of a single object.

Pattern idea

When we have the objects (receivers) with a huge amount of operations in them we can define the class of command objects, which will share the client-needed interface of executing and canceling the operations of receivers. Each command for each operation. As all of the receivers have the same class (or inherit from the same class), there is no need to create the command object for every single receiver (or the final quantity of commands will be the number of receivers multiplied by number of operations). It's much more clever to use the concrete receiver as the dependency injection to the command object (or by passing the receiver to the command's constructor during the instantiation) and to use the advantages of polymorphism in the command object.

If the details of canceling the operation varies from one receiver to another, the command object, which encapsulates the concrete operation of canceling mechanism won't be suitable for some receivers, so it is also not expedient to encapsulate neither the operation nor the undoing operation of receiver inside the command object. It is much better to leave both methods encapsulated in the receiver itself (all receivers must be modified with undoing operations methods) and to use them polymorphically in the command object.

Finally the command objects will be very light and their responsibility will be only to execute the concrete methods of receiver for execution and undoing operations.

However, our client wants to have the single entry point for all operations and we still didn't solve the problem of how to save the history of executed commands, to run the undoing methods of them when it will be needed. So it is time to use the new abstraction, invoker - the object which will encapsulate the history of executed commands (in some data structure, as ex. simple array), and will be responsible for executing the concrete command (passed as argument), and also will be responsible for cancelling the commands by getting the last one from history and running the undoing method on it, or by some other canceling logic.

In the end, for executing the operation, client must use the execution method of the invoker, by passing the concrete command object to it (and by passing the concrete receiver object to command). For canceling - must execute the undoing method of invoker (with, or without parameters).

The backside of this pattern is that client must know all the classes of commands and receivers, but this problem may be solved with an other design pattern (ex. Factory Method, Facade, Mediator etc.)

Generalization

  • Receiver - the large object (or family of objects), which encapsulates the logic of operations and the logic of the operations cancelling.
  • Command - the family of objects, every one of which executes the one concrete operation of gotten receiver, and one concrete cancelling operation of gotten receiver.
  • Invoker - the single entry point object, which saves the history of executed commands, implements the interface of running the execution method of gotten command and running the cancelling method of command from history.
  • Client - uses the invoker's interface to execute the command (passes the concrete command and concrete receiver to invloker) and to cancel the command.

Concepts of Object Oriented Programming applied

polymorphismdelegationencapsulationabstractioninheritance

My example

The source code

Simple pseudographical editor which can execute commands specified by user input, undo them and redo them.

Objects, classes, and interfaces

Drawer - the abstract Receiver, implements the common methods of all concrete receivers. TopLeftCornerDrawer, TopRightCornerDrawer, BottomLeftCornerDrawer, BottomRightCornerDrawer, SpotFillDrawer,HorizontalLineDrawer, VerticalLineDrawer, SolidFillDrawer - the concrete Receivers, inherit the Drawer class, are responsible for drawing the concrete symbols. DrawerCommand - the abstract Command, defines the common interface for concrete commands, and implements the common constructor. SymbolDrawerCommand, SpaceDrawerCommand, BreakLineDrawerCommand - the concrete Commands, responsible for executing the different kind of symbols drawing of different receivers. CommandInvoker - the concrete Invoker, is responsible for undoing, redoing and history saving operations.

The details of implementation

For this implementation I've also introduced the Stream singleton object which has nothing to do with pattern, but is used for proper work of CLI. Here I decided not to instantiate the receivers and to use it in a singleton way, as well, as the invoker object. This example is interactive, so you can try it yourself.