面向对象前戏

Posted ycmyay

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象前戏相关的知识,希望对你有一定的参考价值。

前言

面向对象对于初学者而言是一个非常抽象的东西,直接讲解晦涩难懂,浅尝辄止!

要想畅通无阻的开启它的学习之路,需要学者们先跟着Jason老师一起先来编写一个有趣的案例>>>:人狗大战

案例

步骤1:模拟事物

既然是人狗大战,那肯定得有人和狗啊,目前我们学会的能够比较精确的描述出人和狗的只能是python基本数据类型里面的字典了

# 一个字典表示一人或一狗
dog1 = 
     \'name\': \'小黑\',   
     \'type\': \'田园犬\',  
     \'attack_val\': 30,
     \'life_val\': 200
 
person1 = 
     \'name\': \'小龙\',
     \'type\': \'猛男\',
     \'attack_val\': 10,
     \'life_val\': 1000
 

步骤2:函数封装

程序中人和狗都可以无限创建,如果每次都写上述字典的话那么代码过于冗余,所以我可以封装出两个函数专门用于创建人和狗

def get_person(name, gender, age, t_type, attack_val, life_val):
  	 \'\'\'创建人的函数\'\'\'
     data_dict = 
         \'name\': name,
         \'gender\': gender,
         \'age\': age,
         \'type\': t_type,
         \'attack_val\': attack_val,
         \'life_val\': life_val
     
     return data_dict 
def get_dog(name, t_type, attack_val, life_val):
  	 \'\'\'创建狗的函数\'\'\'
     data_dict = 
         \'name\': name,
         \'type\': t_type,
         \'attack_val\': attack_val,
         \'life_val\': life_val
     
     return data_dict

人和狗的数据模拟问题解决了,接下来就应该干仗了,让两者都具备攻击的能力,截至目前位置我们已经养成了条件反射,谈到所谓的具备某项功能、某种能力其实都可以用函数来模拟

步骤3:攻击能力

def dog_attack(dog_obj, person_obj):
    """
    狗咬人功能
    :param dog_obj: 接收一条狗
    :param person_obj: 接收一个人
    """
    # 使用最简答的掉血逻辑  血量减去对方攻击力
    print(\'当前人的血量是:%s\' % person_obj.get(\'life_val\'))
    person_obj[\'life_val\'] -= dog_obj.get(\'attack_val\')
    print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s"""%(dog_obj.get(\'name\'),person_obj.get(\'name\'),dog_obj.get(\'attack_val\'),person_obj[\'life_val\']))
    
def person_attack(person_obj, dog_obj):
    """
    人揍狗功能
    :param person_obj: 接收一个人
    :param dog_obj: 接收一条狗
    """
    print(\'当前狗的血量是:%s\'%dog_obj.get(\'life_val\'))
    dog_obj[\'life_val\'] -= person_obj.get(\'attack_val\')
    print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s"""%(person_obj.get(\'name\'),dog_obj.get(\'name\'),person_obj.get(\'attack_val\'),dog_obj[\'life_val\']))

步骤4:皇城PK

人和狗的数据有了,各自攻击的功能也有了,接下来就可以一较高下了

p1 = get_person(\'jason\', \'male\', 18, \'猛男\', 800, 1000)
p2 = get_person(\'kevin\', \'female\', 28, \'淑女\', 5, 100)
dog1 = get_dog(\'小黑\', \'松狮犬\', 300, 500)
dog2 = get_dog(\'小白\', \'泰迪犬\', 50, 200)
# 狗咬人
dog_attack(dog2,p1)
print(p1)
# 人揍狗
person_attack(p2, dog1)
print(dog1)

步骤5:黑白颠倒

我们模拟的数据与功能彼此是独立的,也就意味着攻击的函数双方可以随意调用

\'\'\'人调用了狗的攻击动作\'\'\'
dog_attack(p1, dog1)
\'\'\'狗调用了人的攻击工作\'\'\'
person_attack(dog2,p2)

步骤6:数据与功能绑定

我们想让人和狗各自只能调用各自攻击的功能>>>:函数嵌套

def get_person(name, gender, age, t_type, attack_val, life_val):
    # 将人的攻击动作放在产生人的函数内
    def person_attack(person_obj, dog_obj):
        print(\'当前狗的血量是:%s\' % dog_obj.get(\'life_val\'))
        dog_obj[\'life_val\'] -= person_obj.get(\'attack_val\')
        print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
        person_obj.get(\'name\'), dog_obj.get(\'name\'), person_obj.get(\'attack_val\'), dog_obj[\'life_val\']))
        
    data_dict = 
        \'name\': name,
        \'gender\': gender,
        \'age\': age,
        \'t_type\': t_type,
        \'attack_val\': attack_val,
        \'life_val\': life_val,
        \'person_attack\':person_attack
    
    return data_dict
  
def get_dog(name, t_type, attack_val, life_val):
  	# 将狗的攻击动作放在产生狗的函数内
    def dog_attack(dog_obj, person_obj):
        print(\'当前人的血量是:%s\' % person_obj.get(\'life_val\'))
        person_obj[\'life_val\'] -= dog_obj.get(\'attack_val\')
        print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
        dog_obj.get(\'name\'), person_obj.get(\'name\'), dog_obj.get(\'attack_val\'), person_obj[\'life_val\']))
        
    data_dict = 
        \'name\': name,
        \'t_type\': t_type,
        \'attack_val\': attack_val,
        \'life_val\': life_val,
        \'dog_attack\':dog_attack
    
    return data_dict
  
p1 = get_person(\'jason\',\'male\',18,\'猛男\',800, 1000)
p2 = get_person(\'kevin\',\'female\',28,\'淑女\',10,100)
dog1 = get_dog(\'小黑\', \'松狮犬\', 300, 500)
dog2 = get_dog(\'小白\', \'泰迪犬\', 50, 200)
p1[\'person_attack\'](p1,dog1)
dog1[\'dog_attack\'](dog1,p2)

总结:思想升华

上述操作其实就是将数据与功能进行绑定,不再是所有的数据都可以调用任意的功能,而这一操作其实就是面向对象的编程思想

编程思想

我们平时听到的面向对象本质其实是一种编程思想大致可以分为两种

  • 面向过程编程
  • 面向对象编程

编程思想之面向过程编程

将程序的执行流程化 即分步操作 分步的过程中解决问题

# eg:注册、登录、结算购物车...
	"""注册:第一步获取用户名 第二步比对用户名数据 ..."""
	"""结算:第一步获取购物车数据 第二步计算钱数   ..."""

ps:过程可以理解成是流水线 面向过程编程可以理解成是在创建一条流水线

编程思想之面向对象编程

核心就是\'对象\'二字 ,对象其实就是一个"容器" 将数据与功能整合到一起,只要是符合上述描述的事物都可以称之为是对象!!!

# eg:
	"""人狗大战中对数据和功能的整合   可以称之为面向对象编程"""
        """模块文件内含有数据和功能函数   可以称之为面向对象编程"""
  ...

仔细的想想会发现python中一切皆对象>>>:都是数据和功能的整合

# eg:
	\'\'\'数据类型:含有数据和对应的内置方法(函数)\'\'\'
  \'\'\'文件对象:含有数据和对应的内置方法(函数)\'\'\'
  ...

设计模式前戏-UML

一、前言

接下来的一段时间我会和大家一起学习GoF23,即设计模式,在学习设计模式之前呢,希望大家可以具备一些前置能力
首先,你要拥有一颗爱学习的心
其次,你应该拥有面向对象的基础,即了解继承、封装、多态的基本概念和使用
最后,也就是本篇文章要讲的内容:UML类图

二、什么是UML

简介

UML是Unified Modeling Language的缩写,中文名称:统一建模语言,是一种为面向对象的系统产品进行说明、可视化和编制文档的一种标准语言,是非专利的第三代建模和规约语言。

三、为什么要学UML

  • UML是面向对象设计的建模工具,独立于任何具体程序设计语言这就可以很好的帮助不同语言开发者对相同产品进行交流和理解

  • UML用于说明、可视化、构建和编写一个正在开发的面向对象的、软件密集系统的制品,可以对整个软件系统有更加直观的认识

    制品可包括在软件开发过程中的模型、流程图、测试用例、源代码等

四、UML分类

4.1 结构式图形

强调系统式建模

  • 静态图:类图、对象图、包图
  • 实现图:组件图、部署图
  • 剖面图
  • 复合结构图

4.2 行为式图形

强调系统模型中触发的事件

  • 活动图
  • 状态图
  • 用例图

4.3 交互式图形

属于行为式图形子集合,强调系统模型中资料流程

  • 通信图
  • 交互概述图
  • 时序图
  • 时间图

五、类图

UML作图,推荐一款在线软件https://www.processon.com/

简介

类图(Class diagram): 用于表示类、接口、实例等之间的静态结构和关系。

作用

  • 在软件工程中,类图是一种静态的结构图,描述了系统的类的集合,类的属性和类之间的关系,可以简化了人们对系统的理解
  • 类图是系统分析和设计阶段的重要产物,是系统编码和测试的重要模型

类图并不只有类,还包括接口、抽象类、实例

类图案例

类图案例
  • 关系包括:继承(Inheritance),实现关系(Realization/Implementation),关联关系(Association),聚合关系(Aggregation),组合关系(Composition),依赖关系(Dependency)
  • 关系表现为继承或实现关系(is a)
  • 关联关系表现为变量(has a),其中关联关系包含:聚合关系(Aggregation),组合关系(Composition)
  • 依赖关系表现为方法中的参数(use a)

六、时序图

简介

时序图(Sequence Diagram):又名序列图、循序图,是一种UML交互图。它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。

元素

角色(Actor)、对象(Object)、生命线(LifeLine)、控制焦点(Activation)、消息(Message)

时序图案例

时序图案例
  • 上方矩形表示类对象,矩形链接的表示生命线(时间从上向下,上面表示已经流逝的时间,下面是未来),表示对象的生命周期
  • 实线尖头(实心箭头表示同步,空心表示异步)表示方法调用
  • 生命线上的矩形表示实例处于右边箭头描述的活动,
  • 空心箭头表示返回数据,右边箭头对应的活动结束

七、总结

  • UML是一种建模语言, ,可以很好的对系统进行可视化构建
  • 类图对于我们后续学习和使用设计模式提供极大的助力,主要需要关注类图之间的关系、以及类图中图形元素含义
  • 时序图主要帮助我们了解一个业务功能的流程,我们常常在使用第三方平台的接口时会见到,理解常规的时序图元素含义,有助于快速学习使用第三方接口


以上是关于面向对象前戏的主要内容,如果未能解决你的问题,请参考以下文章

设计模式前戏-UML

继承初体验

Scrapy源码剖析前戏之Twisted使用

drf 前戏—CBV的使用及源码流程

python-----堡垒机前戏paramiko模块

DRF 视图