设计模式第二次作业
1.题目1
要求:如果需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Linux、UNIX等)上播放多种格式的视频文件,常见的视频格式包括MPEG、RMVB、AVI、WMV等。使用Bridge模式来设计。
解答
类图如下:
代码如下:
// 播放器抽象类,定义播放接口,同时组合VideoFile对象
public abstract class VideoPlayer {
protected VideoFile videoFile;
public void setVideoFile(VideoFile videoFile) {
this.videoFile = videoFile;
}
abstract void play();
}
// Windows环境下的播放器类,实现播放接口
public class WindowsPlayer extends VideoPlayer {
@Override
void play() {
videoFile.decode();
System.out.println("play stream in Windows way");
}
}
// Linux环境下的播放器类,实现播放接口
public class LinuxPlayer extends VideoPlayer {
@Override
void play() {
videoFile.decode();
System.out.println("play stream in Linux way");
}
}
// 文件抽象类,定义解码接口
public abstract class VideoFile {
abstract void decode();
}
// MPEG文件类,具体实现解码接口
public class MPEGFile extends VideoFile {
@Override
void decode() {
System.out.println("decode MPEG file to stream");
}
}
// RMVB文件类,具体实现解码接口
public class RMVBFile extends VideoFile {
@Override
void decode() {
System.out.println("decode RMVB file to stream");
}
}
用户调用如下:
public class Client {
public static void main(String[] args) {
VideoPlayer videoPlayer = new WindowsPlayer(); // 实例化具体平台的播放器
VideoFile videoFile = new MPEGFile(); // 实例化文件类型
videoPlayer.setVideoFile(videoFile); // 告知播放器文件类型
videoPlayer.play(); // 播放
}
}
// 结果
// decode MPEG file to stream
// play stream in Windows way
2.题目2
要求:杀毒软件(AntiVirus)既能对系统中不同类型的文件 TextFile、ImageFile、VideoFile杀毒,也能对文件夹的杀毒,对文件夹杀毒就是对其中所包含文件的杀毒。使用Composite模式来设计。
解答
类图如下:
代码如下:
// 文件抽象类,定义“扫描”和“判断是否为文件夹”两个接口
public abstract class File {
abstract void scan();
boolean isDir() {
return false;
}
}
// 文本文件类,实现“扫描”接口
public class TextFile extends File {
@Override
void scan() {
System.out.println("scan text file");
}
}
// 图像文件类,实现“扫描”接口
public class ImageFile extends File {
@Override
void scan() {
System.out.println("scan image file");
}
}
// 视频文件类,实现“扫描”接口
public class VideoFile extends File {
@Override
void scan() {
System.out.println("scan video file");
}
}
// 文件夹类,实现“扫描”接口,重写“判断是否为文件夹”方法,添加“添加文件”
// 和“删除文件”两个独有的方法
public class Directory extends File {
private List<File> fileList = new ArrayList<>(); // 文件列表
@Override
void scan() {
System.out.println("scan directory");
for (File file : fileList) {
file.scan();
}
}
@Override
boolean isDir() {
return true;
}
void addFile(File file) {
fileList.add(file);
}
void delFile(File file) {
fileList.remove(file);
}
}
用户调用如下:
public class AntiVirus {
public static void main(String[] args) {
File file1 = new TextFile();
file1.scan(); // 扫描文件 file1
File file2 = new ImageFile();
File file3 = new VideoFile();
Directory dir1 = new Directory();
dir1.addFile(file2);
dir1.addFile(file3);
dir1.scan(); // 扫描文件夹dir1(包含file2和file3)
File file4 = new TextFile();
Directory dir2 = new Directory();
dir2.addFile(dir1);
dir2.addFile(file4);
dir2.scan(); // 扫描文件夹dir2(包含file4和dir1)
}
}
// 结果
// scan text file
//
// scan directory
// scan image file
// scan video file
//
// scan directory
// scan directory
// scan image file
// scan video file
// scan text file
3.题目3
要求:某系统提供一个数据加密功能,可以对字符串进行加密。最简单的加密算法通过对字母进行移位来实现,同时还提供稍复杂的逆向输出加密,还提供更为高级的求模加密。用户首先使用最简单的加密算法对字符串进行加密,如果觉得还不够可以对加密后的结果使用其他的加密算法进行二次加密,当然也可以进行第三次加密。使用Decrator模式来设计。
解答
类图如下:
代码如下:
// 加密抽象类,定义三种加密接口
public abstract class Encryption {
abstract void shiftEncryption();
abstract void revEncrypt();
abstract void modEncrypt();
}
// 加密具体类,实现三种加密方法
public class SingleEncryption extends Encryption {
@Override
void shiftEncryption() {
System.out.println("use shift encrypt");
}
@Override
void revEncrypt() {
System.out.println("use reverse encrypt");
}
@Override
void modEncrypt() {
System.out.println("use mod encrypt");
}
}
// 加密装饰者抽象类,保留一个加密具体类的引用,并提供一个加密的新接口
public abstract class EncryptionDecrator extends Encryption {
protected Encryption encryption;
public EncryptionDecrator(Encryption encryption) {
this.encryption = encryption;
}
@Override
void shiftEncryption() {
encryption.shiftEncryption();
}
@Override
void revEncrypt() {
encryption.revEncrypt();
}
@Override
void modEncrypt() {
encryption.modEncrypt();
}
abstract void newEncrypt();
}
// 加密装饰者具体类,实现接口“newEncrypt”进行二次加密
public class DoubleEncryptionDecrator extends EncryptionDecrator {
public DoubleEncryptionDecrator(Encryption encryption) {
super(encryption);
}
@Override
void newEncrypt() {
System.out.println("use double encrypt");
encryption.shiftEncryption();
encryption.revEncrypt();
}
}
// 加密装饰者具体类,实现接口“newEncrypt”进行三次加密
public class TrebleEncryptionDecrator extends EncryptionDecrator {
public TrebleEncryptionDecrator(Encryption encryption) {
super(encryption);
}
@Override
void newEncrypt() {
System.out.println("use treble encrypt");
encryption.shiftEncryption();
encryption.revEncrypt();
encryption.modEncrypt();
}
}
用户调用如下:
public class Client {
public static void main(String[] args) {
Encryption encryption = new SingleEncryption(); // 指定Component具体类
EncryptionDecrator decrator = new DoubleEncryptionDecrator(encryption); // 指定具体的装饰者类,并添加Component的引用
decrator.shiftEncryption(); // 调用简单的加密
decrator.newEncrypt(); // 调用新的加密接口,即二次加密
}
}
// 结果
// use shift encrypt
//
// use double encrypt
// use shift encrypt
// use reverse encrypt
4.题目4
要求:某系统需要提供一个文件加密模块,加密流程包括:读源文件、加密、保存加密文件。读取文件和保存文件使用流来实现,三个业务相对独立,封装在不同的类中;现在需要提供一个统一的加密外观类,用户可以直接使用该加密外观类完成文件的读取、加密和保存三个操作。使用Facade模式来设计。
类图如下:
代码如下:
// 流处理类,封装“从流中读出”和“写入流”两个方法
public class Stream {
public void read() {
System.out.println("read from stream");
}
public void write() {
System.out.println("write to stream");
}
}
// 文件读取器类,封装了读取文件的方法,创建了一个流对象
public class FileReader {
private Stream stream = new Stream();
public void read() {
stream.read();
System.out.println("read file");
}
}
// 文件保存器类,封装了保存文件的方法,创建了一个流对象
public class FileSaver {
private Stream stream = new Stream();
public void save() {
stream.write();
System.out.println("save file");
}
}
// 加密器类,封装了加密的方法
public class Encryptor {
public void encrypt() {
System.out.println("encrypt object");
}
}
// 加密外观类,封装了文件的读取、加密和保存三个操作
public class FileEncryptor {
private FileReader reader = new FileReader();
private Encryptor encryptor = new Encryptor();
private FileSaver saver = new FileSaver();
public void read() {
reader.read();
}
public void encrypt() {
reader.read();
encryptor.encrypt();
saver.save();
}
public void save() {
saver.save();
}
}
用户调用如下:
public class Client {
public static void main(String[] args) {
FileEncryptor encryptor = new FileEncryptor(); // 创建外观类对象
encryptor.encrypt(); // 调用加密方法
}
}
// 结果
// read from stream
// read file
// encrypt object
// write to stream
// save file
5.题目5
要求:某论坛已注册用户和游客的权限不同,已注册用户拥有发帖、修改自己的注册信息等功能;游客只能看别人的帖子,没有其他权限。使用Proxy模式来设计。
类图如下:
代码如下:
// 访问者类
public abstract class Visitor {
protected int type; // 用户类型:0为游客,1为注册用户
public Visitor(int type) {
this.type = type;
}
abstract void view();
abstract void publish();
abstract void modifyRegInfo();
}
// 注册用户类,实现各个接口
public class User extends Visitor {
public User(int type) {
super(type);
}
@Override
void view() {
System.out.println("view an article");
}
@Override
void publish() {
System.out.println("publish an article");
}
@Override
void modifyRegInfo() {
System.out.println("view an article");
}
}
// 访问代理类
public class VisitorProxy extends Visitor {
private User user = new User(type);
public VisitorProxy(int type) {
super(type);
}
@Override
void view() {
user.view();
}
@Override
void publish() {
// 注册用户
if (type == 1) {
user.publish();
}
// 游客
else {
System.out.println("You are not login, can't publish an article.");
}
}
@Override
void modifyRegInfo() {
// 注册用户
if (type == 1) {
user.publish();
}
// 游客
else {
System.out.println("You are not login, can't modify your personal information.");
}
}
}
用户调用如下:
public class Client {
public static void main(String[] args) {
int type = 1; // 注册用户
VisitorProxy proxy = new VisitorProxy(type);
proxy.view(); // 看帖
proxy.publish(); // 发帖
proxy.modifyRegInfo(); // 修改注册信息
type = 2; // 游客
proxy = new VisitorProxy(type);
proxy.view(); // 看帖
proxy.publish(); // 发帖
proxy.modifyRegInfo(); // 修改注册信息
}
}
// 结果
// view an article
// publish an article
// publish an article
// view an article
// You are not login, can't publish an article.
// You are not login, can't modify your personal information.