案例分析:设计模式与代码的结构特性

Posted zhang512

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了案例分析:设计模式与代码的结构特性相关的知识,希望对你有一定的参考价值。

Adapter(适配器)模式

  首先先大致解释一下软件工程当中的适配器模式,适配器模式指的是将?个类的接口转换成客户所希望的另外?个接口,将?个?法控制的现有对象与?个特定接口相匹配,?我们需要的接口对?法修改的类进?包装。我在接下来提供的例程代码中侧重解释一下包装这一特征。

引用关键代码解释该设计模式在该应用场景中的适用性

 1 class Ui_MainWindow(QtWidgets.QWidget):
 2     def __init__(self, parent=None):
 3         super().__init__(parent)
 4         self.setFixedSize(self.width(), self.height())
 5         self.timer_camera = QtCore.QTimer()
 6         self.cap = cv2.VideoCapture()
 7         self.CAM_NUM = 0
 8         self.set_ui()
 9         self.slot_init()
10         self.icons = []
11         self.gen_iconlist()
12         self.coverflag = False
13         self.embedingList = []
14         self.mtcnn_detector = self.load_align()
15         self.images_placeholder = None
16         self.images_placeholder = None
17         self.embeddings = None
18         self.phase_train_placeholder = None
19         self.keep_probability_placeholder = None
20         self.sess = None
21         self.count = 0
22         self.iconPos = []
23         self.iconclass = []
24         self.sess_init()

  这个例程是我们自己完成的一个利用facenet和MTCNN进行人脸识别的一个代码,整个源代码工程将在后面提供展示。以上部分是创建用户界面用到的一部分代码。我们可以看到整个类的名称为Ui_MainWindow,在这个类当中又包含了很多函数,而用户希望看到的用户界面是简洁的,可以找到自己想使用的功能,但是对于程序来说,一个功能可能需要几个甚至几十个函数来完成,而展示在用户面前的可能只是一个小按钮或者小按键。在我们实现的用户界面中同样有这个问题的存在,例如:

 1 def button_open_camera_clicked(self):
 2         if self.timer_camera.isActive() is False:
 3             flag = self.cap.open(self.CAM_NUM)
 4             if flag is False:
 5                 msg = QtWidgets.QMessageBox.warning(
 6                     self, warning, "未检测到相机!", buttons=QtWidgets.QMessageBox.Ok)
 7             else:
 8                 self.timer_camera.start(10)
 9                 self.button_open_camera.setText(关闭相机)
10         else:
11             self.timer_camera.stop()
12             self.cap.release()
13             self.label_show_camera.clear()
14             self.button_open_camera.setText(打开相机)

  在以上代码中,我们看最后一个else后的这几行代码,呈现在用户面前的只是打开相机这一个按钮,但是程序世纪上执行了,stop,release,clear这几个我们定义的函数,其中这些函数又调用了无数个系统函数,这就是我们在此代码实现过程中对于适配器模式的应用。

引入该设计模式后对系统架构和代码结构带来了哪些好处

  首先适配器模式主要实现的就是对于部分系统函数或者自己实现的底层函数进行封装包装,不管呈现在我们面前还是呈现在用户面前都是一种很简洁的方式。以这种方式组织代码时,代码结构将变得非常清晰,程序员可以根据需求功能来构建自己的代码结构,将函数进行很好的分类,并且不同的功能中也可能会调用其他功能模块调用的函数,这样可以提高代码的利用率。

解释其中用到的多态机制

  同一个对象体现出来的多种不同形态的身份,将一种行为表现出不同的效果,要想实现多态的效果,需要现有的继承关系。在我提供的例程中,对于self.button_open_camera.setText()这个函数不止在此init函数中存在,也在后面提供的open_camera等函数中同样存在,同样对该类进行了继承。

说明模块抽象封装的方法

默认适配器
在适配器中同时包含对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法,它适用于一个接口不想使用其所有的方法的情况。因此也称为单接口适配器模式。

双向适配器
如果在对象适配器中,在适配器中同时包含对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法,那么这个适配器就是一个双向适配器。

某系统需要提供一个加密模块,将用户信息(如密码等机密信息)加密之后再存储在数据库中,系统已经定义好了数据库操作类。为了提高开发效率,现需要重用已有的加密算法,这些算法封装在一些由第三方提供的类中,有些甚至没有源代码。使用适配器模式设计该加密模块,实现在不修改现有类的基础上重用第三方加密方法。
 
目标类:
public abstract class DataOperation { private String password; public void setPassword(String password) { this.password=password; } public String getPassword() { return this.password; } public abstract String doEncrypt(int key,String ps); }
适配者类
public final class Caesar { public String doEncrypt(int key,String ps) { String es=""; for(int i=0;i<ps.length();i++) { char c=ps.charAt(i); if(c>=a&&c<=z) { c+=key%26; if(c>z) c-=26; if(c<a) c+=26; } if(c>=A&&c<=Z) { c+=key%26; if(c>Z) c-=26; if(c<A) c+=26; } es+=c; } return es; } }
适配器类:
public class CipherAdapter extends DataOperation
{
    private Caesar cipher;
    
    public CipherAdapter()
    {
        cipher=new Caesar();
    }
    
    public String doEncrypt(int key,String ps)
    {
        return cipher.doEncrypt(key,ps);
    }
}
public class NewCipherAdapter extends DataOperation
{
    private NewCipher cipher;
    
    public NewCipherAdapter()
    {
        cipher=new NewCipher();
    }
    
    public String doEncrypt(int key,String ps)
    {
        return cipher.doEncrypt(key,ps);
    }
}

分析各个模块的内聚度和模块之间的耦合度

1、将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
2、增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。
3、灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。

提供该应用范例完整的源代码包括构建部署的操作过程

https://github.com/zs9802/coverface

以上是关于案例分析:设计模式与代码的结构特性的主要内容,如果未能解决你的问题,请参考以下文章

案例分析:设计模式与代码的结构特性

案例分析:设计模式与代码的结构特性

案例分析:设计模式与代码的结构特性

案例分析:设计模式与代码的结构特性

案例分析:设计模式与代码的结构特性

案例分析:设计模式与代码的结构特性