关于c:新手必须要注意的编程范式

48次阅读

共计 7117 个字符,预计需要花费 18 分钟才能阅读完成。

编程语言
与成百种编程语言(Programming Language)相比,编程范式(Programming Paradigm、范式)要少得多。

如图所示,共有 27 种范式。少数范式之间仅相差一个或几个概念。

次要的范式
最罕用的范式有三个:过程试编程,面向对象编程(OOP),函数式编程(FP)。而后咱们介绍一下新兴的第四种范式也就是面向切面编程(AOP)。

过程试编程
过程式编程(Procedural programming)的外围在于模块化,在实现过程中应用了状态,依赖了内部变量,导致很容易影响左近的代码,可读性较低,前期的保护老本也较高。

过程试编程经验了倒退的两个阶段,非结构化到结构化:

非机构化编程(Unstructured programming):机器语言和汇编语言的编程范式被认为是非结构化编程,没有封装函数的概念,代码中 goto 语句满天飞的状态。

结构化编程(Structured programming):形象了机器的行为,屏蔽了局部计算机的硬件细节。代表语言就是咱们罕用的 C 语言。

有时结构化编程,也称作过程式编程,或面向过程编程。

def get_shannon_info(output):

"""获取 shannon 类型 flash 卡信息"""

def check_health():
    time_left = float(sub_info["life_left"])
    if time_left < DISK_ALARM_LIFETIME:
        message = "time left is less than {}%".format(DISK_ALARM_LIFETIME)
        return message
    temperature = float(sub_info["temperature"].split()[0])
    if temperature > DISK_ALARM_TEMPERATURE:
        message = "temperature is over than {} C".format(DISK_ALARM_TEMPERATURE)
        return message
    return "healthy"

http://tags.astro.sina.com.cn…

result = {}
all_info = _get_shannon_info(output)
for info in all_info:
    sub_info = {}
    sub_info["available_capacity"] = info.get("disk_capacity", "")
    sub_info["device_name"] = info.get("block_device_node", "")
    sub_info["firmware_version"] = info.get("firmware_version", "")
    sub_info["interface"] = "PCIe"
    sub_info["life_left"] = str(info.get("estimated_life_left", "").replace("%",""))
    sub_info["pcie_id"] = info.get("pci_deviceid", "")
    sub_info["pcie_length"] = ""sub_info["pcie_type"] =""
    sub_info["physical_read"] = info.get("host_read_data", "")
    sub_info["physical_write"] = info.get("total_write_data", "")
    sub_info["serial_number"] = info.get("serial_number")
    sub_info["temperature"] = info.get("controller_temperature")
    sub_info["type"] = info["type"]
    sub_info["error_msg"] = check_health()
    sub_info["status"] = "ok" if sub_info["error_msg"] == "healthy" else "error"
    if sub_info["serial_number"]:
        result[sub_info["serial_number"]] = sub_info
    else:
        result[sub_info["device_name"]] = sub_info
return result

面向对象编程
面向对象编程(Object-oriented programming)的外围在于形象,提供清晰的对象边界。联合封装、集成、多态个性,升高了代码的耦合度,晋升了零碎的可维护性。C++ 和 之后的 Java 成为支流。

人们将畛域问题又开始映射成实体及关系(程序 = 实体 + 关系),而不再是数据结构和算法(过程)了,这就是面向对象编程,外围特点是封装、继承和多态。
1
class IFlash(six.with_metaclass(abc.ABCMeta)):

def __init__(self):
    pass

@abc.abstractmethod
def collect(self):
    """收集 flash 卡物理信息"""
    pass

class FlashShannon(IFlash):

"""宝存的 Flash 卡"""

def __init__(self, txt_path, command, printer):
    super(FlashShannon, self).__init__()
    self.txt_path = txt_path

    self.command = command
    self.printer = printer

def collect(self):
    result = {}
    for info in self._get_shannon_info():
        life_left = str(info.get("estimated_life_left", "")).replace("%","")
        temperature = info.get("controller_temperature", "")
        error_msg = self._get_health_message(life_left, temperature)
        sub_info = {"available_capacity": info.get("disk_capacity", ""),"device_name": info.get("block_device_node",""),
            "firmware_version": info.get("firmware_version", ""),"interface":"PCIe","life_left": life_left,"pcie_id": info.get("pci_deviceid",""),
            "pcie_length": "","pcie_type":"",
            "physical_read": info.get("host_read_data", ""),"physical_write": info.get("total_write_data",""),
            "serial_number": info.get("serial_number", ""),"temperature": temperature,"type": info["type"],"error_msg": error_msg,"status":"ok"if error_msg =="healthy"else"error"
        }
        if sub_info["serial_number"]:
            result[sub_info["serial_number"]] = sub_info
        else:
            result[sub_info["device_name"]] = sub_info
    return result

http://tags.astro.sina.com.cn…
class FlashFio(IFlash):

"""fio 的 Flash 卡"""

def __init__(self, txt_path):
    super(FlashFio, self).__init__()
    self.txt_path = txt_path

def collect(self):
    disk_info = {}
    adapter_info = self._get_adapter_info()
    for info in adapter_info:
        serial_number = info["fio_serial_number"]
        for io in info["iomemory"]:
            data = self._combining_io_memory(io)
            data["serial_number"] = serial_number
            disk_info[serial_number] = data
    return disk_info

函数式编程
函数式编程(Functional Programming)的外围在于“防止副作用”,不扭转也不依赖以后函数外的数据。联合不可变数据、函数是第一等公民等个性,使函数带有自描述性,可读性较高。

首先,函数式编程的次要实践根底是 Lambda 演算,它是图灵齐备的;其次,函数式编程是抽象代数思维,更加靠近古代自然科学,应用一种形式化的形式来解释世界,通过公式来推导世界,极度形象(比方 F=ma)。在这条路上,很多人都是偏学术格调的,他们关注解决方案是否优雅,如何一层层构建形象。他们也摸索更多的可能,垃圾回收机制就是从这里率先进去的。
1
@pytest.mark.parametrize(“line, result”, [
(“Found Shannon PCIE”, False),
(“Found Shannon PCIE Flash car”, False),
(“Found Shannon PCIE Flash card a”, True),
(“Found Shannon PCIE Flash card”, True),
(“Found Shannon PCIE Flash card.”, True),
])
def test_is_shannon_flash_device(line, result):

assert functional.is_shannon_flash_device(line) == result

@pytest.mark.parametrize(“line, result”, [
(“a=1”, True),
(“b=2”, True),
(“c=2333”, True),
(“d x=abcde”, True),
(“Found Shannon PCIE=1”, True),
(“abcdedfew=”, False),
(“Found Shannon PCIE”, False),
(” =Found Shannon PCIE”, False),
(“=Found Shannon PCIE”, False),
(“Found Shannon PCIE=”, False),
(“Found Shannon PCIE= “, False),
])http://tags.astro.sina.com.cn…
def test_is_effective_value(line, result):

assert functional.is_effective_value(line) == result

@pytest.mark.parametrize(“line, result”, [
(“a=1”, {“a”: “1”}),
(“b=2”, {“b”: “2”}),
(“a=a”, {“a”: “a”}),
(“abc=a”, {“abc”: “a”}),
(“abc=abcde”, {“abc”: “abcde”}),
])
def test_gets_the_index_name_and_value(line, result):

assert functional.gets_the_index_name_and_value(line) == result

@pytest.mark.parametrize(“output, filter_func, result”, [
(“abcd\nbcd\nabcd\nbcd\naa\naa”, lambda x: “a” in x, [“abcd\nbcd”, “abcd\nbcd”, “aa”, “aa”]),
(open(os.path.join(project_path, “fixtures”, “shannon-status.txt”)).read(), functional.is_shannon_flash_device, [

open(os.path.join(project_path, "fixtures", "shannon-sctb.txt")).read(),
open(os.path.join(project_path, "fixtures", "shannon-scta.txt")).read()

])http://tags.astro.sina.com.cn…
])
def test_checks_string_split_by_function(output, filter_func, result):

assert functional.checks_string_split_by_function(output, filter_func) == result

面向切面编程
面向切面编程(Aspect Oriented Programming、AOP)为开发人员提供了一种刻画叙述横切关注点的机制,并能够本人被动将横切关注点织入到面向对象的软件系统中。从而实现了横切关注点的模块化。

AOP 能够将那些与业务无关,却为业务模块所独特调用的逻辑或责任。比方事务处理、日志治理、权限管制等。封装起来,便于升高零碎的重复代码,升高模块间的耦合度,并有利于将来的可操作性和可维护性。

python 能够应用装璜器实现 AOP。
1
次要三种范式的比照

畛域驱动设计
不难看出,编程语言的倒退就是一个逐渐远离计算机硬件,向着待解决的畛域问题凑近的过程。所以,编程语言后续的倒退方向就是摸索怎么更好的解决畛域问题,也就是畛域驱动设计(Domain-driven Design、DDD)。

DDD 的精华是对边界的划分和管制,共有四重边界:

1、第一重边界是在问题空间拆散子域,包含外围域,撑持域和通用域。

2、第二重边界是在解决方案空间拆分 BC(限界上下文,Bounded Context),BC 之间的协作关系通过 Context Mapping(上下文映射)来表白。

3、第三重边界是在 BC 外部拆散业务复杂度和技术复杂度,造成分层架构,包含用户界面层,应用层,畛域层和基础设施层。

4、第四重边界是在畛域层引入聚合这一最小的设计单元,它从完整性与一致性对畛域模型进行了无效的隔离,聚合外部包含实体、值对象、畛域服务、工厂和仓储等设计元素。

设计准则与模式
设计准则很多,程序员最常应用的是 SOLID 准则,它是一套比拟成体系的设计准则。它不仅能够领导咱们设计模块(类),还能够被当作一把尺子,来掂量咱们设计的有效性。

SOLID 准则是五个设计准则首字母的缩写,它们别离是:

繁多职责准则(Single responsibility principle,SRP):一个类应该有且仅有一个变动的起因。

凋谢关闭准则(Open–closed principle,OCP):软件实体(类、模块、函数)应该对扩大凋谢,对批改关闭。

里氏替换准则(Liskov substitution principle,LSP):子类型(subtype)必须可能替换其父类型(base type)。

接口隔离准则(Interface segregation principle,ISP):不应强制使用者依赖于它们不必的办法。

依赖倒置准则(Dependency inversion principle,DIP):高层模块不应依赖于低层模块,二者应依赖于形象;形象不应依赖于细节,细节应依赖于形象。

后面咱们提到,对于面向对象来说,外围是多态的设计,咱们看看 SOLID 准则如何领导多态设计:

繁多职责准则:通过接口拆散变与不变,隔离变动。

凋谢关闭准则:多态的指标是零碎对于变动的扩大而非批改。

里氏替换准则:接口设计要达到细节暗藏的圆满成果。

接口隔离准则:面向不同客户的接口要分来到。

依赖倒置准则:接口的设计和规定者应该是接口的应用办法。

除过设计准则,咱们还要把握罕用的设计模式。设计模式是针对一些普遍存在的问题给出的特定解决方案,使面向对象的设计更加灵便和优雅,从而复用性更好。学习设计模式不仅仅要学习代码怎么写,更重要的是要理解模式的利用场景。不管那种设计模式,其背地都暗藏着一些“永恒的真谛”,这个真谛就是设计准则。确实,还有什么比准则更重要呢?就像人的世界观和人生观一样,那才是摆布你所有行为的基本。能够说,设计准则是设计模式的灵魂。

守破离是武术中一种渐进的学习办法:

第一步 —— 守,遵守规则直到充沛了解规定并将其视为习惯性的事。

第二步 —— 破,对规定进行反思,寻找规定的例外并“突破”规定。

第三步 —— 离,在精通规定之后就会根本脱离规定,抓住其精华和深层能量。

设计模式的学习也是一个守破离的过程:

第一步 —— 守,在设计和利用中模拟既有设计模式,在模拟中要学会思考。

第二步 —— 破,纯熟应用根本设计模式后,发明新的设计模式。

第三步 —— 离,遗记所有设计模式,在设计中耳濡目染的应用。

————————————————

原文链接:http://tags.astro.sina.com.cn…

正文完
 0