0%

本文转载于A Complete Guide to TypeScript Decorators

装饰器让TypeScript的世界更好。 我们使用的许多库都基于这一强大特性构建, 例如AngularNestjs。 在这篇博客中我将介绍装饰器和它的许多细节。 我希望在读完这篇文章后,你可以理解何时和如何使用这一强的的特性。

概览

装饰器本质上是一种特殊的函数被应用在于:

  1. 类属性
  2. 类方法
  3. 类访问器
  4. 类方法的参数

所以应用装饰器其实很像是组合一系列函数,类似于高阶函数和类。 通过装饰器我们可以轻松实现代理模式来使代码更简洁以及实现其它一些更有趣的能力。

阅读全文 »

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

“观察者模式”:__被观察者对象__通过一个列表维护__观察者对象__的行为(方法),当__被观察者对象__状态改变时会主动呼叫(调用)__观察者对象__行为(方法)。

PS:观察者模式有时又被称为发布(publish)-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'''
Python示例代码,来自网络
'''
class Observable:
def __init__(self):
self.__observers = []

def register_observer(self, observer):
self.__observers.append(observer)

def notify_observers(self, *args, **kwargs):
for observer in self.__observers:
observer.notify(self, *args, **kwargs)

class Observer:
def __init__(self, observable):
observable.register_observer(self)

def notify(self, observable, *args, **kwargs):
print('Got', args, kwargs, 'From', observable)


subject = Observable()
observer = Observer(subject)
subject.notify_observers('test')

The essence of the Mediator Pattern is to “define an object that encapsulates how a set of objects interact“. It promotes loose coupling by keeping objects from referring to each other explicitly, and it allows their interaction to be varied independently. Client classes can use the mediator to send messages to other clients, and can receive messages from other clients via an event on the mediator class.

Mediator - defines the interface for communication between Colleague objects
ConcreteMediator - implements the Mediator interface and coordinates communication between Colleague objects. It is aware of all of the Colleagues and their purposes with regards to inter-communication.
Colleague - defines the interface for communication with other Colleagues
ConcreteColleague - implements the Colleague interface and communicates with other Colleagues through its Mediator

“中介者模式”:把对象(A)与对象(B)之间的__直接__通信关系,变成对象(A)与对象(B)通过__中介对象__来通信的__间接__关系,从而松散了对象(A)与对象(B)的耦合度;实现上必须“__你中有我,我中有你__”。(PS:如果参与通信的对象很多的话就会增加中介对象的复杂度。)

阅读全文 »

A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy, extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked. For the client, usage of a proxy object is similar to using the real object, because both implement the same interface.
Notes:

  • A proxy may hide information about the real object to the client.
  • A proxy may perform optimization like on demand loading.
  • A proxy may do additional house-keeping job like audit tasks.
  • Proxy design pattern is also known as surrogate design pattern.

“代理模式”:在__客户端__和__目标对象__之间建立一个__代理对象__,客户端通过代理对象来访问目标对象;这样可以起到__保护__或__欺骗__目标对象的作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
"""
Proxy pattern example.
"""
from abc import ABCMeta, abstractmethod

NOT_IMPLEMENTED = "You should implement this."

class AbstractCar:
__metaclass__ = ABCMeta

@abstractmethod
def drive(self):
raise NotImplementedError(NOT_IMPLEMENTED)

class Car(AbstractCar):
def drive(self):
print("Car has been driven!")

class Driver(object):
def __init__(self, age):
self.age = age

class ProxyCar(AbstractCar):
def __init__(self, driver):
self.car = Car()
self.driver = driver

def drive(self):
if self.driver.age <= 16:
print("Sorry, the driver is too young to drive.")
else:
self.car.drive()

driver = Driver(16)
car = ProxyCar(driver)
car.drive()

driver = Driver(25)
car = ProxyCar(driver)
car.drive()

A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can

  1. make a software library easier to use, understand and test, since the facade has convenient methods for common tasks,
  2. make the library more readable, for the same reason,
  3. reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system,
  4. wrap a poorly designed collection of APIs with a single well-designed API.

The Facade design pattern is often used when a system is very complex or difficult to understand because the system has a large number of interdependent classes or its source code is unavailable. This pattern hides the complexities of the larger system and provides a simpler interface to the client. It typically involves a single wrapper class that contains a set of members required by client. These members access the system on behalf of the facade client and hide the implementation details. The facade pattern is typically used when:

  1. a simple interface is required to access a complex system,
  2. a system is very complex or difficult to understand,
  3. an entry point is needed to each level of layered software, or
  4. the abstractions and implementations of a subsystem are tightly coupled.

“外观模式”:用函数或类进行封装实现,对外提供一个__简洁明了__的接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""
Python示例代码,来自网络
ComputerFacade类封装了computer的启动过程的复杂性,用户不用关心内部实现,直接使用就好。
"""

# Complex computer parts
class CPU(object):
"""
Simple CPU representation.
"""
def freeze(self):
print("Freezing processor.")

def jump(self, position):
print("Jumping to:", position)

def execute(self):
print("Executing.")


class Memory(object):
"""
Simple memory representation.
"""
def load(self, position, data):
print("Loading from {0} data: '{1}'.".format(position, data))


class SolidStateDrive(object):
"""
Simple solid state drive representation.
"""
def read(self, lba, size):
return "Some data from sector {0} with size {1}".format(lba, size)


class ComputerFacade(object):
"""
Represents a facade for varius computer parts.
"""
def __init__(self):
self.cpu = CPU()
self.memory = Memory()
self.ssd = SolidStateDrive()

def start(self):
self.cpu.freeze()
self.memory.load("0x00", self.ssd.read("100", "1024"))
self.cpu.jump("0x00")
self.cpu.execute


computer_facade = ComputerFacade()
computer_facade.start()

“策略模式”:__定义了一系列的算法并提供运行时动态更改算法的能力,保证了客户端代码的简洁性__。

实现方式:

  1. 创建__策略接口__;
  2. 创建多个__策略类__继承__策略接口__并通过不同算法实现接口中声明的方法;
  3. 创建一个__消费者类__,它必须存储一个__策略对象__的引用并对外提供一个可修改该引用的方法;
  4. 在执行环境的上下文通过动态的更改__消费者对象__中存储的__策略对象__引用来达到动态更改算法的目的;
阅读全文 »

The decorator pattern can be used to extend (decorate) the functionality of a certain object statically, or in some cases at run-time, independently of other instances of the same class, provided some groundwork is done at design time. This is achieved by designing a new Decorator class that wraps the original class. This wrapping could be achieved by the following sequence of steps:

  1. Subclass the original Component class into a Decorator class (see UML diagram);
  2. In the Decorator class, add a Component pointer as a field;
  3. In the Decorator class, pass a Component to the Decorator constructor to initialize the Component pointer;
  4. In the Decorator class, forward all Component methods to the Component pointer;
  5. In the ConcreteDecorator class, override any Component method(s) whose behavior needs to be modified.
阅读全文 »