- 浏览: 369990 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (335)
- C++ (190)
- 设计模式 (43)
- 数据库技术 (5)
- 网络编程 (11)
- 自动化测试 (6)
- Linux (13)
- OpenSSL (10)
- MS Crypt API (5)
- SCM (2)
- English (4)
- Android (10)
- EMV规范 (1)
- Saturn Platform (0)
- C (10)
- SQL (2)
- ASP.NET (3)
- 英语口语学习 (3)
- 调试工具 (21)
- 编译技术 (5)
- UML (1)
- 项目管理 (5)
- 敏捷开发 (2)
- Http Server (6)
- 代码审查、代码分析 (5)
- 面试基础 (10)
- 重点知识 (16)
- STL (6)
- Efficient C++资料 (8)
- 数据结构和算法 (7)
- 读书笔记 (0)
- 开源项目 (4)
- 多线程 (2)
- Console App (6)
- 个人开源项目 (4)
- IBM DevelopWorks (4)
- Java (16)
- 内存泄漏相关调试和检测 (13)
- 软件测试相关技术 (2)
- C# (11)
- Apple Related (1)
- 软件测试和管理 (2)
- EMV (1)
- Python (1)
- Node.js (6)
- JavaScript (5)
- VUE (1)
- Frontend (1)
- Backend (4)
- RESTful API (3)
- Firebase (3)
最新评论
-
u013189503:
来个密码吧
[C++][Logging] 项目中写日志模块的实现 -
wyf_vc:
来个密码啊!!
[C++][Logging] 项目中写日志模块的实现
简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
一般多个产品只有一个工厂类实现控制。
//SimapleFactoryPattern.h #ifndef SIMPLE_FACTORY_PATTERN_H #define SIMPLE_FACTORY_PATTERN_H #include <Windows.h> namespace SimpleFactoryPattern { // Base Class ////////////////////////////////////////////////////////////////////////// class Operation { public: Operation(); virtual ~Operation(); virtual double GetResoult() = 0; public: double m_fNumberA; double m_fNumberB; }; ////////////////////////////////////////////////////////////////////////// class OperationAdd : public Operation { public: OperationAdd(); virtual ~OperationAdd(); virtual double GetResoult(); }; ////////////////////////////////////////////////////////////////////////// class OperationSub : public Operation { public: OperationSub(); virtual ~OperationSub(); virtual double GetResoult(); }; ////////////////////////////////////////////////////////////////////////// class OperationMul : public Operation { public: OperationMul(); virtual ~OperationMul(); virtual double GetResoult(); }; ////////////////////////////////////////////////////////////////////////// class OperationDiv : public Operation { public: OperationDiv(); virtual ~OperationDiv(); virtual double GetResoult(); }; ////////////////////////////////////////////////////////////////////////// class OperationFactory { public: OperationFactory(); ~OperationFactory(); static Operation* CreateOperate(char chType) { Operation* pTempOp = NULL; switch(chType) { case '+': pTempOp = new OperationAdd(); break; case '-': pTempOp = new OperationSub(); break; case '*': pTempOp = new OperationMul(); break; case '/': pTempOp = new OperationDiv(); break; default: break; } return pTempOp; } }; ////////////////////////////////////////////////////////////////////////// void SimpleFactoryPattern_Test(); } #endif
#include "SimpleFactoryPattern.h" #include <iostream> using namespace std; namespace SimpleFactoryPattern { ////////////////////////////////////////////////////////////////////////// Operation::Operation() { } Operation::~Operation() { } ////////////////////////////////////////////////////////////////////////// OperationAdd::OperationAdd() { } OperationAdd::~OperationAdd() { } double OperationAdd::GetResoult() { return m_fNumberA+m_fNumberB; } ////////////////////////////////////////////////////////////////////////// OperationSub::OperationSub() { } OperationSub::~OperationSub() { } double OperationSub::GetResoult() { return m_fNumberA-m_fNumberB; } ////////////////////////////////////////////////////////////////////////// OperationMul::OperationMul() { } OperationMul::~OperationMul() { } double OperationMul::GetResoult() { return m_fNumberA*m_fNumberB; } ////////////////////////////////////////////////////////////////////////// OperationDiv::OperationDiv() { } OperationDiv::~OperationDiv() { } double OperationDiv::GetResoult() { return m_fNumberA/m_fNumberB; } ////////////////////////////////////////////////////////////////////////// OperationFactory::OperationFactory() { } OperationFactory::~OperationFactory() { } ////////////////////////////////////////////////////////////////////////// void SimpleFactoryPattern_Test() { Operation* pCurOP = NULL; pCurOP = OperationFactory::CreateOperate('+'); pCurOP->m_fNumberA = 1; pCurOP->m_fNumberB = 2; double fResoult = pCurOP->GetResoult(); cout << fResoult; delete pCurOP; pCurOP = NULL; } }
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,悬着判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来是改工厂类,而现在是修改客户端!
一般来说,每一个产品都对应一个工厂类。
//FactoryMethodPattern.h #ifndef FACTORY_METHOD_PATTERN_H #define FACTORY_METHOD_PATTERN_H #include <Windows.h> namespace FactoryMethodPattern { // Base Class ////////////////////////////////////////////////////////////////////////// class Operation { public: Operation(); virtual ~Operation(); virtual double GetResoult() = 0; public: double m_fNumberA; double m_fNumberB; }; // ////////////////////////////////////////////////////////////////////////// // class OperationAdd : public Operation // { // public: // OperationAdd(); // virtual ~OperationAdd(); // // virtual double GetResoult(); // }; // // ////////////////////////////////////////////////////////////////////////// // class OperationSub : public Operation // { // public: // OperationSub(); // virtual ~OperationSub(); // // virtual double GetResoult(); // }; // // ////////////////////////////////////////////////////////////////////////// // class OperationMul : public Operation // { // public: // OperationMul(); // virtual ~OperationMul(); // // virtual double GetResoult(); // }; // // ////////////////////////////////////////////////////////////////////////// // class OperationDiv : public Operation // { // public: // OperationDiv(); // virtual ~OperationDiv(); // // virtual double GetResoult(); // }; ////////////////////////////////////////////////////////////////////////// class IFactory { public: IFactory(); ~IFactory(); virtual Operation* CreateOperate() = 0; }; // class AddFactory : public IFactory // { // public: // AddFactory(); // virtual ~AddFactory(); // // virtual Operation* CreateOperate(); // }; // class SubFactory: public IFactory // { // public: // SubFactory(); // virtual ~SubFactory(); // // virtual Operation* CreateOperate() ; // }; // class MulFactory : public IFactory // { // public: // MulFactory(); // virtual ~MulFactory(); // // virtual Operation* CreateOperate() ; // }; // class DivFactory : public IFactory // { // public: // DivFactory(); // virtual ~DivFactory(); // // virtual Operation* CreateOperate() ; // }; ////////////////////////////////////////////////////////////////////////// void FactoryMethodPattern_Test(); } #endif
#include "FactoryMethodPattern.h" #include <iostream> using namespace std; namespace FactoryMethodPattern { ////////////////////////////////////////////////////////////////////////// class OperationAdd : public Operation { public: OperationAdd(); virtual ~OperationAdd(); virtual double GetResoult(); }; ////////////////////////////////////////////////////////////////////////// class OperationSub : public Operation { public: OperationSub(); virtual ~OperationSub(); virtual double GetResoult(); }; ////////////////////////////////////////////////////////////////////////// class OperationMul : public Operation { public: OperationMul(); virtual ~OperationMul(); virtual double GetResoult(); }; ////////////////////////////////////////////////////////////////////////// class OperationDiv : public Operation { public: OperationDiv(); virtual ~OperationDiv(); virtual double GetResoult(); }; class AddFactory : public IFactory { public: AddFactory(); virtual ~AddFactory(); virtual Operation* CreateOperate(); }; class SubFactory: public IFactory { public: SubFactory(); virtual ~SubFactory(); virtual Operation* CreateOperate() ; }; class MulFactory : public IFactory { public: MulFactory(); virtual ~MulFactory(); virtual Operation* CreateOperate() ; }; class DivFactory : public IFactory { public: DivFactory(); virtual ~DivFactory(); virtual Operation* CreateOperate() ; }; ////////////////////////////////////////////////////////////////////////// Operation::Operation() { } Operation::~Operation() { } ////////////////////////////////////////////////////////////////////////// OperationAdd::OperationAdd() { } OperationAdd::~OperationAdd() { } double OperationAdd::GetResoult() { return m_fNumberA+m_fNumberB; } ////////////////////////////////////////////////////////////////////////// OperationSub::OperationSub() { } OperationSub::~OperationSub() { } double OperationSub::GetResoult() { return m_fNumberA-m_fNumberB; } ////////////////////////////////////////////////////////////////////////// OperationMul::OperationMul() { } OperationMul::~OperationMul() { } double OperationMul::GetResoult() { return m_fNumberA*m_fNumberB; } ////////////////////////////////////////////////////////////////////////// OperationDiv::OperationDiv() { } OperationDiv::~OperationDiv() { } double OperationDiv::GetResoult() { return m_fNumberA/m_fNumberB; } ////////////////////////////////////////////////////////////////////////// IFactory::IFactory() { } IFactory::~IFactory() { } ////////////////////////////////////////////////////////////////////////// AddFactory::AddFactory() { } AddFactory::~AddFactory() { } Operation* AddFactory::CreateOperate() { return new OperationAdd(); } ////////////////////////////////////////////////////////////////////////// SubFactory::SubFactory() { } SubFactory::~SubFactory() { } Operation* SubFactory::CreateOperate() { return new OperationSub(); } ////////////////////////////////////////////////////////////////////////// MulFactory::MulFactory() { } MulFactory::~MulFactory() { } Operation* MulFactory::CreateOperate() { return new OperationMul(); } ////////////////////////////////////////////////////////////////////////// DivFactory::DivFactory() { } DivFactory::~DivFactory() { } Operation* DivFactory::CreateOperate() { return new OperationDiv(); } ////////////////////////////////////////////////////////////////////////// void FactoryMethodPattern_Test() { IFactory* pCurFactory = new AddFactory(); Operation* pCurOp = pCurFactory->CreateOperate(); pCurOp->m_fNumberA = 1; pCurOp->m_fNumberB = 2; double fResoult = pCurOp->GetResoult(); cout << fResoult; delete pCurOp; pCurOp = NULL; delete pCurFactory; pCurFactory = NULL; } }
抽象工厂好处是易于交换产品系列,一个应用只需要在初始化的时候出现一次,这使得改变一个应用的具体共产变得非常方便,它只需要改变具体工厂即可使用不同的产品配置。
第二个好处是,它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体的工厂实现分离,不会出现在客户端代码中。
//AbstractFactoryPattern.h #ifndef ABSTRACY_FACTORY_PATTERN_H #define ABSTRACY_FACTORY_PATTERN_H #include <Windows.h> #include <string> using namespace std; namespace AbstractFactoryPattern { class User { public: User(); ~User(); public: int m_nID; string m_strName; }; ////////////////////////////////////////////////////////////////////////// class Department { public: Department(); ~Department(); public: int m_nID; string m_strName; }; ////////////////////////////////////////////////////////////////////////// class IUser { public: IUser(); virtual ~IUser(); virtual void Insert(User& cUser) = 0; virtual User* GetUser(int nUserID) = 0; }; //Hidden these abstract classes // class SqlServerUser : public IUser // { // public: // SqlServerUser(); // virtual ~SqlServerUser(); // // virtual void Insert(User& cUser); // virtual User* GetUser(int nUserID); // }; // // class AccessUser : public IUser // { // public: // AccessUser(); // virtual ~AccessUser(); // // virtual void Insert(User& cUser); // virtual User* GetUser(int nUserID); // }; ////////////////////////////////////////////////////////////////////////// class IDepartment { public: IDepartment(); virtual ~IDepartment(); virtual void Insert(Department& cDepartment) = 0; virtual Department* GetDepartment(int nDepartmentID) = 0; }; //Hidden these abstract classes // class SqlServerDepartment : public IDepartment // { // public: // SqlServerDepartment(); // virtual ~SqlServerDepartment(); // // virtual void Insert(Department& cDepartment); // virtual Department* GetDepartment(int nDepartmentID); // }; // // class AccessDepartment : public IDepartment // { // public: // AccessDepartment(); // virtual ~AccessDepartment(); // // virtual void Insert(Department& cDepartment); // virtual Department* GetDepartment(int nDepartmentID); // }; ////////////////////////////////////////////////////////////////////////// class IFactory { public: IFactory(); ~IFactory(); virtual IUser* CreateUser() = 0; virtual IDepartment* CreateDepartment() = 0; }; //Hidden these abstract classes // class SqlServerFactory : public IFactory // { // public: // SqlServerFactory(); // virtual ~SqlServerFactory(); // // virtual IUser* CreateUser(); // virtual IDepartment* CreateDepartment(); // }; // class AccessFactory: public IFactory // { // public: // AccessFactory(); // virtual ~AccessFactory(); // // virtual IUser* CreateUser(); // virtual IDepartment* CreateDepartment(); // }; ////////////////////////////////////////////////////////////////////////// void AbstractFactoryPattern_Test(); } #endif
#include "AbstractFactoryPattern.h" #include <iostream> using namespace std; namespace AbstractFactoryPattern { ////////////////////////////////////////////////////////////////////////// class SqlServerUser : public IUser { public: SqlServerUser(); virtual ~SqlServerUser(); virtual void Insert(User& cUser); virtual User* GetUser(int nUserID); }; class AccessUser : public IUser { public: AccessUser(); virtual ~AccessUser(); virtual void Insert(User& cUser); virtual User* GetUser(int nUserID); }; ////////////////////////////////////////////////////////////////////////// class SqlServerDepartment : public IDepartment { public: SqlServerDepartment(); virtual ~SqlServerDepartment(); virtual void Insert(Department& cDepartment); virtual Department* GetDepartment(int nDepartmentID); }; class AccessDepartment : public IDepartment { public: AccessDepartment(); virtual ~AccessDepartment(); virtual void Insert(Department& cDepartment); virtual Department* GetDepartment(int nDepartmentID); }; ////////////////////////////////////////////////////////////////////////// class SqlServerFactory : public IFactory { public: SqlServerFactory(); virtual ~SqlServerFactory(); virtual IUser* CreateUser(); virtual IDepartment* CreateDepartment(); }; class AccessFactory: public IFactory { public: AccessFactory(); virtual ~AccessFactory(); virtual IUser* CreateUser(); virtual IDepartment* CreateDepartment(); }; ////////////////////////////////////////////////////////////////////////// User::User() { } User::~User() { } ////////////////////////////////////////////////////////////////////////// Department::Department() { } Department::~Department() { } ////////////////////////////////////////////////////////////////////////// IUser::IUser() { } IUser::~IUser() { } SqlServerUser::SqlServerUser() { } SqlServerUser::~SqlServerUser() { } void SqlServerUser::Insert(User& cUser) { cout << "Insert a record into TABLT User via SqlServer\n"; } User* SqlServerUser::GetUser(int nUserID) { cout << "Fetch a record from TABLT User via SqlServer\n"; return NULL; } AccessUser::AccessUser() { } AccessUser::~AccessUser() { } void AccessUser::Insert(User& cUser) { cout << "Insert a record into TABLT User via AccessUser\n"; } User* AccessUser::GetUser(int nUserID) { cout << "Fetch a record from TABLT User via AccessUser\n"; return NULL; } ////////////////////////////////////////////////////////////////////////// IDepartment::IDepartment() { } IDepartment::~IDepartment() { } SqlServerDepartment::SqlServerDepartment() { } SqlServerDepartment::~SqlServerDepartment() { } void SqlServerDepartment::Insert(Department& cDepartment) { cout << "Insert a record into TABLT Department via SqlServer\n"; } Department* SqlServerDepartment::GetDepartment(int nDepartmentID) { cout << "Fetch a record from TABLT Department via SqlServer\n"; return NULL; } AccessDepartment::AccessDepartment() { } AccessDepartment::~AccessDepartment() { } void AccessDepartment::Insert(Department& cDepartment) { cout << "Insert a record into TABLT User via AccessUser\n"; } Department* AccessDepartment::GetDepartment(int nDepartmentID) { cout << "Fetch a record from TABLT User via AccessUser\n"; return NULL; } ////////////////////////////////////////////////////////////////////////// IFactory::IFactory() { } IFactory::~IFactory() { } ////////////////////////////////////////////////////////////////////////// SqlServerFactory::SqlServerFactory() { } SqlServerFactory::~SqlServerFactory() { } IUser* SqlServerFactory::CreateUser() { return new SqlServerUser(); } IDepartment* SqlServerFactory::CreateDepartment() { return new SqlServerDepartment(); } ////////////////////////////////////////////////////////////////////////// AccessFactory::AccessFactory() { } AccessFactory::~AccessFactory() { } IUser* AccessFactory::CreateUser() { return new AccessUser(); } IDepartment* AccessFactory::CreateDepartment() { return new AccessDepartment(); } ////////////////////////////////////////////////////////////////////////// void AbstractFactoryPattern_Test() { User cUser; Department cDepartment; IFactory* pFactory = new SqlServerFactory(); IUser* pUser = pFactory->CreateUser(); IDepartment* pDepartment = pFactory->CreateDepartment(); pUser->Insert(cUser); pUser->GetUser(1); pDepartment->Insert(cDepartment); pDepartment->GetDepartment(1); delete pDepartment; pDepartment = NULL; delete pUser; pUser = NULL; delete pFactory; pFactory = NULL; } }
区别
简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
- SimpleFactoryPattern.zip (1.1 KB)
- 下载次数: 0
- AbstractFactoryPattern.zip (1.7 KB)
- 下载次数: 0
- FactoryMethodPattern.zip (1.4 KB)
- 下载次数: 0
发表评论
-
FreeRTOS
2022-03-05 16:31 248Ref https://blog.csdn.net/weix ... -
串口通讯相关
2018-11-02 13:44 411https://bbs.csdn.net/wap/topics ... -
[转]C++验证IP是否可以PING通
2018-10-30 17:54 1326https://www.cnblogs.com/guoyz13 ... -
C++/MFC 換皮膚
2018-10-20 11:05 477https://blog.csdn.net/u01123991 ... -
WinCE 截屏 - C++ 代碼
2018-08-31 09:45 574// this function create a bmp ... -
Android NDK搭建環境
2017-11-27 13:25 580https://www.cnblogs.com/ut2016- ... -
8583协议相关
2017-10-17 13:38 5738583相关资料,整理中... -
Java高级应用之JNI
2017-06-19 09:00 600参考link http://www.cnblogs.com/l ... -
C++实现ping功能
2017-04-18 11:21 2155基础知识 ping的过程是向目的IP发送一个type=8的I ... -
OpenSSL 编译环境搭建
2017-03-27 15:01 9061 安裝VS2008到 c:\Program Files (x ... -
最优非对称加密填充(OAEP)
2017-03-25 14:53 1582OpenSSL命令---rsautl http://blog. ... -
[Platform Builder] 设置SVM OS build Env
2016-11-10 11:39 01 copy one OSDesign Project to ... -
[Windows] System Error Codes(GetLastError )0-----5999
2016-10-26 13:28 1881ERROR_SUCCESS 0 (0x0) T ... -
开源Windows驱动程序框架
2016-09-17 21:35 871转自 http://code.csdn.net/news/28 ... -
c/c++代码中执行cmd命令
2016-09-14 14:50 1908转自 http://blog.csdn.net/slixinx ... -
C#使用C++标准DLL实例(包含callback)
2016-09-11 19:44 1086C++编写标准Win32DLL如下 头文件 /***** ... -
C#调用C++的DLL搜集整理的所有数据类型转换方式
2016-09-09 16:07 969转自 http://www.cnblogs.com/zeroo ... -
WinCE CPU使用率计算 测试工具
2016-09-08 16:14 991转自 http://blog.csdn.net/jan ... -
switch在C++与C#中的一些差异
2016-09-08 15:19 810参考链接 http://blog.csdn.net/weiwe ... -
C++ 鼠标模拟程序
2016-09-04 12:09 1612转自 http://blog.csdn.net/weixinh ...
相关推荐
工厂模式分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。 1. **简单工厂模式** 简单工厂模式是最简单的工厂模式实现,它提供一个静态方法或者类来创建对象,这个类通常被称为“工厂”。用户只需要...
在软件设计模式中,工厂模式是一组非常基础且实用的设计模式,主要分为简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都是为了解决对象创建的问题,通过封装对象的创建过程,使得代码更加灵活,易于扩展和维护...
总结来说,简单工厂模式和工厂方法模式都是为了封装对象的创建过程,使代码更加灵活和易于维护。简单工厂模式适合于产品种类较少且不会频繁扩展的情况,而工厂方法模式更适合于产品种类多,需要根据不同条件创建不同...
本文将详细介绍两种常见的工厂模式——简单工厂模式和工厂方法模式,并通过具体的C#代码示例进行讲解。 #### 二、简单工厂模式 ##### 2.1 概念 简单工厂模式(Simple Factory Pattern)是一种常用的设计模式,它...
简单工厂模式和工厂方法模式是两种常见的设计模式,它们在软件工程中被广泛用于对象创建。这两种模式都属于创建型设计模式,它们的主要目的是抽象出对象的创建过程,使得代码更加灵活,易于扩展。 首先,我们来理解...
本文将深入探讨两种常见的工厂模式:简单工厂模式和工厂方法模式。 简单工厂模式,也称为静态工厂模式,是一种创建型设计模式,它提供了一个静态方法来创建对象,而无需暴露实例化逻辑。在简单工厂模式中,一个单一...
前言 在《设计模式》一书中...接下来会通过例子对比简单工厂模式和工厂方法模式。 工厂意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。 别名 虚构造器(V
本文将深入探讨三种工厂模式:简单工厂模式、工厂方法模式以及抽象工厂模式,并结合源码分析其应用场景和优缺点。 1. 简单工厂模式 简单工厂模式(Simple Factory Pattern)是一种静态工厂方法,它通过一个公共的...
简单工厂模式和工厂方法模式在实际开发中都有广泛的应用。例如,在工具类库中,可能会有一个工具类工厂,根据用户需求返回不同的工具类实例。在框架设计中,工厂模式可以用于创建各种组件,使得框架的使用者可以根据...
本篇文章将对三种主要的工厂模式:简单工厂、工厂方法和抽象工厂进行深入的对比和总结。 **简单工厂模式** 是最基础的工厂模式形式,它提供一个静态方法或类来创建对象。在这个模式中,工厂是负责创建对象的中心...
简单工厂模式和工厂方法模式之间的区别主要在于前者是直接通过一个工厂类来创建产品对象,工厂类中需要有判断逻辑来决定创建哪种产品。而工厂方法模式则是将创建逻辑分解到各个子类中,每个子类对应一种产品,这样做...
Spring框架,作为Java开发中的核心组件,广泛采用了工厂模式和其他设计模式。例如,Spring的IoC(Inversion of Control)容器就是一种高级形式的工厂,它可以管理对象的生命周期和依赖关系,进一步降低了客户端代码...
本文将深入探讨"反射"以及两种常见的工厂模式:"简单工厂模式"和"工厂方法模式",并结合提供的文件名称来解析这些概念。 首先,我们来看"反射"。在Java等面向对象语言中,反射是一种强大的工具,它允许程序在运行时...
**简单工厂模式**是软件设计模式中的一种,属于创建型模式。在Java编程中,它是一种用于创建对象的简便方法,将对象的实例化过程封装到一个单独的工厂类中,使得客户端代码无需直接调用具体类的构造函数,而是通过...
工厂模式分为三种主要类型:简单工厂模式、普通工厂模式(也称为工厂方法模式)和抽象工厂模式。 1. **简单工厂模式**: - 简单工厂模式中,有一个中心工厂类,它负责根据输入条件(通常是一个参数)来创建具体的...