用Factory设计模式解决一个网友的问题

定义一个如下所示的CNumber类,并以其为基类派生出素数类CPrimeNumber,完全平方数类CCompleteSquareNumber和回文数类CPalindromeNumber

class CNumber

{

protected:

    char *p_type;  // points to the text stating type of the number

public:

    CNumber(char *p_number_type);

    void print() { }

    void printYes() { cout < < "It is a " < < p_type < < endl; }

    void printNo() { cout < < "It is not a " < < p_type < < endl; }

    virtual ~CNumber() { delete [] p_type; }

};

 

class CPrimeNumber : public CNumber

{

protected:

    long n;

public:

    CPrimeNumber(long n_val);

    void print();

    ~CPrimeNumber() { }

};

 

class CCompleteSquareNumber : public CNumber

{

protected:

    long n;

public:

    CCompleteSquareNumber(long n_val);

    void print();

    ~CCompleteSquareNumber() { }

};

 

class CPalindromeNumber : public CNumber

{

protected:

    long n;

public:

    CPalindromeNumber(long n_val)

    void print();

    ~CPalindromeNumber() { }

};

 

void CPalindromeNumber::print()

{

         long n1, sum=0;

         int  t;

         n1 = n*n;

    while (n1 != 0)

    { 

                   t = n1%10;

        sum = sum*10 + t;

        n1 = n1/10;

    }

    if (sum == n*n)

      printYes();

    else

      printNo();

}

为了能实现如下例图所示的输出结果,应该怎样编写各个类其余各成员函数,并完成主函数的实现。

Enter a number <0 to exit>:13

Enter the type of number you want to check:

1.Prime number

2.Complete aquare number

3.Palindrome number

1

It is a Prime number

Enter a number <0 to exit>:16

Enter the type of number you want to check:

1.Prime number

2.Complete aquare number

3.Palindrome number

2

It is a Complete aquare number

Enter a number <0 to exit>:11

Enter the type of number you want to check:

1.Prime number

2.Complete aquare number

3.Palindrome number

3

It is a Palindrome number

Enter a number <0 to exit>:0

Press any key to continue

= = = = = = = =  = = = = = = = = = = = = = = = = = = = = =

上文为网友的提问,其中“aquare”疑为“Square”之笔误。

 

这位朋友给出的部分实现代码,很是值得商榷,比如在类Cnumber

1.      char *p_type;根本没有必要;

2.   下面3个函数如果都需要的话,将其设为虚函数更为恰当。

void print() { }

    void printYes() { cout < < "It is a " < < p_type < < endl; }

    void printNo() { cout < < "It is not a " < < p_type < < endl; }

     还有,根据一般的规则,如果在类的定义出实现相关函数,最好使用如下的方式:

         inline void printYes() { cout < < "It is a " < < p_type < < endl; }

等等。

 

这个问题的实现完全可以不用所谓的设计模式,在下面的代码中,纯粹是为了顺便说明Factory Method这个设计模式的用法而引入了Factory Method模式,在这里,使用设计模式会增加很多代码。但这并不是说,设计模式不重要,事实上,设计模式是非常重要的。

 

代码如下:

// 抽象基类CNnumber

#include <math.h>

#include <iostream>

using namespace std;

class CNumber

{

public:

    CNumber();

    virtual void print() = 0;    // 纯虚函数

    virtual ~CNumber();

};

 

// 基类CNnumber的实现

CNumber::CNumber()

{

}

 

CNumber::~CNumber()

{

}

 

 

// 派生类CPrimeNumber

class CPrimeNumber : public CNumber

{

private:

    long n;

public:

         CPrimeNumber();

    CPrimeNumber(long n);

    void print();

    virtual ~CPrimeNumber();

};

 

// 派生类CPrimeNumber的实现

CPrimeNumber::CPrimeNumber()

{

}

 

CPrimeNumber::CPrimeNumber(long n)

{

         this->n = n;

}

 

void CPrimeNumber::print()      // 重写基类的print,在此判断n是否为素数

{

         int i;

         int k;

         k = sqrt((double)n);

         for(i = 2; i <= k; i++)

         {

                   if(n%i == 0) break;

         }

         if(i > k)

         {

                   cout << n << " is a prime number" << endl;

         }

         else

         {

                   cout << n << " isn't a prime number" << endl;

         }

         return;

}

 

CPrimeNumber::~CPrimeNumber()

{

}

 

 

// 派生类CCompleteSquareNumber

class CCompleteSquareNumber : public CNumber

{

private:

    long n;

public:

         CCompleteSquareNumber();

    CCompleteSquareNumber(long n);

    void print();

    virtual ~CCompleteSquareNumber();

};

 

// 派生类CCompleteSquareNumber的实现

CCompleteSquareNumber::CCompleteSquareNumber()

{

}

CCompleteSquareNumber::CCompleteSquareNumber(long n)

{

         this->n = n;

}

 

void CCompleteSquareNumber::print()  // 重写基类的print,在此判断n是否为完全平方数

{

         int k = sqrt((double)n);

         if(n == k * k)

         {

                   cout << n << " is a complete square number." << endl;

         }

         else

         {

                   cout << n << " isn't a complete square number." << endl;

         }

         return;

}

 

CCompleteSquareNumber::~CCompleteSquareNumber()

{

}

 

 

// 派生类CPalindromeNumber

class CPalindromeNumber : public CNumber

{

protected:

    long n;

public:

         CPalindromeNumber();

    CPalindromeNumber(long n);

    void print();

    virtual ~CPalindromeNumber();

};

 

// 派生类CPalindromeNumber的实现

CPalindromeNumber::CPalindromeNumber()

{

}

 

CPalindromeNumber::CPalindromeNumber(long n) 

{

         this->n = n;

}

 

void CPalindromeNumber::print()     // 重写基类的print,在此判断n是否为回文数

{

         int k;

         int length;

         char str[11];

         itoa(n, str, 10);

         length = strlen(str);

         k = length / 2;

         for(int i = 0; i < k; i++)

         {

                   if(str[i] == str[length - i - 1])

                   {

                            continue;

                   }

                   else

                   {

                            cout << n << " isn't a palindrome number." << endl;

                            return;

                   }

         }

         cout << n << " is a palindrome number." << endl;

         return;

}

 

CPalindromeNumber::~CPalindromeNumber()

{

}

 

// 抽象工厂类NumberFactory

class CNumberFactory

{

public:

         CNumberFactory();

         virtual ~CNumberFactory();

         virtual CNumber* create(long number) = 0;    // 这就是所谓的Factory Metho,即工厂方法

};

 

CNumberFactory::CNumberFactory()

{

}

 

CNumberFactory::~CNumberFactory()

{

}

 

// 具体工厂类CPrimeNumberFactory

class CPrimeNumberFactory : public CNumberFactory

{

protected:

         CNumber* cnum;

public:

         inline CPrimeNumberFactory()

         {

                   cnum = NULL;

         }

 

         CNumber* create(long number);                                  // 这就是所谓的Factory Metho,即工厂方法

         virtual inline ~CPrimeNumberFactory()

         {

                   if(cnum != NULL)

                   {

                            delete cnum;

                            cnum = NULL;

                   }

         }

};

 

CNumber* CPrimeNumberFactory::create(long number)

{

         cnum = new CPrimeNumber(number);

         return cnum;

}

 

// 具体工厂类CPalindromeNumberFactory

class CCompleteSquareNumberFactory : public CNumberFactory

{

protected:

         CNumber* cnum;

public:

         inline CCompleteSquareNumberFactory()

         {

                   cnum = NULL;

         }

 

         CNumber* create(long number);                                  // 这就是所谓的Factory Metho,即工厂方法

         virtual inline ~CCompleteSquareNumberFactory()

         {

                   if(cnum != NULL)

                   {

                            delete cnum;

                            cnum = NULL;

                   }

         }

};

 

CNumber* CCompleteSquareNumberFactory::create(long number)

{

         cnum = new CCompleteSquareNumber(number);

         return cnum;

}

 

// 具体工厂类CPalindromeNumberFactory

class CPalindromeNumberFactory : public CNumberFactory

{

protected:

         CNumber* cnum;

public:

         inline CPalindromeNumberFactory()

         {

                   cnum = NULL;

         }

         CNumber* create(long number);                                  // 这就是所谓的Factory Metho,即工厂方法

         virtual inline ~CPalindromeNumberFactory()

         {

                   if(cnum != NULL)

                   {

                            delete cnum;

                            cnum = NULL;

                   }

         }

};

 

CNumber* CPalindromeNumberFactory::create(long number)

{

         cnum = new CPalindromeNumber(number);

         return cnum;

}

 

int main(void)

{

         int number = 0;

         int numbertype = 0;

         CNumber* cnum = NULL;

         CNumberFactory* cf = NULL;

 

         while(true)

    {

                   //system("cls");

                  cout << "Enter a number <0 to exit>:"; //<< endl;

                   cin >> number;

                   if(number == 0)

                   {

                            return 0;

                   }

 

                   cout << "Select the type of number you want to check:" << endl;

                   cout << "1.Prime number" << endl;

                   cout << "2.Complete square number" << endl;

                   cout << "3.Palindrome number" << endl;

                   cin >> numbertype;

 

                   if(numbertype < 1 || numbertype > 3)

                   {

                            cout << "Please select the right action." << endl;

                   }

                  

                   switch(numbertype)

                   {

                   case 1:

                            cf = new CPrimeNumberFactory();

                            break;

                   case 2:

                            cf = new CCompleteSquareNumberFactory();

                            break;

                   case 3:

                            cf = new CPalindromeNumberFactory();

                            break;

                   default:

                            //system("pause");

                            break;

                   }

                   cnum = cf->create(number);

                   cnum->print();

 

                   delete cf;

                   cf = NULL;

                   //system("pause");

         }

 

         return 0;

}

 

各类之间的关系见如下UML类图:

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值