Comprensión del patrón de diseño: el patrón del observador

    Modelo de observador, modelo de comportamiento de objetos, también conocido como modelo de dependencia, modelo de publicación-suscripción. Cuando cambia el estado de un objeto, varios objetos que dependen de él se pueden actualizar automáticamente a través de notificaciones. Por ejemplo, Oyente en JAVA, Evento en C #. 

    En una relación de dependencia razonable, la estructura inferior no debería depender de la estructura superior . Sin embargo, en algunos casos, los objetos de la capa superior deben actualizarse desde el método de la capa inferior. La solución general es pasar continuamente los objetos de la capa superior a la capa inferior en forma de parámetros. En el modo de observador, las notificaciones se envían a la interfaz en el método de la capa inferior, y el objeto de la capa superior actualiza el contenido a sus atributos a través de la implementación de la interfaz. en.

    En este caso, es necesario actualizar la barra de progreso al copiar archivos grandes.

class FileCopy{
   string srcpath;
   string dispath;
   ProgressBar * progressBar;
   public:
   FileCopy(string s,string d,ProgressBar & p):filepath(s),dispath(d),progressBar(p){}
   void copy(){
     //1 创建目标文件,读取源文件
     disfile =createfile(dispath)
     srcfile =readfile(srcpath)
     
     ....
     double totalsize = srcfile.totalsize();
     double sum = 0;
     while(content=srcfile.readline()){
        //按行写入文件
        disfile.write(content);
        //写文件后更新进度条
        sum +=content.size;
        progressBar->setvalue(sum/totalsize);
     }
   }
}

//------------界面---------------
class MainForm {
ProgressBar  bar;
public:
 void button_Click(){ 
    //.....
    FileCopy fc(srcfile,disfile,&bar);
    fc.copy();
 }
}

En el diseño de código anterior, aunque la función se realiza, los inconvenientes son obvios.

1. El FileCopy de la capa inferior depende del objeto del mainform superior La clase FileCopy no se puede reutilizar para otros proyectos como consolas, páginas web, etc.

2. Cuando el requisito se convierte en "la barra de progreso no se usa para mostrar el progreso, use Etiqueta para mostrar el progreso directamente en porcentaje", entonces el tipo de objeto debe modificarse de arriba a abajo, y progressBar tiene un método setvalue, mientras otros controles pueden no hacerlo. La transformación es muy compleja.

3. Este método actualmente solo admite una barra de progreso. Si desea admitir varios controles diferentes, solo puede extender los parámetros y la capacidad de mantenimiento será peor.

En el siguiente código, se muestra que el diseño del patrón del patrón del observador cumple el mismo requisito. Elimine la dependencia de la capa inferior de la capa superior y consiga la separación de estabilidad y cambio, y las clases y las interfaces se pueden utilizar intactas con otros proyectos. Reutilización de código mejorada, fácil mantenimiento y fácil escalabilidad. En forma de notificación, se abre la interfaz de notificación, lo que permite que las aplicaciones implementen la interfaz para lograr el propósito de actualizar la barra de progreso.

//通知接口
class INotice{
    virtual void notify(double)=0;
}
class FileCopy{
   string srcpath;
   string dispath;
   vector<INotice*> notices; //通知对象集合
   public:
   FileCopy(string s,string d):filepath(s),dispath(d){}
   void add(INotice * in){notices.push_back(in);}
   void copy(){
     //1 创建目标文件,读取源文件
     disfile =createfile(dispath)
     srcfile =readfile(srcpath)
     
     ....
     double totalsize = srcfile.totalsize();
     double sum = 0;
     while(content=srcfile.readline()){
        //按行写入文件
        disfile.write(content);
        //写文件后更新进度条
        sum +=content.size;
        //给所有依赖发出通知
        copynotify(sum/totalsize);
     }
   }
   protected:
   void copynotify(double value){
      for(notice :notices){
        notice->notify(value);
      }
   }
}

//------------界面,实现INotice接口方法---------------
class MainForm:public INotice{
ProgressBar  bar;
public:
 void button_Click(){ 
    //.....
    ChildForm *cform = new ChildForm ();
    FileCopy fc(srcfile,disfile);
    
    fc.add(this);
    fc.add(cform );
    fc.copy();
 }
 virtual void notify(double value){
   bar.setvalue(value);
 }
}

class ChildForm:public INotice{
    Label   label;
    virtual void notify(double value){
       bar.settitle(value);
    }
}

 

 

Supongo que te gusta

Origin blog.csdn.net/superSmart_Dong/article/details/114108125
Recomendado
Clasificación