2017年设计模式考试题(ZZU)
前言:发现网上做这些题基本使用的Java语言,由于我只会C/C++,所以就用C++来实现一下看看。发现C++由于没有Java中的client类,往往在main函数中使用时,总感觉那么别扭!先这样吧……
1、 设计一个程序来读取多种不同存储格式的图片,针对每一种图片格式都设计一个图片读取器(ImageReader),如GIF格式图片读取器(GifReader)用于读取GIF格式的图片,JPEG格式图片读取器(JpegReader)用于读取JPEG格式的图片,Tiff格式图片读取器(TiffReader)用于读取Tiff格式的图片。图片读取器对象通过图片读取器工厂(ImageReaderFactory)来创建,ImageReaderFactory是一个抽象类,用于定义创建图片读取器的工厂方法,其子类GifReaderFactory、JpegReaderFactory和TiffReaderFactory用于创建具体的图片读取器对象。请使用工厂方法模式实现该程序的设计,并使用UML画出该模式的类图。
解答:为了省事,类图我直接附上VS自动生成的图形!
C++实现代码 (在主函数使用时候总感觉有点别扭) :
/************************************************************************/
/* Author: Lcy
/* Mail: 164917669@qq.com
/* Bolg: http://blog.csdn.net/MissXy_
/* Describe: 设计模式考题:工厂模式的使用
/* Date: 2017-10-26
/************************************************************************/
#include <iostream>
using namespace std;
class ImageReader //图片读取器
{
public:
ImageReader(){}
virtual ~ImageReader(){}
public:
virtual void ReadPicture() = 0;
};
class GifReader : public ImageReader //GIF格式读取器
{
public:
GifReader(){}
virtual void ReadPicture()
{
cout<< "读取GIF格式图片……"<< endl;
}
};
class JpegReader : public ImageReader //JPEG格式读取器
{
public:
JpegReader(){}
virtual void ReadPicture()
{
cout<< "读取JPEG格式图片……"<< endl;
}
};
class TiffReader : public ImageReader //Tiff格式读取器
{
public:
TiffReader(){}
virtual void ReadPicture()
{
cout<< "读取Tiff格式图片……"<< endl;
}
};
class ImageReaderFactory //创建图片读取器
{
public:
ImageReaderFactory() {}
virtual ~ImageReaderFactory() {}
public:
virtual ImageReader* CreateImageReader() = 0;
};
class GifReaderFactory : public ImageReaderFactory //创建GifReaderFactory图形读取器对象
{
public:
GifReaderFactory() {}
virtual ImageReader* CreateImageReader()
{
return new GifReader();
}
};
class JpegReaderFactory : public ImageReaderFactory //创建JpegReaderFactory图形读取器对象
{
public:
JpegReaderFactory() {}
virtual ImageReader* CreateImageReader()
{
return new JpegReader();
}
};
class TiffReaderFactory : public ImageReaderFactory //创建TiffReaderFactory图形读取器对象
{
public:
TiffReaderFactory() {}
virtual ImageReader* CreateImageReader()
{
return new TiffReader();
}
};
int main()
{
ImageReaderFactory* imageReaderFactory = new GifReaderFactory();
ImageReader* imageReader = imageReaderFactory->CreateImageReader();
imageReader->ReadPicture();
imageReaderFactory = new JpegReaderFactory();
imageReader = imageReaderFactory->CreateImageReader();
imageReader->ReadPicture();
imageReaderFactory = new TiffReaderFactory();
imageReader = imageReaderFactory->CreateImageReader();
imageReader->ReadPicture();
delete imageReader;
imageReader = NULL;
delete imageReaderFactory;
imageReaderFactory = NULL;
return 0;
}
运行结果:
2、某在线股票软件需要提供如下功能:当股票购买者购买的某只股票价格变化幅度达到5%时,系统将自动发送通知(包括新价格)给购买该股票的股民。现使用观察者模式设计该系统,绘制类图并编成实现。
此题百度会有很多结果,类图都可以百度出来,下面附上自己VS生成的类图:
C++实现代码:
Observer.h : 抽象观察者类
#pragma once
#include <iostream>
class Observer
{
public:
virtual void Update() = 0;
};
ConcreteObserver.h : 具体观察者类
#pragma once
#include <string>
#include "Observer.h"
#include "Subject.h"
class ConcreteObserver : public Observer
{
public:
ConcreteObserver(std::string name, ConcreteSubject* pConcreteSubject) :
m_strName(name), pConcreteSubject(pConcreteSubject){}
//股价变更通知函数
void Update()
{
std::cout<< "通知:股民"<<m_strName<<"请注意,您所持股票价格发生了变化!新价格为:"<<
pConcreteSubject->getPrice()<< std::endl;
}
private:
std::string m_strName;
ConcreteSubject* pConcreteSubject;
};
Subject.h : 通知者类(由于代码较少,我直接将 抽象 和 具体类 放一起)
#pragma once
#include <list>
#include "Observer.h"
//定义一个抽象的通知者类
class Subject
{
public:
virtual void addObserver(Observer* ) = 0;
virtual void delObserver(Observer* ) = 0;
virtual void notifyObserver() = 0;
};
//具体的通知者类
class ConcreteSubject : public Subject
{
public:
ConcreteSubject(double price): m_iPrice(price) {}
virtual void addObserver(Observer* pObserver);
virtual void delObserver(Observer* pObserver);
virtual void notifyObserver();
void setPrice(double newPrice);
double getPrice();
private:
double m_iPrice;
std::list<Observer*> m_observerList;
};
Subject.cpp : 主要是具体通知类的实现
#include "Subject.h"
//增加观察者
void ConcreteSubject::addObserver(Observer* pObserver)
{
m_observerList.push_back(pObserver);
}
//删除观察者
void ConcreteSubject::delObserver(Observer* pObserver)
{
m_observerList.remove(pObserver);
}
//重写通知函数
void ConcreteSubject::notifyObserver()
{
std::list<Observer*>::iterator it;
for (it = m_observerList.begin(); it != m_observerList.end(); ++it)
(*it)->Update();
}
//设置股价
void ConcreteSubject::setPrice(double newPrice)
{
double changePrice = this->m_iPrice - newPrice;
this->m_iPrice = newPrice;
//如果股价变动超过%5,通知观察者
if (changePrice/this->m_iPrice > 0.05 || changePrice/this->m_iPrice < -0.05)
notifyObserver();
}
//得到股价
double ConcreteSubject::getPrice()
{
return m_iPrice;
}
main.cpp : 写了一些操作,相当于Java中的Client类
/************************************************************************/
/* Author: Lcy
/* Mail: 164917669@qq.com
/* Bolg: http://blog.csdn.net/MissXy_
/* Describe: 设计模式考题:观察者模式
/* Date: 2017-11-3
/************************************************************************/
#include <iostream>
#include <vector>
#include <string>
#include "Observer.h"
#include "Subject.h"
#include "ConcreteObserver.h"
int main()
{
// 创建具体通知者对象
ConcreteSubject* pSubject = new ConcreteSubject(1000.00);
// 创建观察者
Observer* co1 = new ConcreteObserver("钻石王老五", pSubject);
Observer* co2 = new ConcreteObserver("屌丝刘哈哈", pSubject);
pSubject->addObserver(co1);
pSubject->addObserver(co2);
// 改变股价
pSubject->setPrice(1888);
std::cout<< std::endl;
pSubject->setPrice(1900);
std::cout<< std::endl;
pSubject->setPrice(666);
//删除一个观察者,再测试
std::cout<< std::endl;
pSubject->delObserver(co1);
pSubject->setPrice(1666);
delete co1;
delete co2;
delete pSubject;
return 0;
}
运行结果:
结果分析:
初始设置股价为:1000,第一次更改为1888,超过5%,通知股民;
第二次改为1900,未超过5%,不做通知;
第三次改为666,低于5%,通知;
……
3、设计一个网上书店,该系统中所有的计算机类图书(ComputerBook)每本都有10%的折扣,所有的语言类图书(LanguageBook)每本都有2元的折扣,小说类图书(NovelBok)每100元有10元的折扣。现使用策略模式来设计该系统,绘制类图并编成实现。
VS生成的类图:
C++实现代码:主要使用两个类文件,不太规范,大家可以自行更改!
BookStrategy.h : 这个文件定义了一个抽象的BookStrategy类,包含了一个纯虚函数calcPrice;三个子类继承BookStrategy。
#pragma once
#include <iostream>
class BookStrategy
{
public:
BookStrategy(void) {}
virtual ~BookStrategy(void) {}
public:
virtual double calcPrice(double var) = 0;
};
class ComputerBook : public BookStrategy
{
public:
double calcPrice(double booksPrice)
{
std::cout<< "计算机类图书每本都有10%的折扣。"<< std::endl;
return booksPrice * 0.9;
}
};
class LanguageBook : public BookStrategy
{
public:
double calcPrice(double booksPrice)
{
std::cout<< "语言类图书每本都有2元的折扣。"<< std::endl;
return booksPrice - 2.0;
}
};
class NovelBook : public BookStrategy
{
public:
double calcPrice(double booksPrice)
{
std::cout<< "小说类图书每100元有10元的折扣。"<< std::endl;
return booksPrice - (booksPrice / 100 * 10);
}
};
BookPrice.h :
1、需要使用ConcreteStrategy提供的算法。
2、内部维护一个Strategy的实例。
3、负责动态设置运行时Strategy具体的实现算法。
4、负责跟Strategy之间的交互和数据传递。
#pragma once
#include <iostream>
#include "BookStrategy.h"
class BookPrice
{
public:
BookPrice(BookStrategy* strategy): m_strategy(strategy)
{}
~BookPrice(void) {}
double OriginalPrice(double booksPrice) //传入原价,返回折后价
{
return this->m_strategy->calcPrice(booksPrice);
}
private:
BookStrategy* m_strategy;
};
main.h :
/************************************************************************/
/* Author: Lcy
/* Mail: 164917669@qq.com
/* Bolg: http://blog.csdn.net/MissXy_
/* Describe: 设计模式考题:策略模式
/* Date: 2017-11-4
/************************************************************************/
#include <iostream>
#include "BookPrice.h"
#include "BookStrategy.h"
int main()
{
//三个策略
ComputerBook* computerBook = new ComputerBook();
LanguageBook* languageBook = new LanguageBook();
NovelBook* novelBook = new NovelBook();
double booksPrice, discountPrice, totalPrice = 0.0;
std::cout<< "***************************************"<< std::endl;
std::cout<< "请输入计算机类图书价格:"<< std::endl;
std::cin>> booksPrice;
BookPrice* bookPrice = new BookPrice(computerBook);
discountPrice = bookPrice->OriginalPrice(booksPrice);
std::cout<< "计算机类图书总价:"<< booksPrice<<". "<< "折后价:"<< discountPrice<< std::endl;
totalPrice += discountPrice;
std::cout<< "***************************************"<< std::endl<< std::endl;
std::cout<< "***************************************"<< std::endl;
std::cout<< "请输入语言类图书价格:"<< std::endl;
std::cin>> booksPrice;
bookPrice = new BookPrice(languageBook);
discountPrice = bookPrice->OriginalPrice(booksPrice);
std::cout<< "语言类图书总价:"<< booksPrice<<". "<< "折后价:"<< discountPrice<< std::endl;
totalPrice += discountPrice;
std::cout<< "***************************************"<< std::endl<< std::endl;
std::cout<< "***************************************"<< std::endl;
std::cout<< "请输入小说类图书价格:"<< std::endl;
std::cin>> booksPrice;
bookPrice = new BookPrice(novelBook);
discountPrice = bookPrice->OriginalPrice(booksPrice);
std::cout<< "小说类图书总价:"<< booksPrice<<". "<< "折后价:"<< discountPrice<< std::endl;
totalPrice += discountPrice;
std::cout<< "***************************************"<< std::endl<< std::endl;
std::cout<< "***************************************"<< std::endl;
std::cout<<"总价为:"<< totalPrice<< std::endl;
std::cout<< "***************************************"<< std::endl;
delete computerBook;
delete languageBook;
delete novelBook;
delete bookPrice;
return 0;
}
运行结果: