设计模式第二次作业
1、要求:如果需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Linux、UNIX等)上播放多种格式的视频文件,常见的视频格式包括MPEG、RMVB、AVI、WMV等。使用Bridge模式来设计。
类图如下:
代码:
abstract class MediaPlayer{
Platform pf;
public MediaPlayer(Platform pf) {
this.pf=pf;
}
public void loadApi(){
pf.load_api();
}
public abstract void decodeFormal();
}
class MpegPlayer extends MediaPlayer{
public MpegPlayer(Platform pf) {
super(pf);
}
public void decodeFormal() {
// TODO Auto-generated method stub
System.out.println("MPEG palyer");
}
}
class RmvbPlayer extends MediaPlayer{
public RmvbPlayer(Platform pf) {
super(pf);
}
public void decodeFormal() {
// TODO Auto-generated method stub
System.out.println("RMVB palyer");
}
}
class AviPlayer extends MediaPlayer{
public AviPlayer(Platform pf) {
super(pf);
}
public void decodeFormal() {
// TODO Auto-generated method stub
System.out.println("AVI palyer");
}
}
class WmvPlayer extends MediaPlayer{
public WmvPlayer(Platform pf) {
super(pf);
}
public void decodeFormal() {
// TODO Auto-generated method stub
System.out.println("WMV palyer");
}
}
abstract class Platform{
public abstract void load_api();
}
class windowsPlatform extends Platform{
public void load_api() {
// TODO Auto-generated method stub
System.out.println("load windows api");
}
}
class linuxPlatform extends Platform{
public void load_api() {
// TODO Auto-generated method stub
System.out.println("load linux api");
}
}
class unixPlatform extends Platform{
public void load_api() {
// TODO Auto-generated method stub
System.out.println("load unix api");
}
}
//测试代码
MediaPlayer player=new MpegPlayer(new windowsPlatform());
player.loadApi();
player.decodeFormal();
//运行结果
load windows api
MPEG palyer
小结
- 桥接模式:先要弄清楚具体实现的对象是哪一个。再本题中,为多媒体播放器,它有MPEG、WMV、AVI、RMVB等解码方式,而且有需要跨平台,所以,在播放器中需要一个platform的抽象类,之后根据传进来的具体实现的platform,来加载不同的api,之后,在播放文件的时候再选择解码器。其核心部分,还是在于一个抽象类中包含另一个抽象类。
2、要求:杀毒软件(AntiVirus)既能对系统中不同类型的文件 TextFile、ImageFile、VideoFile杀毒,也能对文件夹的杀毒,对文件夹杀毒就是对其中所包含文件的杀毒。使用Composite模式来设计。
类图如下:
代码:
abstract class File{
String name;
public File(String name) {
this.name=name;
}
public abstract void AntiVirus();
}
class TextFile extends File{
public TextFile(String name) {
super(name);
}
public void AntiVirus() {
// TODO Auto-generated method stub
System.out.println("TextFile "+name+" AntiVirus");
}
}
class ImageFile extends File{
public ImageFile(String name) {
super(name);
}
public void AntiVirus() {
// TODO Auto-generated method stub
System.out.println("ImageFile "+name+" AntiVirus");
}
}
class VideoFile extends File{
public VideoFile(String name) {
super(name);
}
public void AntiVirus() {
// TODO Auto-generated method stub
System.out.println("VideoFile "+name+" AntiVirus");
}
}
class Directory extends File{
List<File> list=new ArrayList<File>();
public Directory(String name) {
super(name);
}
public void addFile(File file){
list.add(file);
}
public void AntiVirus() {
// TODO Auto-generated method stub
System.out.println("Directory "+name+" AntiVirus");
int size=list.size();
for(int i=0;i<size;i++){
list.get(i).AntiVirus();
}
}
}
//测试代码
Directory rootFile=new Directory("root");
rootFile.addFile(new TextFile("root textFile"));
rootFile.addFile(new ImageFile("root imageFile"));
Directory nomalFile=new Directory("normal");
nomalFile.addFile(new VideoFile("normal videoFile"));
nomalFile.addFile(new ImageFile("normal imageFile"));
rootFile.addFile(nomalFile);
rootFile.AntiVirus();
//运行结果
Directory root AntiVirus
TextFile root textFile AntiVirus
ImageFile root imageFile AntiVirus
Directory normal AntiVirus
VideoFile normal videoFile AntiVirus
ImageFile normal imageFile AntiVirus
小结
- 组合模式:就是有一个抽象类,用几个类去实现它。常用于产生树形的结构。文件夹里有文件、文件夹,子文件夹里又有文件,这样就构成了一个树形结构。实现组合模式的要点还是在于在某种“容器”中写入list去添加文件。
3、要求:某系统提供一个数据加密功能,可以对字符串进行加密。最简单的加密算法通过对字母进行移位来实现,同时还提供稍复杂的逆向输出加密,还提供更为高级的求模加密。用户首先使用最简单的加密算法对字符串进行加密,如果觉得还不够可以对加密后的结果使用其他的加密算法进行二次加密,当然也可以进行第三次加密。使用Decrator模式来设计。
类图如下:
代码:
abstract class EncryptionMethod {
public abstract String EncryptionMethod(String data);
}
class FirstMethod extends EncryptionMethod{
@Override
public String EncryptionMethod(String data) {
// TODO Auto-generated method stub
return data+data+" FirstMethod to Encrypt";
}
}
class MethodDecorator extends EncryptionMethod{
EncryptionMethod method;
public MethodDecorator(EncryptionMethod method) {
this.method=method;
}
@Override
public String EncryptionMethod(String data) {
// TODO Auto-generated method stub
return method.EncryptionMethod(data);
}
}
class SecondMethod extends MethodDecorator{
public SecondMethod(EncryptionMethod method) {
super(method);
// TODO Auto-generated constructor stub
}
@Override
public String EncryptionMethod(String data) {
// TODO Auto-generated method stub
return data+" SecondMethod to Encrypt";
}
}
class ThirdMethod extends MethodDecorator{
public ThirdMethod(EncryptionMethod method) {
super(method);
// TODO Auto-generated constructor stub
}
@Override
public String EncryptionMethod(String data) {
// TODO Auto-generated method stub
return data+" ThirdMethod to Encrypt";
}
}
//测试代码
String data="original data";
String encryptedData;
EncryptionMethod FirstMethod=new FirstMethod();
encryptedData=FirstMethod.EncryptionMethod(data);
System.out.println(encryptedData);
EncryptionMethod secondEncryption=new SecondMethod(FirstMethod);
encryptedData=secondEncryption.EncryptionMethod(encryptedData);
System.out.println(encryptedData);
EncryptionMethod thirdEncryption=new ThirdMethod(secondEncryption);
encryptedData=thirdEncryption.EncryptionMethod(encryptedData);
System.out.println(encryptedData);
//运行结果
original dataoriginal data FirstMethod to Encrypt
original dataoriginal data FirstMethod to Encrypt SecondMethod to Encrypt
original dataoriginal data FirstMethod to Encrypt SecondMethod to Encrypt ThirdMethod to Encrypt
小结
- 装扮者模式:这种模式将所有的装扮都最终集中到一个被装扮的对象身上。所以,正好符合题中要求的:在原始字符串上第一次加密,在此基础上第二次加密,之后,可以在基础上第三次加密。所以,所有的可以实现加密(装饰者)的类,都应该继承自同一个被装扮的类,重写装扮的方法(在本题中是重写加密的方法),再在每个加密(装饰者)的类中维护一个被装扮者的对象。这样,就可以在构造更高级的装扮时,引入低级的装扮的对象。(因为所有加密算法的类现在都继承自原始字符串Data类,在内部又维护了一个Data对象,所以,在实现第二次加密的时候,就可以将第一次加密的当作Data的实现类传入)。
4、要求:某系统需要提供一个文件加密模块,加密流程包括:读源文件、加密、保存加密文件。读取文件和保存文件使用流来实现,三个业务相对独立,封装在不同的类中;现在需要提供一个统一的加密外观类,用户可以直接使用该加密外观类完成文件的读取、加密和保存三个操作。使用Facade模式来设计。
类图如下:
代码:
class ReadSource{
public void operate(){
System.out.println("ReadSource");
}
}
class Encrypt{
public void operate(){
System.out.println("EncryptSource");
}
}
class Save{
public void operate(){
System.out.println("SaveSource");
}
}
class Union{
ReadSource read;
Encrypt en;
Save save;
public Union() {
read=new ReadSource();
en=new Encrypt();
save=new Save();
}
public void operate(){
read.operate();
en.operate();
save.operate();
}
}
//测试代码
Union union=new Union();
union.operate();
//运行结果
ReadSource
EncryptSource
SaveSource
小结
- 外观模式:这个模式,说的形象点,就是一个自动挡汽车的启动过程。用户只需要有一个自动挡汽车启动的按钮,去点就好了,在用户按下这个按钮之后,其内部一系列的部件就会启动,这一切都是自动的。在对应到代码中,也就是,拥有三个类,分别在其内部存在着执行的方法,在一个总的外观类中,维护另外三个类的对象,在外观类的某个方法中,使用三个对象去执行其各自的方法。
5、要求:某论坛已注册用户和游客的权限不同,已注册用户拥有发帖、修改自己的注册信息等功能;游客只能看别人的帖子,没有其他权限。使用Proxy模式来设计。
类图如下:
代码:
abstract class Visitor{
int identity;// identity 1:已注册 0:注册
public Visitor() {
identity=0;
}
public int getIdentity() {
return identity;
}
public abstract void post();
public abstract void changeInfo();
public abstract void read();
}
class RegistedVistor extends Visitor{
public RegistedVistor() {
this.identity=1;
}
@Override
public void post() {
// TODO Auto-generated method stub
System.out.println("发帖成功");
}
@Override
public void changeInfo() {
// TODO Auto-generated method stub
System.out.println("修改信息成功");
}
@Override
public void read() {
// TODO Auto-generated method stub
System.out.println("阅读帖子");
}
}
class Proxy extends Visitor{
Visitor vistor;
public Proxy(Visitor vistor) {
this.vistor=vistor;
}
public void post(){
if(vistor.identity==1){
//已注册
vistor.post();//代理执行这个方法
}else {
System.out.println("您没有发帖权限");
}
}
public void changeInfo(){
if(vistor.identity==1){
//已注册
vistor.changeInfo();//代理执行这个方法
}else {
System.out.println("您没有更改信息权限");
}
}
@Override
public void read() {
// TODO Auto-generated method stub
if(vistor.identity==1){
//已注册
vistor.read();//代理执行这个方法
}else {
System.out.println("阅读帖子");
}
}
}
//测试代码
RegistedVistor registeredUser=new RegistedVistor();
Proxy p = new Proxy(registeredUser);
p.post();
p.read();
p.changeInfo();
//运行结果
发帖成功
阅读帖子
修改信息成功
小结
- 代理模式:就是吧事情给代理去做。将能否发帖的判断交给代理。代理拿到用户,判断用户当前的身份信息,是注册用户还是游客,再代理client执行代理的post方法时,代理进行判断身份,如果时注册用户,那么,调用其内部的注册用户的对象去实现这个具体的post方法。代理充当中间人,连接当前用户与权限。
- 这里就涉及到与中介模式的对比:中介模式是两个类的双向通讯的协调,而代理模式,则是单向的。