`
oraclestudy
  • 浏览: 480310 次
文章分类
社区版块
存档分类

用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类图:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics