- Mastering JavaScript Design Patterns
- Simon Timms
- 783字
- 2021-08-05 17:14:58
Abstract Factory
The first pattern presented here is a method to create kits of objects without knowing the concrete types of the objects. Let's continue on with the system presented earlier for ruling a kingdom.
In the kingdom in question, the ruling house changes with some degree of frequency. In all likelihood, there is a degree of battling and fighting during the change of house but we'll ignore that for the moment. Each house will rule the kingdom differently. Some value peace and tranquility, and rule as benevolent leaders, while others rule with an iron fist. The rule of a kingdom is too large for a single individual, so the king defers some of his decisions to a second-in-command known as the hand of the king. The king is also advised on matters by a council, which consists of some of the more savvy lords and ladies of the land.
A diagram of the classes in our description is as follows:

Tip
Unified Modeling Language (UML) is a standardized language developed by the Object Management Group (OMG), which describes computer systems. There is vocabulary in the language to create user interaction diagrams, sequence diagrams, and state machines, among others. For the purposes of this book, we're most interested in class diagrams, which describe the relationship between a set of classes.
The entire UML class diagram vocabulary is extensive and is beyond the scope of this book. However, the Wikipedia article at https://en.wikipedia.org/wiki/Class_diagram acts as a great introduction, as does Derek Banas's excellent video tutorial on class diagrams at https://www.youtube.com/watch?v=3cmzqZzwNDM.
The issue is that with the ruling family, and even the member of the ruling family on the throne changing so frequently, coupling to a concrete family such as Targaryen
or Lannister
makes our application brittle. Brittle applications do not fare well in an ever-changing world.
An approach to fixing this is to make use of the Abstract Factory pattern. The Abstract Factory pattern declares an interface to create each of the various classes related to the ruling family, as shown in the following diagram:

The Abstract Factory class may have multiple implementations for each of the various ruling families. These are known as concrete factories and each of them will implement the interface provided by the Abstract Factory. The concrete factories, in return, will return concrete implementations of the various ruling classes. These concrete classes are known as products.
Let's start by looking at the code for the interface for the Abstract Factory.
No code? Well, actually that is exactly the case. The lack of classes in JavaScript precludes the need for interfaces to describe classes. Instead of having interfaces, we'll move directly to creating the classes, as shown in the following diagram:

Instead of interfaces, JavaScript trusts that the class you provide implements all the appropriate methods. At runtime, the interpreter will attempt to call the method you request, and call it, if it is found. The interpreter simply assumes that if your class implements the method, then it is that class. This is known as duck typing.
Tip
Duck typing
The name duck typing originates a post made by Alex Martelli in the year 2000 to the news group comp.lang.python, where he wrote:
In other words, don't check whether it IS-a duck: check whether it QUACKS-like-a duck, WALKS-like-a duck, etc, etc, depending on exactly what subset of duck-like behaviour you need to play your language-games with.
I enjoy the possibility that Martelli took the term from the witch hunt sketch from Monty Python's search for the Holy Grail. Although I can find no evidence of that, I find it quite likely as the Python programming language takes its name from Monty Python.
Duck typing is a powerful tool in dynamic languages allowing, for much less overhead in implementing a class hierarchy. It does, however, introduce some uncertainty. If two classes implement an identically named method that have radically different meanings, then there is no way to know whether the one being called is the correct one. For example, consider the following code:
class Boxer{ function punch(){} } class TicketMachine{ function punch(){} }
Both classes have a punch()
method but they clearly have different meanings. The JavaScript interpreter has no idea that they are different classes and will happily call punch
on either class, even when one doesn't make sense.
In some dynamic languages, there is support for the generic method, which is called whenever an undefined method is called. Ruby, for instance, has missing_method
, which has proven to be very useful in a number of scenarios. As of this writing, there is no support for missing_method
in JavaScript. However, it may be possible to implement such a feature in ECMAScript 6.
- Spring 5.0 Microservices(Second Edition)
- Java 開發從入門到精通(第2版)
- 零基礎PHP學習筆記
- Python數據可視化:基于Bokeh的可視化繪圖
- Maven Build Customization
- Java Web基礎與實例教程(第2版·微課版)
- Python金融數據分析
- JavaScript動態網頁開發詳解
- Android 應用案例開發大全(第3版)
- 學Python也可以這么有趣
- Python Web數據分析可視化:基于Django框架的開發實戰
- Learning R for Geospatial Analysis
- Qt5 C++ GUI Programming Cookbook
- Struts 2.x權威指南
- Python Linux系統管理與自動化運維