CoreJava matlab springcloud MongoDB xml cocoa sqlalchemy Backbonejs jScrollPane vue版本 vue实现原理 华为路由器ipv6配置 android逆向工程师 hadoop组件 kubernetes官网 python安装mysql python可视化编程 java9 java覆盖 java删除数组中的元素 java中的队列 java读取文件内容 java字符串操作 shell脚本参数 霜之祝福 倒计时计时器 tftpd64 考试练习系统 自动回复机器人 图片轮播代码 流水账软件 我的世界透视 视频md5修改器 1667 大数据之路 死从天降成就 例外被抛出且未被接住 键盘打字手指口诀 快递电子面单打印软件 opencv是什么
当前位置: 首页 > 学习教程  > 编程语言

轻松学习设计模式2

2020/8/31 15:57:00 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

参考:https://www.runoob.com/design-pattern/design-pattern-intro.html

目录

 

一、前言

二、设计模式六大原则

三、模式分类

四、结构型模式解析

1、代理模式

2、适配器模式

3、装饰器模式

3.1、UML图

3.2 模式设计代码解析

3.3 模式调用代码解析 

4、桥接模式

4.1 UML图

4.2 模式实现

4.3 模式调用

5、总结


一、前言

最近重看设计模式感触良多,做软件还是需要多看设计模式的,好处多多,这个轻松学习设计模式的第二篇。

二、设计模式六大原则

这几个原则还是需要重复的。

1.开闭原则(Open Close Principle)
开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。

2.里氏代换原则(Liskov Substitution Principle)
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。 

3.依赖倒转原则(Dependence Inversion Principle)
这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
 

4.接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
 

5.迪米特法则(最少知道原则)(Demeter Principle)
为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

6.合成复用原则(Composite Reuse Principle)
原则是尽量使用合成/聚合的方式,而不是使用继承。

三、模式分类

创建型:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式;
结构型:代理模式、适配器模式、装饰器模式、桥接模式、组合模式、享元模式、外观模式;
行为型:观察者模式、模板方法模式、命令模式、状态模式、职责链模式、解释器模式 、中介者模式、访问者模式、策略模式、备忘录模式、迭代器模式;

J2EE 模式:MVC 模式(MVC Pattern)、业务代表模式(Business Delegate Pattern)、组合实体模式(Composite Entity Pattern)、数据访问对象模式(Data Access Object Pattern)、前端控制器模式(Front Controller Pattern)、拦截过滤器模式(Intercepting Filter Pattern)、服务定位器模式(Service Locator Pattern)、传输对象模式(Transfer Object Pattern)。

四、结构型模式解析

1、代理模式

     在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

 

class Image 
{
   vitrual void display()=0;
}
class RealImage :public Image
 {
 
   
 
   public:
       RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }
 

   public:
      virtual  void display() 
   {
      System.out.println("Displaying " + fileName);
   }
 
   private :
      void loadFromDisk(String fileName)
   {
      System.out.println("Loading " + fileName);
   }
   
  private:
       String fileName;

}

class ProxyImage :public Image
{
 
   private:
     RealImage realImage;
      String fileName;
 
   public:
      ProxyImage(String fileName)
    {
      this.fileName = fileName;
    }

    virtual void display() 
     {
      if(realImage == null){
         realImage = new RealImage(fileName);
      }
      realImage.display();
   }
}



   

           从代理模式的实现代码我们可以发现,类RealImage和类ProxyImage都实现了基类的display的接口,ProxyImage中实现是通过使用RealImage对象来实现display接口的。

int main(String[] args)
{
      Image image = new ProxyImage("test_10mb.jpg");
 
      // 图像将从磁盘加载
      image.display(); 
      System.out.println("");
      // 图像不需要从磁盘加载
      image.display();  
   
}

      从代理模式的调用代码我们可以看出,我们只需要使用代理类,不需要和未代理类打交道。

2、适配器模式

 

class MediaPlayer
 {
   public:
   vitrual void play(String audioType, String fileName)=0;
}


class MediaAdapter : public MediaPlayer
{
 
   AdvancedMediaPlayer advancedMusicPlayer;
 
   public:
     MediaAdapter(String audioType)
   {
      if(audioType.equalsIgnoreCase("vlc") ){
         advancedMusicPlayer = new VlcPlayer();       
      } else if (audioType.equalsIgnoreCase("mp4")){
         advancedMusicPlayer = new Mp4Player();
      }  
    }
 

         vitrual void play(String audioType, String fileName) 
       {
          if(audioType.equalsIgnoreCase("vlc")){
             advancedMusicPlayer.playVlc(fileName);
          }else if(audioType.equalsIgnoreCase("mp4")){
         advancedMusicPlayer.playMp4(fileName);
         }
       } 
}



class AudioPlayer :public MediaPlayer {
   MediaAdapter mediaAdapter; 
 
public:

   vitual void play(String audioType, String fileName)
 {    
 
      //播放 mp3 音乐文件的内置支持
      if(audioType.equalsIgnoreCase("mp3")){
         System.out.println("Playing mp3 file. Name: "+ fileName);         
      } 
      //mediaAdapter 提供了播放其他文件格式的支持
      else if(audioType.equalsIgnoreCase("vlc") 
         || audioType.equalsIgnoreCase("mp4")){
         mediaAdapter = new MediaAdapter(audioType);
         mediaAdapter.play(audioType, fileName);
      }
      else{
         System.out.println("Invalid media. "+
            audioType + " format not supported");
      }
   }   
}

      从实现模式的代码中我们可以发现,类MediaAdapter 对类AdvancedMediaPlayer 实现了适配,类AudioPlayer 又适配了类MediaAdapter,AudioPlayer 从而实现进行播放不同的格式。

int main() 
{
      AudioPlayer audioPlayer = new AudioPlayer();
 
      audioPlayer.play("mp3", "beyond the horizon.mp3");
      audioPlayer.play("mp4", "alone.mp4");
      audioPlayer.play("vlc", "far far away.vlc");
      audioPlayer.play("avi", "mind me.avi");
}

从调用代码我们可以发现,我们只需要和audioPlayer打交道就可以实现不同格式音乐的播放。从而统一了对外调用。

3、装饰器模式

      装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

3.1、UML图

    

3.2 模式设计代码解析

class Shape 
{
   virtual void draw()=0;
}

class Rectangle :Public Shape {
 
   
   public :
    vitural void draw() {
      System.out.println("Shape: Rectangle");
      }
}

class Circle :public Shape 
{
 
   
   public:
    virtual void draw() {
      System.out.println("Shape: Circle");
     }
}

 class ShapeDecorator: public Shape 
{

 
   public:
     ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
     }

     virtual void draw(){
      decoratedShape.draw();
     }  
   protected:
     Shape decoratedShape;
}


public class RedShapeDecorator :public ShapeDecorator 
{
 

 

   public:
      virtual  void draw() {
      decoratedShape.draw();         
      setRedBorder(decoratedShape);
      }
 
   private:
      void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
      }
}

public class TxtShapeDecorator :public ShapeDecorator 
{
 

 

   public:
      virtual  void draw() {
      decoratedShape.draw();         
      setText(decoratedShape);
      }
 
   private:
      void setText(Shape decoratedShape){
      System.out.println("Border Color: Red");
      }
}



      模式设计代码还是比较清晰易懂的,ShapeDecorator是装饰类的抽象基类,它也是集成自shape类的,这样我们就可以设计许多个装饰类从而实现对对象的迭代装饰,就如同一件一件穿衣服一样。

3.3 模式调用代码解析 


int  main() 
{
 
      Shape circle = new Circle();
      ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
      ShapeDecorator redCircleText = new TxtShapeDecorator(redCircle);

      System.out.println("Circle with normal border");
      circle.draw();
 
      System.out.println("\nCircle of red border");
      redCircle.draw();
 
      System.out.println("\nCircle of red border and text");
      redCircleText .draw();
 }

      调用代码也是比较清晰的,我们首先定义了一个circle对象,然后使用RedShapeDecorator和TxtShapeDecorator类对其进行装饰,可以得到一个有边框和文本的圆。

4、桥接模式

     桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

4.1 UML图

4.2 模式实现

class DrawAPI
{
   public:
      virtual void drawCircle(int radius, int x, int y)=0;
}


class RedCircle :public DrawAPI
{
   
   public:
     void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle[ color: red, radius: "
         + radius +", x: " +x+", "+ y +"]");
      }
}


class GreenCircle :public DrawAPI 
{
 
   public:
   virutal void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle[ color: green, radius: "
         + radius +", x: " +x+", "+ y +"]");
    }
}
class Shape 
{
  
   protected:
     Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
     }
   public:
      virtual void draw()=0;  

   protected:
       DrawAPI drawAPI;
}


 class Circle :public Shape 
{

 
   public:
     Circle(int x, int y, int radius, DrawAPI drawAPI) {
      super(drawAPI);
      this.x = x;  
      this.y = y;  
      this.radius = radius;
     }
 
   virtual void draw() {
      drawAPI.drawCircle(radius,x,y);
   }

   private:
       int x, y, radius;
}






    模式实现代码不复杂,上面的代码实现了shape接口和shape绘制实现之间的分离 ,我们可以使用RedCircle和GreenCircle去进行Circle的绘制,灵活性强。

4.3 模式调用


int  main() 
{
      Shape redCircle = new Circle(100,100, 10, new RedCircle());
      Shape greenCircle = new Circle(100,100, 10, new GreenCircle());
 
      redCircle.draw();
      greenCircle.draw();
}

      调用这里我们需要何Shape类、Circle类、RedCircle类和GreenCircle类打交道,桥接接口将接口和实现相分离带来的好处是灵活性强,不利的就是调用方需要打交道的类比较多。

5、总结

    今天分析了几个结构性的设计模式,我们应该根据我们的使用场景灵活选择。结构型设计模式还没介绍完,下次继续。今天就先写到这吧,设计模式估计要写一段时间才能写完了。


本文链接:
http://www.dtmao.cc/news_show_150453.shtml

附件下载

上一篇:python数据可视化

下一篇:分组聚合

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?