参考网站 链接到标题

https://refactoring.guru/store

分类 链接到标题

所有设计模式按目的分成3种

  1. 行为模式:如何划分类的职责
  2. 结构模式:如何用类来组成大类
  3. 创造模式:如何创造新类,就是新类创造的准则

这种分类有重叠的部分在,就是有的设计模式你说他是行为模式也行,说他是结构模式也行这种。 有个大致概念就好。

A pattern isn’t just a recipe for structuring your code in a specific way. It can also communicate to other developers the problem the pattern solves.

假如一个类想用多个模式,就直接在抽象类里多列几个纯虚函数就好。 prototype+Observer. 就是在subcriber那个抽象类里写clone和update两个纯虚函数。

注意,抽象模式是为了大型项目开发中,人与人代码方法协作的,所以用法和写法都要懂,不要只懂怎么设计,却忘了怎么用(大部分的使用其实不用记,但有些模式的使用就是需要client配合)。

有些一般原则,不一定对,但大部分是这样:要用谁就用一个成员指向相应对象。要细化谁就继承谁。e.g. facade里,要用子系统,就指向一个,要让人家()用

template pattern 链接到标题

类别:行为模式(多是设计成员函数的) 模板模式: 其实就是基本的虚函数,多态的应用,加入要实现动物叫唤函数,狗对象是狗叫,猫对象猫叫。

适用条件 链接到标题

设计时: Use the Template Method pattern when you want to let clients extend only particular steps of an algorithm, but not the whole algorithm or its structure.

The Template Method lets you turn a monolithic algorithm into a series of individual steps which can be easily extended by subclasses while keeping intact the structure defined in a superclass. 重构时: Use the pattern when you have several classes that contain almost identical algorithms with some minor differences. As a result, you might need to modify all classes when the algorithm changes.

When you turn such an algorithm into a template method, you can also pull up the steps with similar implementations into a superclass, eliminating code duplication. Code that varies between subclasses can remain in subclasses.

strategy 链接到标题

类别:行为模式 策略(模式): 在一个context中,动态替换某个步骤,也是多态的应用,加入要实现动物叫唤函数,狗对象是狗叫,猫对象猫叫,和template 的不同在形式上是,template是继承,strategy是组合。组合就更灵活

Template Method is based on inheritance: it lets you alter parts of an algorithm by extending those parts in subclasses. Strategy is based on composition: you can alter parts of the object’s behavior by supplying it with different strategies that correspond to that behavior. Template Method works at the class level, so it’s static. Strategy works on the object level, letting you switch behaviors at runtime.

适用条件 链接到标题

Use the Strategy pattern when you want to use different variants of an algorithm within an object and be able to switch from one algorithm to another during runtime.

The Strategy pattern lets you indirectly alter the object’s behavior at runtime by associating it with different sub-objects which can perform specific sub-tasks in different ways.

Use the Strategy when you have a lot of similar classes that only differ in the way they execute some behavior.

The Strategy pattern lets you extract the varying behavior into a separate class hierarchy and combine the original classes into one, thereby reducing duplicate code.

Use the pattern to isolate the business logic of a class from the implementation details of algorithms that may not be as important in the context of that logic.

The Strategy pattern lets you isolate the code, internal data, and dependencies of various algorithms from the rest of the code. Various clients get a simple interface to execute the algorithms and switch them at runtime.

Use the pattern when your class has a massive conditional statement that switches between different variants of the same algorithm.

The Strategy pattern lets you do away with such a conditional by extracting all algorithms into separate classes, all of which implement the same interface. The original object delegates execution to one of these objects, instead of implementing all variants of the algorithm.

Observer 链接到标题

类别:行为模式 观察者模式:也可以叫publisher+subscriber模式(和ros2中的差不多,但是不是一个层面的概念了)。就是有一个publish类,自己的变化需要让所有subscribe类知晓,那么这个模式就有用。

subscriber要有一个update方法给publisher调用

对于subject,要有notify,register,unregister方法 对于observer,要有update方法给subject调用。

适用条件 链接到标题

Use the Observer pattern when changes to the state of one object may require changing other objects, and the actual set of objects is unknown beforehand or changes dynamically.

You can often experience this problem when working with classes of the graphical user interface. For example, you created custom button classes, and you want to let the clients hook some custom code to your buttons so that it fires whenever a user presses a button.

The Observer pattern lets any object that implements the subscriber interface subscribe for event notifications in publisher objects. You can add the subscription mechanism to your buttons, letting the clients hook up their custom code via custom subscriber classes.

Use the pattern when some objects in your app must observe others, but only for a limited time or in specific cases.

The subscription list is dynamic, so subscribers can join or leave the list whenever they need to.

decorator 链接到标题

类别:结构模式 装饰模式:这个是一个比较难搞的模式,就是可以在不影响client的情况下,多加一些功能。这个功能一定得在原有功能上加。

带码比较难理解,有一个base基类->concretebase base -> decorator ->concretedecorator

这里decorater一定要有一个base指针,用于指向concretebase的原有对象

适用条件 链接到标题

Use the Decorator pattern when you need to be able to assign extra behaviors to objects at runtime without breaking the code that uses these objects.

The Decorator lets you structure your business logic into layers, create a decorator for each layer and compose objects with various combinations of this logic at runtime. The client code can treat all these objects in the same way, since they all follow a common interface.

Use the pattern when it’s awkward or not possible to extend an object’s behavior using inheritance.

Many programming languages have the final keyword that can be used to prevent further extension of a class. For a final class, the only way to reuse the existing behavior would be to wrap the class with your own wrapper, using the Decorator pattern.

bridge 链接到标题

类别:结构模式

桥模式:说是桥模式,其实整体的代码结构和策略模式差不多,主要讲究的是分层的含义,一部分类专门处理一部分,两个部分的联动用composite组织。

Bridge, State, Strategy (and to some degree Adapter) have very similar structures. Indeed, all of these patterns are based on composition, which is delegating work to other objects. However, they all solve different problems. A pattern isn’t just a recipe for structuring your code in a specific way. It can also communicate to other developers the problem the pattern solves.

适用条件 链接到标题

Use the Bridge pattern when you want to divide and organize a monolithic class that has several variants of some functionality (for example, if the class can work with various database servers).

The bigger a class becomes, the harder it is to figure out how it works, and the longer it takes to make a change. The changes made to one of the variations of functionality may require making changes across the whole class, which often results in making errors or not addressing some critical side effects.

The Bridge pattern lets you split the monolithic class into several class hierarchies. After this, you can change the classes in each hierarchy independently of the classes in the others. This approach simplifies code maintenance and minimizes the risk of breaking existing code.

Use the pattern when you need to extend a class in several orthogonal (independent) dimensions.

The Bridge suggests that you extract a separate class hierarchy for each of the dimensions. The original class delegates the related work to the objects belonging to those hierarchies instead of doing everything on its own.

Use the Bridge if you need to be able to switch implementations at runtime.

Although it’s optional, the Bridge pattern lets you replace the implementation object inside the abstraction. It’s as easy as assigning a new value to a field.

By the way, this last item is the main reason why so many people confuse the Bridge with the Strategy pattern. Remember that a pattern is more than just a certain way to structure your classes. It may also communicate intent and a problem being addressed.

factory 链接到标题

类别:创造模式 工厂模式:要我说,其实是桥模式+模板模式的组装+简单的创建机制。这个简单的创建机制是对client说的,client用个create就好,实际在创建concreteproduct时可能会有很多依赖,导致创建时会要求调用很多东西,但有工厂就可以一个create就好。

区别在于,桥模式中对于两个正交维度的东西还是组装的调用方法(就是A中含有B,然后用户调用A的时候只需要指定concreteB就好),工厂的话,对于concreteB的调用是需要用户知道B的调用方法的。也就是说可以通过A去弄一个新的B,所以是创建模式。

适用条件 链接到标题

Use the Factory Method when you don’t know beforehand the exact types and dependencies of the objects your code should work with.

The Factory Method separates product construction code from the code that actually uses the product. Therefore it’s easier to extend the product construction code independently from the rest of the code.

For example, to add a new product type to the app, you’ll only need to create a new creator subclass and override the factory method in it.

Use the Factory Method when you want to provide users of your library or framework with a way to extend its internal components.

Inheritance is probably the easiest way to extend the default behavior of a library or framework. But how would the framework recognize that your subclass should be used instead of a standard component?

The solution is to reduce the code that constructs components across the framework into a single factory method and let anyone override this method in addition to extending the component itself.

Let’s see how that would work. Imagine that you write an app using an open source UI framework. Your app should have round buttons, but the framework only provides square ones. You extend the standard Button class with a glorious RoundButton subclass. But now you need to tell the main UIFramework class to use the new button subclass instead of a default one.

To achieve this, you create a subclass UIWithRoundButtons from a base framework class and override its createButton method. While this method returns Button objects in the base class, you make your subclass return RoundButton objects. Now use the UIWithRoundButtons class instead of UIFramework. And that’s about it!

Use the Factory Method when you want to save system resources by reusing existing objects instead of rebuilding them each time.

You often experience this need when dealing with large, resource-intensive objects such as database connections, file systems, and network resources.

Let’s think about what has to be done to reuse an existing object:

First, you need to create some storage to keep track of all of the created objects.
When someone requests an object, the program should look for a free object inside that pool.
… and then return it to the client code.
If there are no free objects, the program should create a new one (and add it to the pool).

That’s a lot of code! And it must all be put into a single place so that you don’t pollute the program with duplicate code.

Probably the most obvious and convenient place where this code could be placed is the constructor of the class whose objects we’re trying to reuse. However, a constructor must always return new objects by definition. It can’t return existing instances.

Therefore, you need to have a regular method capable of creating new objects as well as reusing existing ones. That sounds very much like a factory method.

abstract factory 链接到标题

类别:创造模式 抽象工厂就是多个类的create弄到多个工厂中,多个工厂弄成多态的。

适用条件 链接到标题

Use the Abstract Factory when your code needs to work with various families of related products, but you don’t want it to depend on the concrete classes of those products—they might be unknown beforehand or you simply want to allow for future extensibility.

The Abstract Factory provides you with an interface for creating objects from each class of the product family. As long as your code creates objects via this interface, you don’t have to worry about creating the wrong variant of a product which doesn’t match the products already created by your app.

Consider implementing the Abstract Factory when you have a class with a set of Factory Methods that blur its primary responsibility.

In a well-designed program each class is responsible only for one thing. When a class deals with multiple product types, it may be worth extracting its factory methods into a stand-alone factory class or a full-blown Abstract Factory implementation.

prototype 链接到标题

类别:创造模式 原型设计模式:主要是解决第三方的代码中,一个类的构造过程超级难搞,那么不如用一个prototype来clone一个新对象,这里的构造函数要好好写。 就是实现时要有clone抽象方法。

然后具体实现需要练习,因为这个实现的方式还蛮反直觉的。他会直接用一个config来创建一些根本不用的对象,只是用于clone的。

真正使用时,可能需要继承两次,先是prototype -> concreteprototype -> concreteclass
理解时要注意,比如: 按钮抽象类他是一个按钮prototype,则有prototype - > 按钮类 -> 圆形按钮类
实际中可有一个protoregister的类,这个类里包含item指向注册的配置

适用条件 链接到标题

Use the Prototype pattern when your code shouldn’t depend on the concrete classes of objects that you need to copy.

This happens a lot when your code works with objects passed to you from 3rd-party code via some interface. The concrete classes of these objects are unknown, and you couldn’t depend on them even if you wanted to.

The Prototype pattern provides the client code with a general interface for working with all objects that support cloning. This interface makes the client code independent from the concrete classes of objects that it clones.

Use the pattern when you want to reduce the number of subclasses that only differ in the way they initialize their respective objects.

Suppose you have a complex class that requires a laborious configuration before it can be used. There are several common ways to configure this class, and this code is scattered through your app. To reduce the duplication, you create several subclasses and put every common configuration code into their constructors. You solved the duplication problem, but now you have lots of dummy subclasses.

The Prototype pattern lets you use a set of pre-built objects configured in various ways as prototypes. Instead of instantiating a subclass that matches some configuration, the client can simply look for an appropriate prototype and clone it.

builder 链接到标题

类别:创建模式

建造者模式:主要是细化的构造方法,像是factory模式有时候会演化成这种模式。一个builder可以用于构建多种对象,就是builder -> concreteA,builder ->concreteB,这里的A和B又可以构建同一种对象的不同变种。解决复杂配置的对象的配置问题。

就是细化的factory方法,有时会弄一个director来详细写构造方法来减少重复代码。(有意思的是,我一开始想的是这个director用友员来弄,但实际实现其实就是director里写一个builder的成员。)

适用条件 链接到标题

Use the Builder pattern to get rid of a “telescoping constructor”.

Say you have a constructor with ten optional parameters. Calling such a beast is very inconvenient; therefore, you overload the constructor and create several shorter versions with fewer parameters. These constructors still refer to the main one, passing some default values into any omitted parameters.

class Pizza { Pizza(int size) { … } Pizza(int size, boolean cheese) { … } Pizza(int size, boolean cheese, boolean pepperoni) { … } // …

Creating such a monster is only possible in languages that support method overloading, such as C# or Java.

The Builder pattern lets you build objects step by step, using only those steps that you really need. After implementing the pattern, you don’t have to cram dozens of parameters into your constructors anymore.

Use the Builder pattern when you want your code to be able to create different representations of some product (for example, stone and wooden houses).

The Builder pattern can be applied when construction of various representations of the product involves similar steps that differ only in the details.

The base builder interface defines all possible construction steps, and concrete builders implement these steps to construct particular representations of the product. Meanwhile, the director class guides the order of construction.

Use the Builder to construct Composite trees or other complex objects.

The Builder pattern lets you construct products step-by-step. You could defer execution of some steps without breaking the final product. You can even call steps recursively, which comes in handy when you need to build an object tree.

A builder doesn’t expose the unfinished product while running construction steps. This prevents the client code from fetching an incomplete result.

singleton 链接到标题

类别:创造模式 单件设计模式:保证一个实体只有一个对象的方法。其实说是不是设计模式,而是一种编程trick啥的。

class Singleton { private: static Singleton * pinstance_; //用于指向自身 static std::mutex mutex_; //用于线程安全 protected: Singleton(const std::string value): value_(value) { } ~Singleton() {} std::string value_; public: std::string value() const{ return value_; } }; Singleton* Singleton::pinstance_{nullptr}; std::mutex Singleton::mutex_; Singleton *Singleton::GetInstance(const std::string& value) { std::lock_guardstd::mutex lock(mutex_); if (pinstance_ == nullptr) { pinstance_ = new Singleton(value); } return pinstance_; }

适用条件 链接到标题

Use the Singleton pattern when a class in your program should have just a single instance available to all clients; for example, a single database object shared by different parts of the program.

The Singleton pattern disables all other means of creating objects of a class except for the special creation method. This method either creates a new object or returns an existing one if it has already been created.

Use the Singleton pattern when you need stricter control over global variables.

Unlike global variables, the Singleton pattern guarantees that there’s just one instance of a class. Nothing, except for the Singleton class itself, can replace the cached instance.

Note that you can always adjust this limitation and allow creating any number of Singleton instances. The only piece of code that needs changing is the body of the getInstance method.

flyweight 链接到标题

类别:结构模式 享元设计模式:这个是为了解决有大量对象时的性能问题提出的。具体实现其实是复杂的。就是代码超级难理解,感觉还是client懂计算机内存知识,自己用指针写还方便些。

这个模式要实现的是,让用户只管向程序里加对象,至于对象的那些部分需要共享,则是由设计者决定,并写好,让用户不需要管理内存相关的东西。

具体实现中,抽像的unique一个类。抽象的share一个类,然后用flyweight来引用一个share,用具体函数传参来使用unique。然后还有一个flyweightfactory类来管理flyweight类,保证有可以share的就share,没有的就加入。

这里就是需要添加用户用法学习的模式,我还不懂,第二次看的时候加上吧。

适用条件 链接到标题

Use the Flyweight pattern only when your program must support a huge number of objects which barely fit into available RAM.

The benefit of applying the pattern depends heavily on how and where it’s used. It’s most useful when:

an application needs to spawn a huge number of similar objects
this drains all available RAM on a target device
the objects contain duplicate states which can be extracted and shared between multiple objects

facade 链接到标题

类别:结构模式 门面模式:就是最基础的,包一层的思想,有点想hal库和直接寄存器操作的关系。弄出来的类只有方法和指针,指向需要的子系统。

其实蛮奇怪的,对于一个类到底应该怎么理解呢,我以前总感觉类里一定要有个成员,比如一个int这种,然后成员函数是围绕int来设计的,现在看设计模式,感觉类只是用于规划的一个东西,很难说是一个有成员的东西。

适用条件 链接到标题

Use the Facade pattern when you need to have a limited but straightforward interface to a complex subsystem.

Often, subsystems get more complex over time. Even applying design patterns typically leads to creating more classes. A subsystem may become more flexible and easier to reuse in various contexts, but the amount of configuration and boilerplate code it demands from a client grows ever larger. The Facade attempts to fix this problem by providing a shortcut to the most-used features of the subsystem which fit most client requirements.

Use the Facade when you want to structure a subsystem into layers.

Create facades to define entry points to each level of a subsystem. You can reduce coupling between multiple subsystems by requiring them to communicate only through facades.

For example, let’s return to our video conversion framework. It can be broken down into two layers: video- and audio-related. For each layer, you can create a facade and then make the classes of each layer communicate with each other via those facades. This approach looks very similar to the Mediator pattern.

Adapter/Wrapper 链接到标题

类别:创造模式 适应器:要用3方lib,但结构和我想要的不一样,就搞个adapter,adapter里指向第3方lib,client用adapter提供的方法。

适用条件 链接到标题

Use the Adapter class when you want to use some existing class, but its interface isn’t compatible with the rest of your code.

The Adapter pattern lets you create a middle-layer class that serves as a translator between your code and a legacy class, a 3rd-party class or any other class with a weird interface.

Use the pattern when you want to reuse several existing subclasses that lack some common functionality that can’t be added to the superclass.

You could extend each subclass and put the missing functionality into new child classes. However, you’ll need to duplicate the code across all of these new classes, which smells really bad.

The much more elegant solution would be to put the missing functionality into an adapter class. Then you would wrap objects with missing features inside the adapter, gaining needed features dynamically. For this to work, the target classes must have a common interface, and the adapter’s field should follow that interface. This approach looks very similar to the Decorator pattern.

Mediator 链接到标题

类别:结构模式 中介/调节者模式:其实如果看过黑马的linux网络编程的话,你会感觉反应堆模型和这个还蛮像的,但这个是代码协作的模式。就是希望用户用类A时,可以只用一个mediator,而不用好多其他类来实现一个功能。

每个component要有指向mediator的指针,虚mediator要有一个notify虚函数给component用。concretemediator要指向所有component来调用他们,具体的调用代码就可以写在mediator里。

适用条件 链接到标题

Use the Mediator pattern when it’s hard to change some of the classes because they are tightly coupled to a bunch of other classes.

The pattern lets you extract all the relationships between classes into a separate class, isolating any changes to a specific component from the rest of the components.

Use the pattern when you can’t reuse a component in a different program because it’s too dependent on other components.

After you apply the Mediator, individual components become unaware of the other components. They could still communicate with each other, albeit indirectly, through a mediator object. To reuse a component in a different app, you need to provide it with a new mediator class.

Use the Mediator when you find yourself creating tons of component subclasses just to reuse some basic behavior in various contexts.

Since all relations between components are contained within the mediator, it’s easy to define entirely new ways for these components to collaborate by introducing new mediator classes, without having to change the components themselves.

State 链接到标题

类别:结构模式 状态模式:就是状态机的类设计的体现,整体架构很像strategy,但是在具体的状态里一般会引用调用状态类的类。

实现时,要把所有状态的共同操作提取出来,弄成基类,然后一个个实现。 我应该把图都偷过来的

适用条件 链接到标题

Use the State pattern when you have an object that behaves differently depending on its current state, the number of states is enormous, and the state-specific code changes frequently.

The pattern suggests that you extract all state-specific code into a set of distinct classes. As a result, you can add new states or change existing ones independently of each other, reducing the maintenance cost.

Use the pattern when you have a class polluted with massive conditionals that alter how the class behaves according to the current values of the class’s fields.

The State pattern lets you extract branches of these conditionals into methods of corresponding state classes. While doing so, you can also clean temporary fields and helper methods involved in state-specific code out of your main class.

Use State when you have a lot of duplicate code across similar states and transitions of a condition-based state machine.

The State pattern lets you compose hierarchies of state classes and reduce duplication by extracting common code into abstract base classes.

Memento 链接到标题

类别:行为模式 备忘录(便签,那种一层一层撕下来的,我的理解了)模式:这个是为了实现类似于文档编辑中undo,reverse操作的设计模式。

具体实现时,需要一个memento虚类,主要实现按名字索引,存储状态,返回状态,返回时间(就是状态的标签)。 然后一个具体的功能类(就是具体做业务流程的类),这个类要有restore和save功能,就用memento实现。 再来一个caretaker类,包含功能类的引用和memento类指针组,专门用于实现undo和backup功能(这个类起到了隔离作用,用户用这个类的功能来实现状态的undo和restore)。

适用条件 链接到标题

Use the Memento pattern when you want to produce snapshots of the object’s state to be able to restore a previous state of the object.

The Memento pattern lets you make full copies of an object’s state, including private fields, and store them separately from the object. While most people remember this pattern thanks to the “undo” use case, it’s also indispensable when dealing with transactions (i.e., if you need to roll back an operation on error).

Use the pattern when direct access to the object’s fields/getters/setters violates its encapsulation.

The Memento makes the object itself responsible for creating a snapshot of its state. No other object can read the snapshot, making the original object’s state data safe and secure.

Composite 链接到标题

类别:结构模式 组合模式:组合模式是解决树状结构难以访问,对外保证只用简单方法就可以使用树状结构的一个模式。就是这个类一定要是可以用树表达的。

其实就是树的应用了,比如说,一个高纬度箱子,里面可以继续装箱子或实际物品,然后要计算一个箱子装的所有东西的价值,现在就要用树了,要用户自己写便利不现实,就弄一个有getvalue的基类,所有物体和箱子都继承这个,然后箱子要有基类指针组,然后就是leetcode哪里那套了。

适用条件 链接到标题

Applicability

Use the Composite pattern when you have to implement a tree-like object structure.

The Composite pattern provides you with two basic element types that share a common interface: simple leaves and complex containers. A container can be composed of both leaves and other containers. This lets you construct a nested recursive object structure that resembles a tree.

Use the pattern when you want the client code to treat both simple and complex elements uniformly.

All elements defined by the Composite pattern share a common interface. Using this interface, the client doesn’t have to worry about the concrete class of the objects it works with.

Iterator 链接到标题

类别:结构模式 迭代器:将复杂的内部结构弄得可以用getnext和hasleft两个函数遍历出来,其实就是封装遍历过程。

我比较在意的是为什么示例中为什么又用了友元,这个的事件我大概率会用工厂给他包含就好。

适用条件 链接到标题

Use the Iterator pattern when your collection has a complex data structure under the hood, but you want to hide its complexity from clients (either for convenience or security reasons).

The iterator encapsulates the details of working with a complex data structure, providing the client with several simple methods of accessing the collection elements. While this approach is very convenient for the client, it also protects the collection from careless or malicious actions which the client would be able to perform if working with the collection directly.

Use the pattern to reduce duplication of the traversal code across your app.

The code of non-trivial iteration algorithms tends to be very bulky. When placed within the business logic of an app, it may blur the responsibility of the original code and make it less maintainable. Moving the traversal code to designated iterators can help you make the code of the application more lean and clean.

Use the Iterator when you want your code to be able to traverse different data structures or when types of these structures are unknown beforehand.

The pattern provides a couple of generic interfaces for both collections and iterators. Given that your code now uses these interfaces, it’ll still work if you pass it various kinds of collections and iterators that implement these interfaces.

chain of responsibility 链接到标题

类别:行为模式 责任链模式:其实咋一看实现和decorator很想,几乎没啥区别,也是派生类即包含又继承基类。但是区别还是有的,decorator是完全包含前面的方法,但责任链可以按心情看用不用前面的东西,或者直接停止。

适用条件 链接到标题

当程序需要以不同方式处理不同类型的请求,但具体请求类型及其顺序事先未知时,可以使用责任链模式。

该模式允许你将多个处理器连接到一条链中,并在收到请求时“询问”每个处理器是否能处理该请求。这样所有处理员都有机会处理请求。

当必须按特定顺序执行多个处理程序时,使用该模式。

由于你可以任意顺序连接链中的处理器,所有请求都会按你计划的方式通过链条。

当处理器集合及其顺序在运行时应当发生变化时,使用CoR模式。

如果你在处理程序类中为引用字段提供设置器,你就能动态插入、删除或重排处理程序。

command 链接到标题

类别:行为模式 命令模式:咋一看,是"啊啊啊,我真的要控制你了"这种感觉。其实完全是两码事了,本质是职责分离,一个类的功能要足够小。例子是,一个按钮,可以是复制按钮,可以是重置按钮,然后复制操作又可以用其他方法触发,比如ctrl+c(或者p)。这时最好是让按钮包含一个command类,command里写去调用复制功能的代码。

适用条件 链接到标题

Use the Command pattern when you want to parameterize objects with operations.

The Command pattern can turn a specific method call into a stand-alone object. This change opens up a lot of interesting uses: you can pass commands as method arguments, store them inside other objects, switch linked commands at runtime, etc.

Here’s an example: you’re developing a GUI component such as a context menu, and you want your users to be able to configure menu items that trigger operations when an end user clicks an item.

Use the Command pattern when you want to queue operations, schedule their execution, or execute them remotely.

As with any other object, a command can be serialized, which means converting it to a string that can be easily written to a file or a database. Later, the string can be restored as the initial command object. Thus, you can delay and schedule command execution. But there’s even more! In the same way, you can queue, log or send commands over the network.

Use the Command pattern when you want to implement reversible operations.

Although there are many ways to implement undo/redo, the Command pattern is perhaps the most popular of all.

To be able to revert operations, you need to implement the history of performed operations. The command history is a stack that contains all executed command objects along with related backups of the application’s state.

This method has two drawbacks. First, it isn’t that easy to save an application’s state because some of it can be private. This problem can be mitigated with the Memento pattern.

Second, the state backups may consume quite a lot of RAM. Therefore, sometimes you can resort to an alternative implementation: instead of restoring the past state, the command performs the inverse operation. The reverse operation also has a price: it may turn out to be hard or even impossible to implement.

vistord 链接到标题

类别:行为模式 拜访者模式:其实是允许向已经定义好的class里(用最小的类修改)加功能函数的一个方法~~(有意思的是,要我说,其实无论怎么样,加功能,改类,就是容易出bug,搞个这个模式复杂化后应该更容易出问题才是)~~。

具体做法中,让功能类继承一个accept函数,用于接受一个vistor,这个accept就只用调用vistor里的访问功能类的函数就对了。相当于让vistor里的函数可以让本来功能类使用。vistor类里的函数可能得要写多个vistor函数,因为可能需要访问多种不一样的class,那就需要多种函数了。

适用条件 链接到标题

Use the Visitor when you need to perform an operation on all elements of a complex object structure (for example, an object tree).

The Visitor pattern lets you execute an operation over a set of objects with different classes by having a visitor object implement several variants of the same operation, which correspond to all target classes.

Use the Visitor to clean up the business logic of auxiliary behaviors.

The pattern lets you make the primary classes of your app more focused on their main jobs by extracting all other behaviors into a set of visitor classes.

Use the pattern when a behavior makes sense only in some classes of a class hierarchy, but not in others.

You can extract this behavior into a separate visitor class and implement only those visiting methods that accept objects of relevant classes, leaving the rest empty.