基于策略的设计C++;问题 我一直在读Andrei Alexandrescu现代C++设计的书。我有一个关于将类分解为策略的问题

基于策略的设计C++;问题 我一直在读Andrei Alexandrescu现代C++设计的书。我有一个关于将类分解为策略的问题,c++,templates,design-patterns,C++,Templates,Design Patterns,基本上,好的政策规模是多少?大多数示例显示了构造、破坏、线程安全等部分。简单地说就是小政策:) 如果我想创建一个文件io类,它将文件类型作为策略,例如 struct XX_Type { void AsyncRead(callback c); void* Write(const uint8* image); } struct YY_Type { void AsyncRead(callback c); void* Write(const uint8*, imag

基本上,好的政策规模是多少?大多数示例显示了构造、破坏、线程安全等部分。简单地说就是小政策:)

如果我想创建一个文件io类,它将文件类型作为策略,例如

struct XX_Type
{
    void  AsyncRead(callback c);
    void* Write(const uint8* image);
}

struct YY_Type
{
    void  AsyncRead(callback c);
    void* Write(const uint8*, image, uint32 offset);
};

template<class FileType = XX_Type>
class File : public FileType
{
    virtual void OnDataRead(const uint8*, uint32 size) = 0;
    ...
};
struct XX_类型
{
void异步读取(回调c);
void*写入(const uint8*图像);
}
结构YY_类型
{
void异步读取(回调c);
void*写入(常量uint8*,图像,uint32偏移量);
};
模板
类文件:公共文件类型
{
虚拟空OnDataRead(常量uint8*,uint32大小)=0;
...
};
想法是从文件中继承并创建一个不同的模板,以后需要时可以生成这些模板。这是否适合策略,还是应该将文件句柄传递给全局静态函数,还是应该为每种类型的文件创建一个类?我希望确保用户错误率较低:),并且策略似乎不太容易出错

编辑:

感谢@Claudiordgz给了我一个非常不得体的回答

再举一个例子,就是采用网络方法


UPD和TCP非常相似,同时又非常不同。它们都需要一个套接字,但一个是无连接的,另一个是面向连接的。但从逻辑上讲,它们仍然是传输的一部分,如果我想创建更高级别的抽象,比如应用层协议,那么以@Claudiordgz为例,至少对我来说,使用传输层作为策略是有意义的,因为它在网络堆栈中的位置。

策略是一种聪明的切换机制。它们用于以下任何一项:

Waveform<W_128_Samples> w1;
  w1.setup(60, 1000);
 Waveform<W_1024_Samples> w2;
  w2.setup(60, 1000);
  • 一个工厂模式,带有一个在产品之间切换的模板工厂
  • 具有一个模板类的策略模式,该模板类在行为之间切换行为
  • 具有不同类型属性包的类。例如,您有一辆车,并且在策略中,您可以拥有该行为
其思想是从文件继承并创建不同的模板,这些模板可以在以后需要时生成。这是否适合策略,或者我应该将文件句柄传递给全局静态函数,还是应该为每种类型的文件创建一个类?我希望确保用户错误率较低:),并且策略似乎不太容易出错

你可以走你刚才说的任何一条路,这里是每一条路的优点/缺点:

  • 全局静态函数
    • 专业人士
      • 如果你计划做一个小程序,那么你担心什么?只要使用它们,发布并停止开发
    • 缺点
      • 您的实现可能需要来自其他地方的额外数据,这意味着事情可能会变得不成比例
      • 随着程序的发展,您可能希望在全局静态函数之间共享内容,因此您删除了静态,然后开始使用全局变量,然后使用混沌,这需要大约3年的时间。如果这适用于你的情况,要小心
      • 您希望在一个线程中运行一组函数,在另一个线程中运行另一组函数,因此您创建了一个函数类管理器,其中包含全局静态函数,重构所需的过程可能会非常繁琐
  • 为每种类型的文件初始化
    • 专业人士
      • 很多关于如何做的教程
    • 缺点
      • 随着程序的发展,需要跟踪的类越来越多
      • 改写了很多。。。。。。。样板
      • 这基本上与使用模板相同,如果您可以创建一个模板主类,那么一些执行问题将仅限于此,而不是扩展到其他文件
  • 政策(免责声明:我爱政策)
    • 专业人士
      • 一个主界面来管理它们
      • 在编译时创建代码,因此您将为使用的每个类创建一个类
      • 与许多样板类相比,易于维护
    • 缺点
      • 正如Alexandrescu所说,一些模板编码可能会使编译优化变得无用
      • 它更难设计,更难理解,更难实现
      • 更简单的方法可能会吸引您,您可能会退出实现,重新运行全局静态函数,像个小女孩一样哭泣
根据您的算法,run方法可能会扩展到数千行代码

“大多数示例都显示了构建、销毁、线程安全等部分。简单地说就是小策略”,这是因为它们都是小示例,策略只能扩展到您的想象中,记住您是程序员,您将代码提升到了前所未有的高度。如果你不这么做,没有人会这么做

记住佛罗多。。。 这项任务是指派给你的,如果你找不到方法,没有人会这样做。

###至少对我来说,使用传输层作为策略是有意义的,因为它在网络堆栈中的位置###

例如,假设您有一个名为connection的类。然后有一个类TCP_conn和一个类UDP_conn,分别定义数据包、头和方法,例如:

Template<class Protocol>
class Connection : public Protocol
{
   // your inherited methods would be here
   // just define connect or something
}
  • 方法发送
  • 方法接收(对于TCP)
  • 方法设置
然后像您的示例一样继承:

Template<class Protocol>
class Connection : public Protocol
{
   // your inherited methods would be here
   // just define connect or something
}
模板
类连接:公共协议
{
//您继承的方法将在这里
//定义一下连接之类的
}
例如。。。 假设您有一个生成波形的波形类

template <class SamplingPolicy >
class Waveform
{
public:
  typedef typename SamplingPolicy::iterator iterator;
  typedef typename SamplingPolicy::const_iterator const_iterator;
  typedef typename SamplingPolicy::inner_iterator inner_iterator;
  typedef typename SamplingPolicy::const_inner_iterator const_inner_iterator;
  typedef typename SamplingPolicy::size_type size_type;
  typedef typename SamplingPolicy::component component;
  typedef typename SamplingPolicy::Wave Wave;

  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;

  inner_iterator begin(iterator Itr);
  const_inner_iterator begin(iterator Itr) const;
  inner_iterator end(iterator Itr);
  const_inner_iterator end(iterator Itr) const;

  std::size_t Rows() const;
  std::size_t Columns() const;
  const typename SamplingPolicy::Wave& get() const;
  typename SamplingPolicy::Wave& get();

  typename SamplingPolicy::component& row(size_type const &n);
  const typename SamplingPolicy::component& row(size_type const &n) const;

  Waveform();
  ~Waveform();

  template <class Tx, class Ty>
  void setup(Tx const &frequency, Ty const &amplitude);

  template <class T>
  double Omega(T const &frequency);

  Waveform& operator=(Waveform const &rhWave);
  Waveform& operator+=(Waveform const &rhWave);
  Waveform& operator*=(Waveform const &rhWave);
  Waveform& operator-=(Waveform const &rhWave);
  Waveform& operator/=(Waveform const &rhWave);
  template<class T>
  Waveform& operator=(T const &number);
  template<class T>
  Waveform& operator+=(T const &number);
  template<class T>
  Waveform& operator*=(T const &number);
  template<class T>
  Waveform& operator-=(T const &number);
  template<class T>
  Waveform& operator/=(T const &number);

  Waveform operator+(Waveform const &rhWave) const;
  Waveform operator-(Waveform const &rhWave) const;
  template<class T>
  Waveform operator+(T const &number) const;
  template<class T>
  Waveform operator-(T const &number) const;
  Waveform operator/(Waveform const &rhWave) const;
  template<class T>
  Waveform operator/(T const &number) const;
  Waveform operator*(Waveform const &rhWave) const;
  template<class T>
  Waveform operator*(T const &number) const;

  void PrintToConsole(std::size_t columns);
  void PrintToFile(std::string const &filename,
    std::size_t columns);
protected:
  SamplingPolicy _samples;
  double _frequency;
  double _amplitude;
  std::string _frequencyString;
  std::string _amplitudeString;
  std::map<int,double> _SampleTimes;

private:
  bool ValidateSizes(Waveform const &rhWaveform) const;
  void print(std::size_t const &columns,
    std::ostream &output);
};
模板
类波形
{
公众:
typedef typename采样策略::迭代器迭代器;
typedef typename采样策略::常量迭代器常量迭代器;
typedef typename采样策略::内部迭代器内部迭代器;
typedef typename采样策略::常量内部迭代器常量内部迭代器;
typedef typename采样策略::大小\类型大小
Waveform<W_128_Samples> w1;
  w1.setup(60, 1000);
 Waveform<W_1024_Samples> w2;
  w2.setup(60, 1000);