设计模式的艺术 结构性模式之外观模式

前言

去饭馆吃饭,自己只需要点个菜,然后自然后厨做好了之后会有服务员给你端上来,真正来讲,自己只需要告诉服务员自己要吃的菜就行,不需要与原材料和厨子之间发生任何的交互,在软件设计思想中也有这样的场景,为了完成一个复杂的功能,一个类可能需要与多个其他业务类发生交互,而这些交互类经常会作为一个整体出现,因为涉及的业务类比较多,导致使用代码时比较复杂,所以这时候就需要一个类似于服务员的外观类,由他为这些需要交互的业务类提供一个统一的入口,从而简化类与类之间的交互。

什么是外观模式 Facade Pattern

外部与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易的使用。外观模式又称为门面模式,它是一种对象结构型模式。

外观模式的优点

(1)、对客户端屏蔽了子系统的组件,减少了客户端所需处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户端代码将变得简单,与之关联的对象也很少。

(2)、实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。

(3)、一个子系统的修改对其他子系统没有任何的影响,而且子系统内部的变化也不会影响到外观对象。

(4)、只是提供了一个访问子系统的统一入口,并不影响客户端直接使用子系统类。

外观模式的主要缺点

(1)、不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性。

(2)、如果设计不当,增加新的子系统可能需要修改外观类的源代码,这违背了开闭原则

外观模式的适用场景

(1)、当要为访问一系列复杂的子系统提供一个简单入口时可以使用外观模式

(2)、客户端程序与多个子系统之间存在着很大的依赖性。引入外观类可以将子系统与客户端之间实现解耦,从而提供子系统的独立性和可移植性,这是迪米特法则的具体体现

(3)、在层次结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

外观模式的具体实现

项目结构

子系统的类

//数据加密类:子系统类
public class CipherMachine {
    public String encrypt(String plainText){
        System.out.println("数据加密,将明文转换为密文");
        String es="";
        for(int i=0;i<plainText.length();i++){
            String c=String.valueOf(plainText.charAt(i)%7);
            es+=c;
        }
        System.out.println(es);
        return es;
    }
}
package com.company.documentFunction;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

//文件读取类:子系统类
public class FileReader {
    public String read(String fileNameSrc){
        System.out.println("读取文件,获取明文");
        StringBuffer sb=new StringBuffer();
        try {
            FileInputStream inFS=new FileInputStream(fileNameSrc);
            int data;
            while ((data=inFS.read())!=-1){
                sb=sb.append((char) data);
            }
            inFS.close();
            System.out.println(sb.toString());
        }catch (FileNotFoundException e){
            e.printStackTrace();
            System.out.println("文件不存在");
            return null;
        }
        catch (IOException e){
            System.out.println("文件操作错误");
        }
        return  sb.toString();
    }
}
package com.company.documentFunction;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

//文件保存类:子系统类
public class FileWriter {
    public void write(String encryptStr,String fileNameDes){
        System.out.println("保存密文,写入文件");
        try {
            FileOutputStream outFS=new FileOutputStream(fileNameDes);
            outFS.write(encryptStr.getBytes());
            outFS.close();
        }catch (FileNotFoundException e){
            System.out.println("文件不存在");
        }catch (IOException e){
            System.out.println("文件操作错误");
        }
    }
}

外观类

package com.company;

import com.company.documentFunction.CipherMachine;
import com.company.documentFunction.FileReader;
import com.company.documentFunction.FileWriter;

//加密外观类:外观类
public class EncryptFacade {
    //维持对其他对象的引用
    private FileReader fileReader;
    private FileWriter fileWriter;
    private CipherMachine cipherMachine;
    public EncryptFacade(){
        fileReader=new FileReader();
        fileWriter=new FileWriter();
        cipherMachine=new CipherMachine();
    }
    //调用其他对象的业务方法
    public void fileEncrypt(String fileNameSrc,String fileNameDes){
        String plainStr=fileReader.read(fileNameSrc);
        String encryptStr=cipherMachine.encrypt(plainStr);
        fileWriter.write(encryptStr,fileNameDes);

    }
}

客户端测试

package com.company;

public class Client {

    public static void main(String[] args) {
           EncryptFacade ef=new EncryptFacade();
           ef.fileEncrypt("1.txt","2.txt");
    }
}

转载请注明出处,掌声送给社会人

猜你喜欢

转载自blog.csdn.net/SCDN_CP/article/details/82964649