zoukankan      html  css  js  c++  java
  • 一道题采用两种设计模式:对比策略模式和模版方法

      摘要

      《C++ Primer》习题14.38和14.39分别采用策略模式、模版方法解决问题。

      问题

      《C++ Primer 5th》习题 14.38 : 编写一个类令其检查某个给定的 string 对象的长度是否与一个阀值相等。使用该对象编写程序,统计并报告输入的文件中长度为 1 的单词有多少个、长度为 2 的单词有多少个、......、长度为 10 的单词有多少个。

      《C++ Primer 5th》习题 14.39 : 修改上一题的程序令其报告长度在 1 至 9 之间的单词有多少个、长度在 10 以上的单词又有多少个。

      解法一 模版方法 Template Method

      UML 类图如下:

      Solution 代码如下:

    template <typename T>
    struct Solution {
        Solution(int n) :val(n) {}
        virtual ~Solution() {}
        virtual void operator() (const T& e) = 0;
        unsigned int val;
        int times = 0;
    };

      EqualSolution 代码如下:

    template <typename T>
    struct EqualSolution : public Solution<T>{
        Solution::Solution;
        virtual void operator() (const T& e) override {
            if (e.size() == this->val)
                this->times++;
        }
    };

      GreaterSolution 代码如下:

    template <typename T>
    struct GreaterSolution : public Solution<T> {
        Solution::Solution;
        virtual void operator() (const T& e) override {
            if (e.size() > this->val)
                this->times++;
        }
    };

      LesserSolution 代码如下:

    template <typename T>
    struct LesserSolution : public Solution<T> {
        Solution::Solution;
        virtual void operator() (const T& e) override {
            if (e.size() < this->val)
                this->times++;
        }
    };

      客户端调用代码如下:

    int main()
    {
        vector<string> v{ "a", "b", "abc", "abcd", "abcde", "abcdef" };
    
        Solution<string>* es = new EqualSolution<string>(1);
        Solution<string>* ls = new LesserSolution<string>(5);
        Solution<string>* gs = new GreaterSolution<string>(5);
    
        for (auto &e : v) {
            es->operator()(e);
            ls->operator()(e);
            gs->operator()(e);
        }
    
        cout << "长度等于 1 的有几个: " << es->times << endl;
        cout << "长度小于 5 的有几个: " << ls->times << endl;
        cout << "长度大于 5 的有几个: " << gs->times << endl;
    
        return 0;
    }

      解法二 策略方法 + 工厂方法

      UML类图如下:

      

      CompareStrategy 代码如下:

    struct CompareStrategy {
        virtual void operator() (const string& s, const unsigned int val, unsigned int& times) = 0;
        virtual ~CompareStrategy() {};
    };

      EqualStrategy 代码如下:

    struct EqualStrategy : public CompareStrategy {
        virtual void operator() (const string& s, const unsigned int val, unsigned int& times) {
            if (s.size() == val)
                times++;
        }
    };

      GreaterStrategy 代码如下:

    struct GreaterStrategy : public CompareStrategy {
        virtual void operator() (const string& s, const unsigned int val, unsigned int& times) {
            if (s.size() > val)
                times++;
        }
    };

      LesserStrategy 代码如下:

    struct LesserStrategy : public CompareStrategy {
        virtual void operator() (const string& s, const unsigned int val, unsigned int& times) {
            if (s.size() < val)
                times++;
        }
    };

      Context 代码如下:

    struct Context {
        CompareStrategy *strategy;
        unsigned int times = 0;
        unsigned int val = 0;
        void operator() (const string& s) {
            strategy->operator() (s, val, times);
        }
        Context(char type, int v) : val(v) {  
            switch (type)    // 简单工厂模式
            {
            case 'e': // equal
                strategy = new EqualStrategy();
                break;
            case 'g': // greater
                strategy = new GreaterStrategy();
                break;
            case 'l': // lesser
                strategy = new LesserStrategy();
                break;
            default:
                cout << "不存在该方法" << endl;
                exit(-1);
                break;
            }
        }
    };

      客户端调用代码如下:

    int main() {
        vector<string> v{ "1", "12", "123", "1234" };
    
        Context c1('e', 3);
        Context c2('g', 3);
        Context c3('l', 3);
    
        for (auto &e : v) {
            c1(e);
            c2(e);
            c3(e);
        }
    
        cout << c1.times << endl;
        cout << c2.times << endl;
        cout << c3.times << endl;
        return 0;
    }

       总结

      两种模式下,耦合度都不高,但是采用策略模式更合乎人类的思维。

      所以这道题,策略模式更适用。

  • 相关阅读:
    Hive和HBase的区别
    HBase面试问题
    HBase的rowkey的设计原则
    一、spark 数据类型(Data Types)
    Phaser显示对象(文字)
    Phaser中的组对象group
    Phaser中的动画
    phaser.js 显示对象笔记
    MD5之C#密码加密备忘录
    学了点小小的技巧,也有一点点问题,怎么解决呢?
  • 原文地址:https://www.cnblogs.com/fengyubo/p/4878824.html
Copyright © 2011-2022 走看看