Design patterns---Behavioral patterns

Behavioral patterns are concerned with algorithms and the assignment of responsibilities between objects.Behavioral patterns describe not just patterns of objects or classes but also the patterns of communication between them.These patterns characterize complex control flow that’s difficult to follow at run-time.They shift your focus away from flow of control to let you concentrate just on the way objects are interconnected.
*Behavioral class patterns use inheritance to distribute behavior between classes.
*Behavioral object patterns use object composition rather than inheritance.

I.Chain of responsibility
Intent:
Avoid couping the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.
To forward the request along the chain,and to ensure receivers remain implicit,each object on the chain shares a common interface for handling requests and for accessing its successor on the chain.
Applicability:Use Chain of Responsibility when:
*more than one object may handle a request,and the handler isn’t known a priori.The handler should be ascertained automatically.
*you want to issue a request to one of several objects without specifying the receiver explicitly.
*the set of objects that can handle a request should be specified dynamically.

Structure:
在这里插入图片描述
Consequences:Chain of Responsibility has the following benefits and liabilities:
*Reduced coupling.The pattern frees an object fom knowing which other object handles a request.
*Added flexibility in assigning responsibilities to objects.You can add or change responsibilities for handling a request by adding to or otherwise changing the chain at run-time.
*Receipt isn’t guaranted.The request can fall off the end of the chain without ever being handled.
Implementation:
*Implementing the successor chain.
(a)Define new links(usually in the Handler,but ConcreteHandlers could define them instead)
(b)Use existing links.
*Connecting successors.
Here’s a HelpHandler base class that maintains a successor link:

class HelpHandler{
    public:
    HelpHandler(HelpHandler* s) : _successor(s){}
    virtual void HandleHelp();
    private:
    HelpHandler* _successor;
};
void HelpHandler::HandleHelp(){
    if(_successor)
    {
        _successor->HandleHelp();
    }
}

*Representing requests.

void Handler::HandlerRequest(Request* theRequest)
{
    switch(theRequest->GetKind())
    {
        case Help:
        HandleHelp((HelpRequest*)theRequest);
        break;
        case Print:
        HandlePrint((PrintRequest*)theRequest);
        break;
        //...
        default:
        //...
        break;
    }
}
class ExtendedHandler:public Handler{
    public:
    virtual void HandleRequest(Request* theRequest);
    //...
};
void ExtendedHandler::HandleRequest(Request* theRequest)
{
       switch(theRequest->GetKind())
    {
        case Preview:
        HandlePre((PreRequest*)theRequest);
        break;
        default:
        Handler::HandleRequest(theRequest);
        break;
    }
}

Sample Code://C++,This is not a program
The following example illustrates how a chain of responsibility can handle requests for an on-line help system.

  typedef int Topic;
const Topic NO_HELP_TOPIC=-1;
class HelpHandler{
    public:
    HelpHandler(HelpHandler* =0,Topic = NO_HELP_TOPIC);
    virtual bool HasHelp();
    virtual void SetHandler(HelpHandler*,Topic);
    virtual void HandleHelp();
    private:
    HelpHandler* _successor;
    Topic _topic;
};
HelpHandler::HelpHandler(HelpHandler* h,Topic t): _successor(h),_topic(t){}
bool HelpHandler::HasHelp(){return _topic!=NO_HELP_TOPIC;}
void HelpHandler::HandleHelp(){
    if(_successor!=0)
    _successor->HandleHelp();
}
class Widget:public HelpHandler{
    protected:
    Widget(Widget* parent,Topic t=NO_HELP_TOPIC);
    private:
    Widget* _parent;
};
Widget::Widget(Widget* w,Topic t):HelpHandler(w,t){
    _parent=w;
}
class Button:public Widget{
  public:
  Button(Widget* d,Topic t=NO_HELP_TOPIC);
  virtual void HandleHelp();
  //Widget operations that Button overrides...
};
Button::Button(Widget* h,Topic t):Widget(h,t){}

void Button::HandleHelp(){
    if(HasHelp())
    {
        //offer help on the button
    }
    else{
        HelpHandler::HandleHelp();
    }
}
class Dialog:public Widget{
    public:
    Dialog(HelpHandler* h,Topic t=NO_HELP_TOPIC);
    virtual void HandleHelp();
    //Widget operations that Dialog overrides...
};

Dialog::Dialog(HelpHandler* h,Topic t):Widget(0){
    SetHandler(h,t);
}
void Dialog::HandleHelp(){
    if(HasHelp())
    {
        //offer help on the dialog
    }
    else{
        HelpHandler::HandleHelp();
    }
}
class Application:public HelpHandler{
    public:
    Application(Topic t):HelpHandler(0,t){}
    virtual void HandleHelp();
    //application-specific operations
};
void Application::HandleHelp(){
    //show a list of help topics
}
//How to use? The handle will be passed to application finally.you can //change the topic to catch the handle in the mid of chain.
Application* application=new Application(3);
Dialog* dialog=new Dialog(application,-1);
Dialog* button=new Button(dialog,-1);
button->HandleHelp();

Related patterns:
Chain of responsibilities if often applied in conjunction with Composite.There,a component’s parent can act as its successor.

II.Command
Intent:
Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.
Applicability:
Use the Command pattern when you want to:
*parameterize objects by an action to perform.
*specify,queue,and excute requests at different times.
*support undo.
*support logging changes so that they can be reapplied in case of a system crash.
*structure a system around high-level operations built on primitives operations.

Structure:
在这里插入图片描述Collaborations:
The following diagram shows the interactions between these objects.It illustrates how command decouples the invoker from the receiver(and the request it carries out.)
在这里插入图片描述

Consequences:
The command pattern has the following consequences:
*Command decouples the object that invokes the operation from the one that knows how to perform it.
*Commands are first-class objects.They can be manipulated and extended like any other object.
*You can assemble commands into a composite command.
*It’s easy to add new Commands,because you don’t have to changing existing classes.
Implementation:
*How intelligent should a command be?
*Supporting undo and redo.
A ConcreteCommand class might need to store additional state to do so.This state can include:
The receiver object,which actually carries out operations in response to the request,
the arguments to the operation performed on the receiver,and
any original values in the receiver that can change as a result of handling the request.The receiver must provide operations that let the command return the receiver to its prior state.

*Avoiding error accumulation in the undo process.
*Using C++ templates.

Sample Code://C++,This is not a program


```cpp
  class Command
{
    virtual ~Command();
    virtual void Execute()=0;
    protected:
    Command();
};
class OpenCommand:public Command{
    public:
    OpenCommand(Application*);
    virtual void Execute();
    protected:
    virtual const char* AskUser();
    private:
    Application* _application;
    char* _response;
};
OpenCommand::OpenCommand(Application* a){
    _application=a;
}
void OpenCommand::Execute(){
    const char* nteame=AskUser();
    if(name!=0)
    {
        Document* document=new Document(name);
        _application->Add(document);
        document->Open();
    }
}
class PasteCommand:public Command{
    public:
    PasteCommand(Document*);
    virtual void Execute();
    private:
    Document* _document;
};
PasteCommand::PasteCommand(Document* doc){
    _document=doc;
}
void PasteCommand::Execute(){
    _document->Paste();
}
/*For simple commands that aren't undoable and don't require arguments,
we can use a class template to parameterize the command's receiver*/

template<class Receiver>
class SimpleCommand:public Command{
    public:
    typedef void (Receiver::* Action)();
    SimpleCommand(Receiver* r,Action a):
    _receiver(r),_action(a){}
    virtual void Execute();
    private:
    Action _action;
    Receiver* _receiver;
};
template<class Receiver>
void SimpleCommand<Receiver>::Execute(){
    (_receiver->*_action)();
}
//How to use?
MyClass * receiver=new MyClass;
//...
Command* aCommand=new SimpleCommand<MyClass>(receiver,&MyClass::Action);
//...
aCommand->Execute();

//The flowing shows a more complicated situation.
class MacroCommand:public Command{
    public:
    MacroCommand();
    virtual ~MacroCommand();

    virtual void Add(Command*);
    virtual void Remove(Command*);

    virtual void Execute();
    private:
    List<Command*>* _cmds;
};
void MacroCommand::Execute(){
    ListIterator<Command*> i(_cmds);
    for(i.First();!i.IsDone();i.Next())
    {
        Command* c=i.CurrentItem();
        c->Execute();
    }
}
void MacroCommand::Add(Command* c)
{
    _cmds->Append(c);
}
void MacroCommand::Remove(Command*c)
{
    _cmds->Remove(c);
}

Related Patterns:
A Composite can be used to implement MacroCommands.
A Memento can keep state the command requires to undo its effect.
A command that must be copied before being placed on the history list acts as a Prototype.

III.Interpreter
Intent:
 Given a language,define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
 The Interpreter pattern uses a class to represent each grammar rule.
 For example:
 The abstract syntax tree:
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200629160631704.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZqeV9oaGho,size_16,color_FFFFFF,t_70)represents the regular expression:
 raining&(dogs|cats)*

Applicability:
Use the interpreter pattern when there is a language to interpret,and you can represent statements in the language as abstract syntax trees.The interpreter pattern works best when:
*The grammar is simple.
*Efficiency is not a critical pattern.

Structure:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200629161138975.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZqeV9oaGho,size_16,color_FFFFFF,t_70)
Consequences:
The interpreter pattern has the following benefits and liabilities:
*It's easy to change and extend the grammar.
*Implementing the grammar is easy,too.
*Complex grammar are hard to maintain.
*Adding new ways to interpret expressions.

Implementation:
*Creating the abstract syntax tree.
*Defining the Interpret operation.
*Sharing terminal symbols with the Flyweight pattern.

Sample Code://C++,Not a program
The example is a system for manipulating and evaluating Boolen expression implemented in C++.The terminal symbols in this language are Boolen variables,that is,the constants true and false.Nonterminal symbols represent expressions containing the operators and ,or ,not.The gammar is defined follows:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200629163903742.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZqeV9oaGho,size_16,color_FFFFFF,t_70)

```cpp
class BooleanExp{
    public:
    BooleanExp();
    virtual ~BooleanExp();

    virtual bool Evaluate(Context&)=0;
    virtual BooleanExp* Replace(const char*,BooleanExp&)=0;
    virtual BooleanExp* Copy() const=0;
};
class Context{
    public:
    bool Lookup(const char*);
    void Assign(VariableExp*,bool);    
};
class VariableExp:public BooleanExp{
    public:
    VariableExp(const char*);
    virtual ~VariableExp();
    virtual bool Evaluate(Context&);
    virtual BooleanExp* Replace(const char*,BooleanExp&);
    virtual BooleanExp* Copy() const;
    private:
    char* _name;
};
VariableExp::VariableExp(const char* name)
{
    strcpy(_name,name);
}
bool VariableExp::Evaluate(Context& aContext){
    return aContext.Lookup(_name);
}
BooleanExp* VariableExp::Copy()const{
    return new VariableExp(_name);
}
BooleanExp* VariableExp::Replace(const char* name,BooleanExp& exp)
{
    if(strcmp(name,_name)==0)
    return exp.Copy();
    else
   return new VariableExp(_name);
}
class AndExp:public BooleanExp{
    public:
    AndExp(BooleanExp*,BooleanExp*);
    virtual ~AndExp();
    virtual bool Evaluate(Context&);
    virtual BooleanExp* Replace(const char*,BooleanExp&);
    virtual BooleanExp* Copy()const;
    private:
    BooleanExp* _operand1;
    BooleanExp* _operand2;
};
AndExp::AndExp(BooleanExp* op1,BooleanExp* op2)
{
    _operand1=op1;
    _operand2=op2;
}
bool AndExp::Evaluate(Context& aContext)
{
    return 
    _operand1->Evaluate(aContext)&&
    _operand2->Evaluate(aContext);
}
BooleanExp* AndExp::Copy()const{
    return new AndExp(_operand1->Copy(),_operand2->Copy());
}
BooleanExp* AndExp::Replace(const char* name,BooleanExp& exp)
{
    return new AndExp(_operand1->Replace(name,exp),_operand2->Replace(name,exp));
}

Related pattern:
Composite:The abstract syntax tree is an instance of the Composite pattern.
Flyweight:show how to share terminal symbols within the abstract syntax tree.
Iterator:The interpreter can use an Iterator to traverse the structure
Vistor:can be used to maintain the behavior in each node in the astract syntax tree in one class.

IV.Iterator
Intent:
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
Applicability:
Use the Iterator pattern:
*To access an aggregate object’s contents without exposing its internal representation.
*To support multiple traversals of aggregate objects.
*To provide a uniform interface for traversing different aggregate structures(that is,to support polymorphic iteration)

Structure:
在这里插入图片描述
Consequences:
*It supports variations in the traversal of an aggregate.
*Iterators simplify the Aggregate interface.
*More than one traversal can be pending on an aggregate.

Implementation:
*Who controls the iteration?external iterator or internal iterator.
*Who defines the traversal algorithm?aggregate or iterator
*How robust is the iterator?
*Additional Iterator operations.
*Using polymorphic iterators in C++.
*Iterators may have privileged access.
*Iterators for composites.
*Null iterators.A NullIterator is a degenerate iterator that’s helpful for handling boundary conditions.

Sample code://C++,This is not a program.

class AbstractList{
    public:
    virtual Iterator<Item>* CreateIterator() const=0;
    //...
};
template<class Item>
class List:public AbstractList<Item>{
    public:
    List(long size=DEFAULT_LIST_CAPACITY);
    long Count()const;
    Item& Get(long index)const;
    //...
};
template<class Item>
Iterator<Item>* List<Item>::CreateIterator() const{
  return new ListIterator<Item>(this);
}
template<class Item>
class Iterator{
    public:
    virtual void First()=0;
    virtual void Next()=0;
    virtual bool IsDone() const=0;
    virtual Item CurrentItem() const =0;
    protected:
    Iterator();
};
template<class Item>
class ListIterator:public Iterator<Item>{
    public:
    ListIterator(const List<Item>* aList)
    virtual void First();
    virtual void Next();
    virtual bool IsDone() const;
    virtual Item CurrentItem() const ;
    protected:
    const List<Item>* _list;
    long _current;
};
template<class Item>
ListIterator<Item>::ListIterator(const List<Item>* aList){
    _list=aList;
    _current=0;
}
template<class Item>
void ListIterator<Item>::First(){
    _current=0;
}
template<class Item>
void ListIterator<Item>::Next(){
    _current++;
}
template<class Item>
bool ListIterator<Item>::IsDone(){
    return _current>=_list->Count();
}
template<class Item>
Item ListIterator<Item>::CurrentItem(){
    if(IsDone())
     throw IteratorOutOfBounds;
     return _list->Get(_current);
}
//Use proxy pattern to delete list for clients
template<class Item>
class IteratorPtr{
    public:
    IteratorPtr(Iterator<Item>* i):_i(i){}
    ~Iterator(){delete _i;}
    Iterator<Item>* operator->(){return _i;}
    Iterator<Item>& operator*(){return *_i;}
    private:
    //disallow copy and assignment to avoid
    //multiple deletions of _i:
    IteratorPtr(Const IteratorPtr);
    IteratorPtr& operator=(const IteratorPtr&);
    private:
    Iterator<Item>*_i;
};
//How to use ?
void PrintEmployees(Iterator<Employee*>& i)
{
    for(i.First();!i.IsDone();i.Next())
    i.CurrentItem()->Print();
}
AbstractList<Employee*>* employees;
IteratorPtr<Employee*>iterator(employees->CreateIterator());
PrintEmployees(*iterator);
//The following example shows what a internal ListIterator look like.
//We use subclassing to perform the special operation.
template<class Item>
class ListTraverser{
    public:
    ListTraverser(List<Item>* aList);
    bool Traverse();
    protected:
    virtual bool ProcessItem(const Item&)=0;
    private:
    ListIterator<Item> _iterator;
};
template<class Item>
ListTraverser<Item>::ListTraverser(List<Item>* aList):_iterator(aList){}
template<class Item>
bool ListTraverser<Item>::Traverse(){
    bool result=false;
    for(_iterator.First();!_iterator.IsDone();_iterator.Next())
    {
        result=ProcessItem(_iterator.CurrentItem);
        if(result= =false)
        break;
    }
    return result;
}
//Internal Iterator to print first 10 employees
class PrintNEmployees:public ListTraverser<Employee*>
{
    public:
    PrintNEmployees(List<Employee*>* aList,int n)
    {
        ListTraverser<Employee*>(aList);
        _total=n;
        _count=0;
    }
    protected:
    bool ProcessItem(Employee* const&);
    private:
    int _total;
    int _count;
};
bool PrintNEmployees::ProcessItem(Employee* const& e)
{
    _count++;
    e->Print();
    return _count<_total;
}
//How to use? for internal Iterator
List<Employee*>* employees;
//...
PrintNEmployees pa(employees,10);
pa.Traverse();
//for external Iterator
ListIterator<Employee*> i(employees);
int count=0;
for(i.First();!i.IsDone();i.Next())
{
    count++;
    i.CurrentItem()->Print();
    if(count>=10)
    break;
}
//What's more ,Internal iterators can encapsulate different kinds of iteration.
template<class Item>
class FilteringListTraverser{
    public:
    FilteringListTraverser(List<Item>* aList);
    bool Traverse();
    protected:
    virtual bool ProcessItem(const Item&)=0;
    virtual bool TestItem(const Item&)=0;
    private:
    ListIterator<Item> _iterator;
}
bool FilteringListTraverser<Item>::Traverse(){
    bool result=false;
    for(_iterator.First();!_iterator.IsDone();_iterator.Next())
    {
        if(TestItem(_iterator.CurrentItem())){
        result=ProcessItem(_iterator.CurrentItem);
        if(result==false)
        break;
    }
    }
    return result;
}

Related patterns:
Composite:Iterators are often applied to recursive structures such as Composite
Factory Method:Polymorphic iterators rely on factory methods to instantiate the appropriate Iterator subclass.
Memento is often used in conjucetion with the Iterator pattern.An iterator can use a memento to capture the state of an iteration.The iterator stores the memento internally.

V.Mediator
Intent:
Define an object that encapsulates how a set of objects interact.Mediator promotes loose couping by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.
Applicability:
Use the Mediator pattern when:
*a set of objects communicate in well-defined but complex ways.The resulting interdependencies are unstructured and difficult to understand.
*reusing an object is difficult because it refers to and communicates with many other objects.
*a behavior that’s distributed between several classes should be customizable without a lot of sublassing.

Structure:
在这里插入图片描述
A typical object structure might look like this:
在这里插入图片描述Consequences:
The Mediator pattern has the following benefits and drawbacks:
*It limits subclassing.
*It decouples colleagues.
*It simplifies object protocols.
*It abstracts how objects cooperate.
*It centralizes control(a draw back)

Implementation:
*Omitting the abstract Mediator class.
*Colleague-Mediator communication.

Sample Code:

class DialogDirector{
    public:
    virtual ~DialogDirector();
    virtual void ShowDialog();
    virtual void WidgetChanged(Widget*)=0;
    protected:
    DialogDirector();
    virtual void CreateWidgets()=0;
};
class Widget{
    public:
    Widget(DialogDirector*);
    virtual void Changed();
    virtual void HandleMouse(MouseEvent& event);
    //...
    private:
    DialogDirector* _director;
};
void Widget::Changed(){
    _director->WidgetChanged(this);
}
class ListBox::public Widget{
    public:
    ListBox(DialogDirector*);
    virtual const char* GetSelection();
    virtual void SetList(List<char*>* listItems);
    virtual void HandleMouse(MouseEvent& event);
    //...
};
class EntryField:public Widget{
    public:
    EntryField(DialogDirector*);
    virtual void SetText(const char* text);
    virtual const char* GetText();
    virtual void HandleMouse(MouseEvent& event);
    //...
};
class Button:public Widget{
    public:
    Button(DialogDirector*);
    virtual void SetText(const char* text);
    virtual void HandleMouse(MouseEvent& event);
    //...
};
void Button::HandleMouse(MouseEvent& event)
{
    //...
    Changed();
}
class FontDialogDirector:public DialogDirector{
    public:
    FontDialogDirector();
    virtual ~FontDialogDirector();
    virtual void WidgetChanged(Widget*);
    protected:
    virtual void CreateWidgets();
    private:
    Button* _ok;
    Button* _cancel;
    ListBox* _fontList;
    EntryField* _fontName;
};
void FontDialogDirector::CreateWidgets(){
    _ok=new Button(this);
    _cancel=new Button(this);
    _fontList=new ListBox(this);
    _fontName=new EntryField(this);
    //fill the listBox with the available font names.
    //assemble the widgets in the dialog
}

void FontDialogDirector::WidgetChanged(Widget* theChangedWidget)
{
    if(theChangedWidget==_fontList)
    {
        _fontName->SetText(_fontList->GetSelection());
    }
    else if(theChangedWidget==_ok)
    {
        //apply font change and dismiss dialog
        //...
    }
    else if(theChangedWidget==_cancel)
    {
        //dismiss dialog
    }
}

Related pattern:
Facade differs from Mediator in that it abstracts a subsystem of objects to provide a more convenient interface.Its protocol is unidirectional;that is,Facade objects make requests of the subsystem classes but not vice versa.In contrast,Mediator enables cooperative behavior that colleague objects don’t or can’t provide,and the protocol is multidirectional.
Colleagues can communicate with the mediator using the Observer pattern.

VI. Memento
Intent:
Without violating encapsulation,capture and externalize an object’s internal state so that the object can be restored to this state later.
A memento is an object that stores a snapshot of the internal state of another object—The memento’s originator.
Applicability:
Use the Memento pattern when:
*a snapshot of an object’s state must be saved so that it can be restored to that state later and
*a direct interface to obtaining the state would expose implementation details and break the object’s encapsulation.
Structure:
在这里插入图片描述Collaborations:
*A caretaker requests a memento from an originator,holds it for a time,and passes it back to the originator,as the following interaction diagram illustrates:
在这里插入图片描述Sometimes the caretaker won’t pass the memento back to the originator,because the originator might never need to revert to an earlier state.
*Mementos are passive.Only the originator that created a memento will assign or retrieve its state.

Consequences:
*Preserving encapsulation boundaries.
*It simplifies originator.
*Using mementos might be expensive.
*Defining narrow and wide interfaces.
*Hidden costs in caring for mementos.

Implementation:
*Language support.Mementos have two interfaces:a wide one for originators and a narrow one for other objects.
eg://C++

class State;
class Originator{
    public:
    Memento* CreateMemento();
    void SetMemento(const Memento*);
    //...
    private:
    State* _state;
    //...
};
class Memento{
 public:
 //narrow public interface
 virtual ~Memento();
 private:
 //private members accessible only to originator
 friend class Originator;
 Memento();
 void SetState(State*);
 State* GetState();
 //...
 private:
 State* _state;
};

*Storing incremental changes.

Sample Code://C++,Not a program.

class Graphic;
class MoveCommand{
    public:
    MoveCommand(Graphic* target,const Point& delta);
    void Execute();
    void Unexecute();
    private:
    ConstraintSolverMemento* _state;
    Point _delta;
    Graphic* _target;
};
class ConstraintSolver{
    public:
    static ConstraintSolver* Instance();
    void Solve();
    void AddConstraint(Graphic* startConnection,Graphic* endConnection);
    void RemoveConstraint(Graphic* startConnection,Graphic* endConnection);
    ConstraintSolverMemento* CreateMemento();
    void SetMemento(ConstraintSolverMemento*);
    private:
    //...
};
class ConstraintSolverMemento{
  public:
  virtual ~ConstraintSolverMemento();
  private:
  friend class ConstraintSolver;
  ConstraintSolverMemento();
  //private Constraint Solver State
};
/*We can implement MoveCommand like this*/
void MoveCommand::Execute(){
    ConstraintSolver* solver=ConstraintSolver::Instance();
    _state=solver->CreateMemento();
    _target->Move(_delta);
    solver->Solve();
}
void MoveCommand::Unexecute(){
    ConstraintSolver* solver=ConstraintSolver::Instance();
    _target->Move(-_delta);
    solver->SetMemento(_state);
    solver->Solve();
}

Related patterns:
*Command:Commands can use mementos to maintain state for undoable operations.
*Iterator:Mementos can be use for iteration .

VII.Observer
Intent:
Define a one-to-many dependency between objects so that hen one object changes state,all its dependents are notified and updated automatically.
It is also known as Publish-Subscribe.
Applicability:
Use the Observer pattern in any of the following situations:
*When an abstraction has two aspects ,one dependent on the other.Encapsulating these aspects in separate objects lets you vary and reuse them independently.
*When a change to one object requires changing others,and you don’t know how many objects need to be changed.
*When an object should be able to notify other objects without making asumptions about who these objects are.In other words,you don’t want these objects tightly coupled.
Structure:
在这里插入图片描述Collaborations:
*ConcreteSubject notifies its observers whenever a change occurs that could make its observers’ state inconsistent with its own.
*After being informed of a change in the concrete subject,a ConcreteObserver object may query the subject for information.ConcreteObserver uses this information to reconcile its state with that of the subject.
在这里插入图片描述
Consequences:
*Abstract coupling between Subject and Observer.All a subject knows is that it has a list of observers,each confroming to the simple interface of the abstract Observer class.The subject doesn’t know the concrete class of any observer.
*Support for broadcast communication.
*Unexpected updates.

Implementation:
*Mapping subjects to their observers.
*Observing more than one subject.
*Who triggers the update?

Here are two options:
(a)Have state-setting operations on Subject call Notify after they change the subject’s state.
(b)Make clients responsible for calling Notify at the right time.

*Dangling references to deleted subjects.
*Making sure Subject state is self-consistent before notification.
*Avoiding observer-specific update protocols:the push and pull models.
*specifying modifications of interest explicitly.
*Encapsulating complex update semantics.
*Combining the Subject and Observer classes.

Sample Code://C++,Not a program

class Observer{
    public:
    virtual ~Observer();
    virtual void Update(Subject* theChangedSubject)=0; //support multiple subjects
    protected:
    Observer();
};
class Subject{
    public:
    virtual ~Subject();
    virtual void Attach(Observer*);
    virtual void Detach(Observer*);
    virtual void Notify();
    protected:
    Subject();
    private:
    List<Observer*> *_observers;
};
void Subject::Attach(Observer* o)
{
    _observers->Append(o);
}
void Subject::Detach(Observer* o)
{
    _observers->Remove(o);
}
void Subject::Notify(){
    ListIterator<Observer*> i(_observers);
    for(i.First();!i.IsDone();i.Next())
    i.CurrentItem()->Update(this);
}
class ClockTimer:public Subject{
    public:
    ClockTimer();
    virtual int GetHour();
    virtual int GetMinute();
    virtual int GetSecond();
    void Tick();
};
void ClockTimer::Tick(){
    //Update internal time-keeping state
    //...
    Notify();
}
class DigitalClock:public Widget,public Observer{
    public:
    DigitalClock(ClockTimer*);
    virtual ~DigitalClock();
    virtual void Update(Subject*);
    //overrides Observer operation
    virtual void Draw();
    //overrides Widget operation;
    //defines how to draw the digital clock
    private:
    ClockTimer* _subject;
};
DigitalClock::DigitalClock(ClockTimer* s)
{
    _subject=s;
    _subject->Attach(this);
}
DigitalClock::~DigitalClock(){
    _subject->Detach(this);
}
/*Before the Update operation draws the clock face,
it checks to make sure the notifying subject is clock's subject*/
void DigitalClock::Update(Subject *theChangedSubject)
{
    if(theChangedSubject==_subject)
    Draw();
}
void DigitalClock::Draw(){
    int hour=_subject->GetHour();
    int minute=_subject->GetMinute();
    ///etc
}
class AnalogClock:public Widget,public Observer{
    public:
    AnalogClock(ClockTimer*);
    virtual void Update(Subject*);
    virtual void Draw();
    //...
};

//How to use?
ClockTimer* timer=new ClockTimer;
AnalogClock* analogClock=new AnalogClock(timer);
DigitalClock* digitalClock=new DigitalClock(timer);

Related Patterns:
Mediator:By encapsulating complex update semantics,the ChangeManager acts as mediator between subjects and observers.
Singleton:The ChangeManager may use the Singleton pattern to make it unique and globally accessible.

VIII. State
Intent:
Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.
Applicability:Use the State pattern in either of the following cases:
*An object’s behavior depends on its state,and it must change its behavior at run-time depending on that state.
*Operations have large,multipart conditional statements that depend on the object’s state.
Structure:
在这里插入图片描述
Consequences:
*It localizes state-specific behavior and partitions behavior for different states.The State pattern puts all behavior associated with a particular state into one object.
*It makes state transitions explicit.
*State objects can be shared.

Implementation:
*Who defines the state transitions?
*A table-based alternative.
*Creating and destroying State objects.
*Using dynamic inheritance.

Sample Code://C++,Not a program

class TCPOctetStream;
class TCPConnection{
    public:
    TCPConnection();
    void ActiveOpen();
    void PassiveOpen();
    void Close();
    void Send();
    void Acknowledge();
    void Synchronize();
    void ProcessOctet(TCPOctetStream*);
    private:
    friend class TCPState;
    void ChangeState(TCPState*);
    TCPState* _state;
};
class TCPState{
    public:
    virtual void Transmit(TCPConnection*,TCPOctetStream*);
    virtual void ActiveOpen(TCPConnection*);
    virtual void PassiveOpen(TCPConnection*);
    virtual void Close(TCPConnection*);
    virtual void Synchronize(TCPConnection*);
    virtual void Acknowledge(TCPConnection*);
    virtual void Send(TCPConnection*);
    protected:
    void ChangeState(TCPConnection*,TCPState*);
};
TCPConnection::TCPConnection(){
    //_state=TCPClosed::Instance();
}
void TCPConnection::ChangeState(TCPState*s)
{
    _state=s;
}
void TCPConnection::ActiveOpen(){
    _state->ActiveOpen(this);
}
void TCPConnection::PassiveOpen(){
    _state->PassiveOpen(this);
}
void TCPConnection::Close(){
    _state->Close(this);
}
void TCPConnection::Acknowledge(){
    _state->Acknowledge(this);
}
void TCPConnection::Synchronize(){
    _state->Synchronize(this)
}
void TCPState::Transmit(TCPConnection*,TCPOctetStream*){}
void TCPState::ActiveOpen(TCPConnection*){}
void TCPState::PassiveOpen(TCPConnection*){}
void TCPState::Close(TCPConnection*){}
void TCPState::Synchronize(TCPConnection*){}

void TCPState::ChangeState(TCPConnection* t,TCPState*s)
{
    t->ChangeState(s);
}
class TCPEstablished:public TCPState{
    public:
    static TCPState* Instance();
    virtual void Transmit(TCPConnection*,TCPOctetStream*);
    virtual void Close(TCPConnection*);
};
class TCPListen:public TCPState{
    public:
    static TCPState* Instance();
    virtual void Send(TCPConnection*);
    //...
};
class TCPClosed:public TCPState{
    public:
    static TCPState* Instance();
    virtual void ActiveOpen(TCPConnection*);
    virtual void PassiveOpen(TCPConnection*);
    //...
};
void TCPClosed::ActiveOpen(TCPConnection* t)
{
    //send SYN,reveive SYN,ACK,etc
    ChangeState(t,TCPEstablished::Instance());
}
void TCPClosed::PassiveOpen(TCPConnection*t)
{
    ChangeState(t,TCPListen::Instance());
}
void TCPEstablished::Close(TCPConnection*t)
{
    //send FIN,receive ACK of FIN
    ChangeState(t,TCPListen::Instance())
}
void TCPEstablished::Transmit(TCPConnection*t,TCPOctetStream*o)
{
    t->ProcessOctet(o);
}
void TCPListen::Send(TCPConnection*t)
{
    //send SYN,receive SYN,ACK,etc.
    ChangeState(t,TCPEstablished::Instance());
}
/*
After performing state-specific work,these operations call 
ChangeState operation to change the state of the TCPConnection.
*/

Related patterns:
The flyweight pattern explains when and how State objects can be shared.State objects are often Singletons.

IX.Strategy
Intent:
Define a family of algorithms,encapsulate each one,and make them interchangeable.Strategy lets the algorithms vary independently from clients that use it.
Applicability:Use the Strategy pattern when:
*many related classes differ only in their behavior.Strategies provide a way to configure a class with one of many behaviors.
*you need different variants of an algorithm.
*an algorithm uses data that clients shouldn’t know about.
*a class defines many behaviors,and these appear as multiple conditional statements in its operation.

Structure:
在这里插入图片描述Consequences:
Benefits:
*Families of related algorithms.
*An alternative to subclassing.
*Strategies eliminate conditional statements.
*A choice of implementations.
Drawbacks:
*Clients must be aware of different Strategies.
*Communication overhead between strategy and context.
*Increased number of objects.

Implementation:
*Defining the Strategy and Context interfaces.The Strategy and Context interfaces must give a ConcreteStrategy efficient access to any data it need from a context,and vice versa.
*Strategies as template parameters.This technique is only applicable if (1)the Strategy can be selected at compile-time,and (2)it does not have to be changed at run-time.

template<class AStrategy>
class Context
{
   void Operation(){theStrategy.DoAlgorithm();}
   //...
   private:
   AStrategy theStrategy;
};
class MyStrategy{
    public:
    void DoAlgorithm();
};
Context<MyStrategy>aContext;

*Making Strategy objects optimal.

Sample Code://C++,Not a program

class Composition{
    public:
    Composition(Compositor*);
    void Repair();
    private:
    Compositor* _compositor;
    Component* _components;
    int _componentCount;
    int _lineWidth;
    int *_lineBreaks;/*The position of linebreaks in components*/
    int _lineCount;
};
class Compositor{
    public:
    virtual int Compose(Coord natural[],Coord stretch[],Coord shrink[],
    int componentCount,int lineWidth ,int breaks[])=0;
    protected:
    Compositor();
};
void Composition::Repair(){
    Coord* natural;
    Coord* stretchability;
    Coord* shrinkability;
    int componentCount;
    int *break;
    //prepare the arrays with the desired component sizes
    //...
    //determine where the breaks are:
    int breakCount;
    breakCount=_compositor->Compose(natural,stretchability,shrinkability,componentCount,_lineWidth,breaks);
    //lay out components according to breaks
    //...
}
class SimpleCompositor:public Compositor{
    public:
    SimpleCompositor();
    virtual int Compose(Coord natural[],Coord Stretch[],Coord shrink[],
    int componentCount,int lineWidth,int breaks[]);
    //...
};
class TeXCompositor:public Compositor{
    public:
    TeXCompositor();
    virtual int Compose(Coord natural[],Coord Stretch[],Coord shrink[],
    int componentCount,int lineWidth,int breaks[]);
    //...
};
class ArrayCompositor:public Compositor{
    public:
    ArrayCompositor(int interval);
    virtual int Compose(Coord natural[],Coord Stretch[],Coord shrink[],
    int componentCount,int lineWidth,int breaks[]);
    //...
};
//How to use?
Composition* quick=new Composition(new SimpleCompositor);
Composition* slick=new Composition(new TeXCompositor);
Composition* iconic=new Composition(new ArrayCompositor(100));

Related patterns:
Flyweight:Strategy objects often make good flyweights.

X.Template Method
Intent:
Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
Applicability:The Template Method pattern should be used
*to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary.
*when common behavior among subclasses should be factored and localized in a common class to avoid code duplication.

  • to control subclasses extensions.

Structure:
在这里插入图片描述

Consequences:
Template methods are a fundamental technique for code reuse.
Tempalte methods lead to an inverted control structure that’s sometimes referred to as “the Holldwood principle”,that is,“Don’t call us,we’ll call you”.
Template methods call the following kinds of operations:
*concrete operations(either on the ConcreteClass or on client classes);
*concrete AbstractClass operations;
*primitive operations;
*factory methods;
*hook operations.

Implementation:
Three implementation issues are worth noting:
*Using C++ access control.
*Minimizing primitive operations.
*Naming conventions.

Sample Code://C++,Not a program

void View::Display(){
    SetFocus();
    DoDisplay();
    ResetFocus();
}
void View::DoDisplay(){}
void MyView::DoDisplay(){
    //render the view's contents
}

Related Patterns:
Factory Methods are often called by template methods.
Strategy:Template methods use inheritance to vary part of an algorithm.Strategies use delegation to vary the entire algorithm.

XI.Visitor
Intent:
Represent an operation to be performed on the elements of an object structure.Visitor lets you define a new operation without changing the classes of the elements on which it operates.
With the Visitor pattern,you define two class hierarchies:one for the elements being operated on and one for the visitors that define operations on the elements.You create a new operation by adding a new subclass to the visitor class hierarchy.

Applicability:Use the visitor pattern when
*an object structure contains many classes of objects with differing interfaces,and you want to perform operations on these objects that depend on their concrete classes.
*many distinct and unrelated operations need to be performed on objects in an object structure,and you want to avoid "polluting"their classes with these operations.
*the classes defining the object structure rarely change,but you often want to define new operations over the structure.

Structure:
在这里插入图片描述Collaborations:
*A client that uses the Visitor pattern must create a ConcreteVisitor object and then traverse the object structure,visiting each element with the visitor.
*When an element is visited,it calls the Visitor operation that corresponds to its class.
The following interaction diagram illustrates the collaborations between an object structure ,a visitor,and two elements:
在这里插入图片描述Consequences:
Benefits:
*Visitor makes adding new operations easy.
*A visitor gathers related operations and separates unrelated ones.
*Visiting across class hierarchies.
*Accumulating state.
Liabilities:
*Adding new ConcreteElement classes is hard.
*Breaking encapsulation.

Implementation:
Each object structure will have an associated Visitor class.
The Visitor class would be declared like this in C++:

class Visitor{
    public:
    virtual void VisitElementA(ElementA *);
    virtual void VisitElementB(ElementB *);
    virtual void VisitCompositeElement(CompositeElement*);
    //and so on for other concrete elements
    protected:
    Visitor();
};
class Element{
    public:
    virtual ~Element();
    virtual void Accept(Visitor&)=0;
    protected:
    Element();
};
class ElementA:public Element{
    public:
    ElementA();
    virtual void Accept(Visitor& v){v.VisitElementA(this);}
};
class ElementB:public Element{
    public:
    ElementB();
    virtual void Accept(Visitor& v){v.VisitElementB(this);}
};
class CompositeElement:public Element{
    public:
    virtual void Accept(Visitor&);
    private:
    List<Element*>* _children;
};
void CompositeElement::Accept(Visitor& v)
{
    ListIterator<Element*> i(_children);
    for(i.First();!i.IsDone();i.Next())
    {
        i.CurrentItem()->Accept(v);
    }
    v.VisitCompositeElement(this);
}

Here are two other implementation issues that arise when you apply the Visitor pattern:
*Double dispatch.This is the key to the Visitor pattern:The operation that gets executed depends on both the type of Visitor and the type of Element it visits.
*Who is responsible for traversing the object structure?We can put responsibility for traversal in any of three places:in the object structure(usually),in the visitor,or in a separate iterator object.

Sample Code://C++,Not a program

class Equipment{
    public:
    virtual ~Equipment();
    const char* Name(){return _name;}
    virtual Watt Power();
    virtual Currency NetPrice();
    virtual Currency DiscountPrice();
    virtual void Accept(EquipmentVisitor&);
    protected:
    Equipment(const char*);
    private:
    const char* _name;
};
class EquipmentVisitor{
    public:
    virtual ~EquipmentVisitor();
    virtual void VisitFloppyDisk(FloppyDisk*);
    virtual void VisitCard(Card*);
    virtual void VisitChassis(Chassis*);
    virtual void VisitBus(Bus*);
    //and so on for other concrete subclasses of Equipment
    protected:
    EquipmentVisitor();
};

void FloppyDisk::Accept(EquipmentVisitor& visitor)
{
    visitor.VisitFloppyDisk(this);
}
void Chassis::Accept(EquipmentVisitor& visitor)
{
    for(ListIterator<Equipment*> i(_parts);!i.IsDone();i.Next())
    {
        i.CurrentItem()->Accept(visitor);
    }
    visitor.VisitChassis(this);
}

class PricingVisitor:public EquipmentVisitor{
    public:
    PricingVisitor();
    Currency& GetTotalPrice();
    virtual void VisitFloppyDisk(FloppyDisk*);
    virtual void VisitCard(Card*);
    virtual void VisitChassis(Chassis*);
    virtual void VisitBus(Bus*);
    //...
    private:
    Currency _total;
};
void PricingVisitor::VisitFloppyDisk(FloppyDisk* e)
{
    _total+=e->NetPrice();
}
void PricingVisitor::VisitChassis(Chassis* e)
{
    _total+=e->DiscountPrice();
}
class InventoryVisitor:public Equipment{
    public:
    InventoryVisitor();
    Inventory& GetInventory();
    virtual void VisitFloppyDisk(FloppyDisk*);
    virtual void VisitCard(Card*);
    virtual void VisitChassis(Chassis*);
    virtual void VisitBus(Bus*);
    //...
    private:
    Inventory _inventory;
};
void InventoryVisitor::VisitFloppyDisk(FloppyDisk* e)
{
    _inventory.Accumulate(e);
}
void InventoryVisitor::VisitChassis(Chassis *e)
{
    _inventory.Accumulate(e);
}
//How to use?
Equipment* component;
InventoryVisitor visitor;
component->Accept(visitor);

Related patterns:
Composite:Visitors can be used to apply an operation over an object structure defined by the Composite pattern.
Interpreter:Visitor may be applied to do the interpretation.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
# 智慧旅游解决方案摘要 智慧旅游解决方案旨在通过新一代信息网络技术和装备,实现旅游服务、管理、营销和体验的智能化。该方案响应国家政策背景,如国家旅游局和工业信息化部的指导意见,以及国家发改委的发展规划,强调数字化、网络化、智能化在旅游业的应用,推动5G和移动互联网技术在旅游领域的创新应用。 方案的建设目标围绕“一个中心、四个方面、五大平台”展开,即以智慧旅游数据中心为核心,面向服务、管理、商务和营销构建智慧景区管理平台、智慧旅游服务平台、智慧旅游商务平台和智慧旅游营销平台。这五大平台将整合全域旅游资源,提升旅游设施,拓展旅游空间,融合旅游产业链,提升旅游服务,定制旅游产品,推进旅游改革。 建设内容涵盖了整体架构的构建,包括智慧服务、智慧管理、电子商务和智慧营销等方面。通过云计算、人工智能、大数据、物联网、5G等技术,实现“云-管-端”服务能力,打造集时间、空间、层次为一体的体验平台。此外,还包括智慧景区管理平台的多个子系统,如视频监控、应急指挥调度、流量监测、舆情监督、线路SOS一键呼救、GIS人车调度、停车场管理、语音广播、环境监测管理、多媒体发布、电子巡更以及指挥调度大屏建设等。 智慧旅游服务平台则包括自助票务系统、人脸识别、扫码购票、景区门户网站、机游、WIFI覆盖系统、数字全景VR、AI机器人、智慧座椅、智慧厕所等,旨在提升游客体验,实现景区的智能化管理和服务。通过这些服务,游客可以享受到便捷的购票、入园、导览和信息服务,同时景区管理者能够更有效地监控和管理景区运营。 智慧旅游商务平台则侧重于旅行社团队申报、电子商城、综合票务系统、分销管理系统、大会员系统和景区聚合支付系统,为旅游企业提供全面的商务服务和营销支持。这些平台和系统帮助旅游企业拓宽分销渠道,实现财务管理和订单管理,同时为游客提供便捷的支付和会员服务。 最后,智慧营销平台通过综合票务系统、分销管理系统、大会员系统和景区聚合支付系统,为旅游行业提供精准的营销工具和策略。这些工具和策略有助于整合旅游资源,拓宽销售渠道,提升游客体验,实现旅游业务的数字化和智能化。 智慧旅游解决方案通过这些综合性的技术和平台,不仅提升了游客的旅游体验,还为旅游行业的可持续发展提供了强有力的技术支持和数据驱动的决策依据。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值