zoukankan      html  css  js  c++  java
  • 设计模式与面向对象

    一、设计模式

      设计模式:对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。

      每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计

      设计模式的创始人,一般称为“四人帮”(Gang of Four, GoF):Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides......他们编写一套书来介绍23种设计模式:《设计模式:可复用面向对象软件的基础》。

    二、面向对象回顾

      设计模式是用来设计面向对象系统中的设计。不解决面向过程的问题。

    1、面向对象的三大特性

      封装:把数据和函数封装到一个类里,体现类内和类外。

      继承:由于有了封装,需要通过继承在类之间复用代码。

      多态:python本身是一门多态语言,因此不需去处理多态的问题。Java中则会区分虚类和普通类。

      因此这三个特性是一个递进的关系。

    2、接口

      接口:若干抽象方法的集合。

      作用:限制实现接口类必须按照接口给定的调用方式实现这些方法;对高层模块隐藏了类的内部实现

    # 方法一:继承
    # 存在的问题是:如果不调用pay方法并不会报错
    class Payment:
        def pay(self, money):
            raise NotImplementedError
    
    class Alipay(Payment):
        pass
    
    class WechatPay(Payment):
        pass
    
    p = Alipay()
    p.pay(100)
    
    
    # 方法二:抽象类
    # 约束子类必须实现抽象类:TypeError: Can't instantiate abstract class Alipay with abstract methods pay
    from abc import ABCMeta, abstractmethod
    
    class Payment(metaclass=ABCMeta):
        # abstract class
        @abstractmethod
        def pay(self, money):   # 抽象方法
            pass
    
    class Alipay(Payment):
        def pay(self, money):   # 实现Payment接口
            print('支付宝支付%d元' % money)
    
    class WechatPay(Payment):
        def pay(self, money):   # 实现Payment接口
            print("微信支付%d元" % money)
    
    p = Alipay()
    p.pay(100)

      不用去查看具体实现,只要去查看接口(抽象类)的结构和注释,就可以了解需要传递的参数和pay方法的使用。

      在写底层模块或者开源框架时需要大量应用设计模式,优化封装,让程序员在学习和使用时非常方便。

    三、面向对象设计SOLID原则

      不管是面向对象设计还是各个设计模式都需要遵循这五大原则。

    • 开放封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展
    • 里氏替换原则:所有引用父类的地方必须能透明地使用其子类的对象。(子类是特殊的父类,子类继承父类时同样方法的表现一致)
      # 子类和父类的show_name内部实现和逻辑可能不同,但是参数和返回值是相同的
      class User:
          def show_name(self):
              pass
      
      class VIPUser(User):
          def show_name(self):
              pass
      
      def show_user(u):  # u可以是普通用户或VIP
          res = u.show_name()
    • 依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
      from abc import ABCMeta, abstractmethod
      
      class Payment(metaclass=ABCMeta):  # 抽象
          # abstract class
          @abstractmethod
          def pay(self, money):   # 抽象方法
              pass
      
      class Alipay(Payment):      # 细节
          def pay(self, money):   # 实现Payment接口
              print('支付宝支付%d元' % money)
      
      class WechatPay(Payment):   # 细节
          def pay(self, money):   # 实现Payment接口
              print("微信支付%d元" % money)
    • 接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
      from abc import ABCMeta, abstractmethod
      
      # (一)单一总接口的情况
      # 子类必须实现所有抽象方法,但其实很多方法是子类不需要的
      class Animal(metaclass=ABCMeta):
          @abstractmethod
          def walk(self):
              pass
      
          @abstractmethod
          def swim(self):
              pass
      
          @abstractmethod
          def fly(self):
              pass
      
      class Tiger(Animal): # Class Tiger must implement all abstract methods
          def walk(self):
              print("老虎走路")
      
      # (二)多个接口隔离情况
      class LandAnimal(metaclass=ABCMeta):
          @abstractmethod
          def walk(self):
              pass
      
      class WaterAnimal(metaclass=ABCMeta):
          @abstractmethod
          def swim(self):
              pass
      
      class SkyAnimal(metaclass=ABCMeta):
          @abstractmethod
          def fly(self):
              pass
      
      class Tiger(LandAnimal):
          def walk(self):
              print("老虎走路")
      
      class Frag(LandAnimal,WaterAnimal):  # 青蛙多继承
          pass
    • 单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责

    四、设计模式分类

    1、创建型模式(5种)

      主要聚焦怎么去创建对象。目的是为了隐藏底层模块的逻辑。

      工厂方法模式、抽象工厂模式、创建者模式、原型模式、单例模式。

      创建型模式

    2、结构型模式(7种)

      主要关注在几个类之间怎么组合协同工作在一起。

      适配器模式、桥模式、组合模式、装饰模式、外观模式、享元模式、代理模式。

      结构型模式

    3、行为型模式(11种)

      主要关注方法和行为的完成。

      解释器模式、责任链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、访问者模式、模板方法模式。

      行为型模式

    五、设计模式总结

      python这门语言是一个动态语言,对参数、父类子类等限制不严格。对设计模式并不强求,不是完全契合,而java则是完全与设计模式契合。但是了解一些设计模式对写出优秀代码还是非常有帮助的。

      在写大型项目时,尤其是底层代码、开源框架等时,设计模式的优势将更加突出。

  • 相关阅读:
    首页三级菜单显示
    mysql引擎(转)
    nginx配置虚拟主机
    macos10.9 配置nginx,php-fpm
    排序算法 java实现
    Struts清楚session方法
    No result defined for action and result input的错误
    java throw throws
    try catch finally中return语句与非return语句的执行顺序问题
    java操作Excel
  • 原文地址:https://www.cnblogs.com/xiugeng/p/10374102.html
Copyright © 2011-2022 走看看