设计模式NO.2
本次博客内容为第二次设计模式的练习。根据老师的要求完成下列题目:
题目1
如果需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Linux、UNIX等)上播放多种格式的视频文件,常见的视频格式包括MPEG、RMVB、AVI、WMV等。使用Bridge模式来设计。
类图设计如下:
代码实现如下:
a.视频格式抽象类
public abstract class Form {
public abstract void playForm(String os);
}
b.AVI视频格式类
public class AVI extends Form{
@Override
public void playForm(String os) {
System.out.println("the form of video is AVI. OS version is "+os);
}
}
c.MPEG视频格式类
public class MPEG extends Form{
@Override
public void playForm(String os) {
System.out.println("the form of video is MPEG. OS version is "+os);
}
}
d.RMVB视频格式类
public class RMVB extends Form{
@Override
public void playForm(String os) {
System.out.println("the form of video is RMVB. OS version is "+os);
}
}
e.WAV视频格式类
public class WAV extends Form{
@Override
public void playForm(String os) {
System.out.println("the form of video is WAV. OS version is "+os);
}
}
f.操作系统抽象类
public abstract class OS {
protected Form m_form;
public void setForm(Form form)
{
m_form=form;
}
public abstract void play();
}
g.Windows系统类
public class Windows extends OS{
@Override
public void play() {
m_form.playForm("Windows");
}
}
h.Linux系统类
public class Linux extends OS{
@Override
public void play() {
m_form.playForm("Linux");
}
}
i.UNIX系统类
public class UNIX extends OS{
@Override
public void play() {
m_form.playForm("UNIX");
}
}
j.测试代码
public static void main(String[] args) {
Form form = new RMVB();
OS os = new Windows();
os.setForm(form);
os.play();//the form of video is RMVB. OS version is Windows
form = new AVI();
os = new Linux();
os.setForm(form);
os.play();//the form of video is AVI. OS version is Linux
}
Bridge模式小结
a.优点
桥接模式将抽象部分与它的实现部分分离开来,使他们都可以独立变化。 桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。
b.适用场景
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
- 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
题目2
杀毒软件(AntiVirus)既能对系统中不同类型的文件 TextFile、ImageFile、VideoFile杀毒,也能对文件夹的杀毒,对文件夹杀毒就是对其中所包含文件的杀毒。使用Composite模式来设计。
类图设计如下:
代码实现如下:
a.抽象文件类
public abstract class Files {
public abstract void antiVirus();
}
b.TextFile类
public class TextFile extends Files
{
@Override
public void antiVirus() {
System.out.println("TextFile is antivirusing!");
}
}
c.ImageFile类
public class ImageFile extends Files{
@Override
public void antiVirus() {
System.out.println("ImageFile is antivirusing!");
}
}
d.VideoFile类
public class VideoFile extends Files{
@Override
public void antiVirus() {
System.out.println("VideoFile is antivirusing");
}
}
e.FolderFile类
import java.util.ArrayList;
public class FloderFile extends Files{
private ArrayList<Files> m_files=new ArrayList<Files>();
@Override
public void antiVirus() {
System.out.println("folder is antivirusing!");
for(Files file:m_files)
{
file.antiVirus();
}
}
public void addFile(Files file)
{
m_files.add(file);
}
public void deleteFile(Files file)
{
m_files.remove(file);
}
}
f.AntiVirus类(测试类)
public class AntiVirus {
public static void main(String[] args) {
Files file = new VideoFile();
file.antiVirus();//VideoFile is antivirusing
Files file2 = new TextFile();
file2.antiVirus();//TextFile is antivirusing!
FloderFile files = new FloderFile();
files.addFile(file);
files.addFile(file2);
files.antiVirus();
//folder is antivirusing!
//VideoFile is antivirusing
//TextFile is antivirusing!
}
}
Composite模式小结
Composite模式有两种形态:透明形态和安全形态。本文是使用安全形态实现的。
a.优点
Composite模式 定义了包含基本对象和组合对象的类层次结构,这不仅可以简化客户代码,而且使得更容易增加新类型的组件、设计变得更加一般化。
b.适用场景
- 将对象组合成树形结构以表示 “部分-整体” 的层次结构。
- 使得用户对于单个对象和组合对象的使用具有一致性。
题目3
某系统提供一个数据加密功能,可以对字符串进行加密。最简单的加密算法通过对字母进行移位来实现,同时还提供稍复杂的逆向输出加密,还提供更为高级的求模加密。用户首先使用最简单的加密算法对字符串进行加密,如果觉得还不够可以对加密后的结果使用其他的加密算法进行二次加密,当然也可以进行第三次加密。使用Decrator模式来设计。
类图设计如下:
代码实现如下:
a.抽象加密接口
public interface Encryption {
public void encrypt();
}
b.字母移位加密类
public class ShiftEncryption implements Encryption{
@Override
public void encrypt() {
System.out.println("ShiftEncryption");
}
}
c.逆向输出加密类
public class ConverseEncryption extends Decrator{
public ConverseEncryption(Encryption enc) {
super(enc);
}
public void encrypt() {
m_way.encrypt();
System.out.println("ConverseEncryption");
}
}
d.求模加密类
public class ModEncryption extends Decrator{
public ModEncryption(Encryption enc) {
super(enc);
}
public void encrypt() {
m_way.encrypt();
System.out.println("ModEncryption");
}
}
e. Decrator类
public class Decrator implements Encryption{
protected Encryption m_way;
public Decrator(Encryption enc) {
m_way=enc;
}
@Override
public void encrypt() {
m_way.encrypt();
}
}
f.测试类
public class test {
public static void main(String[] args) {
Encryption enc = new ShiftEncryption();
enc = new ModEncryption(enc);
enc = new ConverseEncryption(enc);
enc = new ModEncryption(enc);
enc.encrypt();
//ShiftEncryption
//ModEncryption
//ConverseEncryption
//ModEncryption
}
}
Decrator模式小结
Decrator模式有透明和半透明两种形态。透明形态是指:装饰者不改变接口类型。半透明形态是指:装饰者改变接口类型,增加新的方法。
本文使用的是透明形态的Decrator模式。
a.优点
装饰模式可以在不改变接口的前提下动态地增强所考虑的类的性能。通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
b.适用场景
- 需要动态的给一个对象增加功能,这些功能可以再动态地撤销。
- 需要增加一些基本功能的排列组合而产生的非常大量的功能。
题目4
某系统需要提供一个文件加密模块,加密流程包括:读源文件、加密、保存加密文件。读取文件和保存文件使用流来实现,三个业务相对独立,封装在不同的类中;现在需要提供一个统一的加密外观类,用户可以直接使用该加密外观类完成文件的读取、加密和保存三个操作。使用Facade模式来设计。
类图设计如下:
代码实现如下:
a.抽象Facade接口
public interface Facade {
public void Encrypt();
}
b.文件加密装饰者FacadeEncryptor
public class FacadeEncryptor implements Facade{
private Reader m_read;
private Saver m_saver;
private Encryptor m_encryptor;
public FacadeEncryptor() {
m_read = new Reader();
m_saver = new Saver();
m_encryptor = new Encryptor();
}
@Override
public void Encrypt() {
m_read.FileReade();
m_encryptor.FileEncrypt();
m_saver.FileSave();
}
}
c.读取文件类
public class Reader {
public void FileReade()
{
System.out.println("File is reading!");
}
}
d.加密文件类
public class Encryptor {
public void FileEncrypt()
{
System.out.println("File is encrypting!");
}
}
e.保存文件类
public class Saver {
public void FileSave()
{
System.out.println("File is saving!");
}
}
f.测试类
public class Client {
public static void main(String[] args) {
Facade fac = new FacadeEncryptor();
fac.Encrypt();
//File is reading!
//File is encrypting!
//File is saving!
}
}
Facade模式小结
a.优点
- 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。
- 实现了子系统与客户之间的松耦合关系。
- 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类
b.适用场景
- 需要为一个复杂子系统提供一个简单接口时。
- 客户程序与抽象类的实现部分之间存在着很大的依赖性。
- 需要构建一个层次结构的子系统时。
题目5
某论坛已注册用户和游客的权限不同,已注册用户拥有发帖、修改自己的注册信息等功能;游客只能看别人的帖子,没有其他权限。使用Proxy模式来设计。
类图设计如下:
代码实现如下:
a.抽象用户类
public abstract class User {
public abstract void view();
public abstract void post();
public abstract void modify();
}
b.注册用户类
public class realUser extends User{
@Override
public void view() {
System.out.println("please view nicely!");
}
@Override
public void post() {
System.out.println("please post nicely!");
}
@Override
public void modify() {
System.out.println("please modify rightly!");
}
}
c.游客类
public class visitor extends User{
private User user;
public visitor(User user)
{
this.user=user;
}
@Override
public void view() {
user.view();
}
@Override
public void post() {
System.out.println("please login!");
}
@Override
public void modify() {
System.out.println("please login!");
}
}
d.测试类
public class Client {
public static void main(String[] args) {
User u1 = new realUser();
u1.view();//please view nicely!
u1.post();//please post nicely!
u1.modify();//please modify rightly!
u1 = new visitor(u1);
u1.view();//please view nicely!
u1.post();//please login!
u1.modify();//please login!
}
}
Proxy模式小结
a.优点
- 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
- 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
b.适用场景
- 需要为一个对象在不同的地址空间提供局部代表的时候,可以使用远程代理。
- 需要控制对原始对象的访问的时候,可以使用保护代理。
- 需要在访问对象执行一些附加操作的时候,可以使用智能指引代理。
需要为一个对象在不同的地址空间提供局部代表的时候,可以使用远程代理。