設(shè)計(jì)模式系列|之外觀(門面)模式
本文轉(zhuǎn)載自微信公眾號(hào)「狼王編程」,作者狼王。轉(zhuǎn)載本文請(qǐng)聯(lián)系狼王編程公眾號(hào)。
1、概述
外觀模式是一種結(jié)構(gòu)型設(shè)計(jì)模式, 能為程序庫(kù)、 框架或其他復(fù)雜類提供一個(gè)簡(jiǎn)單的接口。
避免多種不相關(guān)的功能污染單一外觀, 使其變成又一個(gè)復(fù)雜結(jié)構(gòu)。客戶端和其他外觀都可使用附加外觀。
2、適用場(chǎng)景
1)如果你需要一個(gè)指向復(fù)雜子系統(tǒng)的直接接口, 且該接口的功能有限, 則可以使用外觀模式。外觀將會(huì)提供指向子系統(tǒng)中最常用功能的快捷方式, 能夠滿足客戶端的大部分需求。
2)如果需要將子系統(tǒng)組織為多層結(jié)構(gòu), 可以使用外觀。你可以為每個(gè)層次創(chuàng)建一個(gè)外觀, 然后要求各層的類必須通過這些外觀進(jìn)行交互。
3、實(shí)例
有以下場(chǎng)景:
當(dāng)前有學(xué)生子系統(tǒng),該系統(tǒng)有三個(gè)接口,查詢學(xué)生姓名,查詢學(xué)生年齡,查詢學(xué)生家庭地址。
有一個(gè)教學(xué)系統(tǒng),要分別去調(diào)用這三個(gè)接口。
有一個(gè)成績(jī)系統(tǒng),要分別調(diào)用者三個(gè)接口。
有一個(gè)考試系統(tǒng),也要分別調(diào)用這三個(gè)系統(tǒng)。
3.1 不使用外觀模式時(shí)候
- /**
- * 學(xué)生
- */
- public class Student {
- private String name = "狼王";
- private int age = 25;
- private String address = "上海";
- public Student(String name, int age, String address) {
- this.name = name;
- this.age = age;
- this.address = address;
- }
- public Student(){
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- }
- /**
- * 學(xué)生
- */
- public class Student {
- private String name = "狼王";
- private int age = 25;
- private String address = "上海";
- public Student(String name, int age, String address) {
- this.name = name;
- this.age = age;
- this.address = address;
- }
- public Student(){
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- }
- /**
- * 年齡接口
- */
- @Service
- public class StudentAgeService implements IStudentAge{
- @Override
- public int getAge() {
- Student student = new Student();
- return student.getAge();
- }
- }
- @Service
- public class StudentNameService implements IStudentName{
- @Override
- public String getName() {
- Student student = new Student();
- return student.getName();
- }
- }
三個(gè)外部服務(wù)
- /**
- * 教育服務(wù)
- */
- @Service
- public class EduService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public void getStudentName(){
- System.out.println("學(xué)生姓名是:" + studentNameService.getName());
- }
- public void getStudentAge(){
- System.out.println("學(xué)生年齡是:" + studentAgeService.getAge());
- }
- public void getStudentAddress(){
- System.out.println("學(xué)生地址是:" + studentAddressService.getAddress());
- }
- }
- /**
- * 考試服務(wù)
- */
- @Service
- public class ExamService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public void getStudentName(){
- System.out.println("學(xué)生姓名是:" + studentNameService.getName());
- }
- public void getStudentAge(){
- System.out.println("學(xué)生年齡是:" + studentAgeService.getAge());
- }
- public void getStudentAddress(){
- System.out.println("學(xué)生地址是:" + studentAddressService.getAddress());
- }
- }
- /**
- * 成績(jī)服務(wù)
- */
- @Service
- public class ScoreService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public void getStudentName(){
- System.out.println("學(xué)生姓名是:" + studentNameService.getName());
- }
- public void getStudentAge(){
- System.out.println("學(xué)生年齡是:" + studentAgeService.getAge());
- }
- public void getStudentAddress(){
- System.out.println("學(xué)生地址是:" + studentAddressService.getAddress());
- }
- }
3.2 使用外觀模式
在學(xué)生服務(wù)這里增加一個(gè)外觀service
- /**
- * 外觀模式服務(wù)
- */
- @Service
- public class StudentFacedService {
- @Autowired
- private StudentNameService studentNameService;
- @Autowired
- private StudentAgeService studentAgeService;
- @Autowired
- private StudentAddressService studentAddressService;
- public String getStudentName(){
- return studentNameService.getName();
- }
- public int getStudentAge(){
- return studentAgeService.getAge();
- }
- public String getStudentAddress(){
- return studentAddressService.getAddress();
- }
- }
三個(gè)調(diào)用服務(wù)只需要引入外觀服務(wù)
- /**
- * 教育服務(wù)
- */
- @Service
- public class EduService {
- @Autowired
- private StudentFacedService studentFacedService;
- public void getStudentName() {
- System.out.println("學(xué)生姓名是:" + studentFacedService.getStudentName());
- }
- public void getStudentAge() {
- System.out.println("學(xué)生年齡是:" + studentFacedService.getStudentAge());
- }
- public void getStudentAddress() {
- System.out.println("學(xué)生地址是:" + studentFacedService.getStudentAddress());
- }
- }
- /**
- * 考試服務(wù)
- */
- @Service
- public class ExamService {
- @Autowired
- private StudentFacedService studentFacedService;
- public void getStudentName() {
- System.out.println("學(xué)生姓名是:" + studentFacedService.getStudentName());
- }
- public void getStudentAge() {
- System.out.println("學(xué)生年齡是:" + studentFacedService.getStudentAge());
- }
- public void getStudentAddress() {
- System.out.println("學(xué)生地址是:" + studentFacedService.getStudentAddress());
- }
- }
- /**
- * 成績(jī)服務(wù)
- */
- @Service
- public class ScoreService {
- @Autowired
- private StudentFacedService studentFacedService;
- public void getStudentName() {
- System.out.println("學(xué)生姓名是:" + studentFacedService.getStudentName());
- }
- public void getStudentAge() {
- System.out.println("學(xué)生年齡是:" + studentFacedService.getStudentAge());
- }
- public void getStudentAddress() {
- System.out.println("學(xué)生地址是:" + studentFacedService.getStudentAddress());
- }
- }
4、分析
以上兩種方式代碼結(jié)構(gòu)如下所示:
從上面兩張圖可以看到,對(duì)于外部服務(wù)來說,極大的縮減了代碼復(fù)雜度,只需要調(diào)用學(xué)生服務(wù)的一個(gè)接口。
5、總結(jié)
優(yōu)點(diǎn):
讓客戶端代碼獨(dú)立獨(dú)立于復(fù)雜的子系統(tǒng),且減少對(duì)于子系統(tǒng)的依賴。
缺點(diǎn):
過于龐大的外觀,會(huì)使得該外觀稱成為上帝對(duì)象,造成所有類的耦合,可通過它操作所有的類功能。
好了。今天就說到這了,我還會(huì)不斷分享自己的所學(xué)所想,希望我們一起走在成功的道路上!


































