惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
爱范儿
爱范儿
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
博客园 - 司徒正美
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
罗磊的独立博客
阮一峰的网络日志
阮一峰的网络日志
The Register - Security
The Register - Security
D
DataBreaches.Net
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Privacy & Cybersecurity Law Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
B
Blog
V
Vulnerabilities – Threatpost
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
T
Tor Project blog
GbyAI
GbyAI
Recent Announcements
Recent Announcements
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
G
GRAHAM CLULEY
宝玉的分享
宝玉的分享
T
Threat Research - Cisco Blogs
C
Check Point Blog
W
WeLiveSecurity
F
Fortinet All Blogs
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
月光博客
月光博客
Project Zero
Project Zero
Know Your Adversary
Know Your Adversary
V
Visual Studio Blog
H
Help Net Security
H
Hacker News: Front Page
Webroot Blog
Webroot Blog
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
O
OpenAI News
The Cloudflare Blog
Attack and Defense Labs
Attack and Defense Labs

Posts on WKLKEN THINKING

apisix 中的 lrucache apisix 中的服务发现机制 apisix 中的负载均衡 apisix etcd机制 聊聊框架 关于 k8s 的 zero downtime deployment 一些建议 apisix 遇到的一些问题 关于在除夕前一天换了一个洗衣机的故事 Django DRF 性能优化 DRF 的一些实践 Part1: Serializer DRF继承关系图 Better Code: 关于接口的灵活性 新的仓库: wklken/naming 缓存使用的一些经验 Better Code: 抽象: 可扩展性与可维护性的抉择 Better Code: 异常时, 该提示用户哪些信息? Better Code: 更好的异常日志打印 Go: some libs Go: go-redis/cache升级的坑 Go: logrus性能提升 Go: gin validation 远程办公的一点总结 Go: 开发过程中的一些bug 项目管理实践: 风险驱动开发 Go: 一种error wrap调用链处理方式 漫谈技术选型 Go: 基于 apitest 做handler层单元测试 Go: go-sql-driver interpolateparams参数优化 [分享]深度工作 你需要更多的思考时间 Django项目重构小结 工作七年小结: 学习,生活及其他 [分享]bash日常: bash-utils 极客时间推广海报 2017总结: 予时光以意义 k8s APIServer源码: api注册详细细节 k8s APIServer源码: api注册主体流程 k8s APIServer源码: 服务启动 k8s APIServer源码: go-restful框架 重构 - 读书笔记(Python示例) 写给新人的沟通建议 vim 杂谈 - 关于快速编辑 vim 杂谈 - 关于移动 读书笔记-重构: 章11 处理概括关系 读书笔记-重构: 章10 简化函数调用 读书笔记-重构: 章9 简化表达式 读书笔记-重构: 章7 在对象之间搬移特性 读书笔记-重构: 章6 重新组织函数 Python 代码规范小结 [分享]关于vim ElasticSearch集群部署文档 Logstash+ElasticSearch处理mysql慢查询日志 [分享]关于代码调试DE那些事 Logstash+ElasticSearch+Kibana- 实现相对通用的数据收集分析 ELK维护的一些点(二) [分享]Python源码剖析-数据结构 一些Centos Python生产环境的部署命令 摘录<<6个月学会任何一种外语>> ELK 维护的一些点 也许是一个新的开始 一些vim的个性化配置 读书笔记-调试九法 这段时间的一些想法 Python 源码阅读 - 垃圾回收机制 我为什么要写博客 APUE笔记-第一章 UNIX基础知识 Python源码阅读-闭包的实现 Python源码阅读-内存管理机制(二) Python源码阅读-内存管理机制(一) Python-基础-数据结构小结 '活动'设计的一些trick 一些简单的Python测试题 我的tmux配置及说明【k-tmux】 Review and Restart 工作四周年小结 vim插件: surround & repeat[成对符号编辑] vim插件: gundo[时光机] vim插件: expand-region[区域选中] vim插件: quickrun[快速执行] vim插件: trailing-whitespace[行尾空格处理] vim插件: closetag[成对标签补全] vim插件: ctrlp[文件搜索] vim插件: airline[状态栏增强] vim插件: theme[主题] vim插件: tagbar[大纲式导航] vim插件: nerdcommenter[快速注释] vim插件: rainbow_parentheses[括号高亮] vim插件: syntastic[语法检查] vim插件: delimitmate[符号自动补全] vim插件: matchit[成对标签跳转] vim插件: easy-align[快速对齐] vim插件: multiple-cursors[多光标操作] vim插件: vim-signature[快速标记跳转] vim插件: easymotion[快速跳转] vim插件: vundle[管理插件] Elasticsearch几个问题的解决 分享一份 Vim 简介PPT k-vim 更新9.0版本 关于知识管理工具的思考 Logstash+ElasticSearch+Kibana处理nginx访问日志
读书笔记-重构: 章8 重新组织数据
2016-12-03 · via Posts on WKLKEN THINKING

重构的读书笔记, 简单转成python版本的code, 供参考

8.1 Self Encapsulate Field 自封装字段

你直接访问一个字段, 但字段间的耦合关系逐渐变额笨拙. 为这个字段建立取值/设置函数, 并且只以这些函数来访问字段

间接访问的好处是, 可以灵活改变获取数据的途径

class A(object):
    def include(self, arg):
        return self.low < arg < self.high

to

class A(object):
    def include(self, arg):
        return self.low < arg < self.high

    @property
    def low(self):
        return self._low

    @property
    def height(self):
        return self._high

8.2 Replace Data Value with Object 以对象取代数据值

你有一个数据项, 需要与其他数据和行为一起使用才有意义

独立成对象

class Customer(object):
    def__init__(self, name, area_code, number):
        ....

    def get_phone_number(self):
        return "%s-%s" % (self.area_code, self.number)

to

class Phone(object):
    def __init__(self, area_code ,number):
        ....
    @property
    def number(self):
        return "%s-%s" % (self.area_code, self.number)


class Customer(object):
    def__init__(self, name, area_code, number):
        ....

8.3 Change Value to Reference 将值对象改为饮用对象

你从一个类衍生出许多彼此相等的实例, 希望将他们替换为同一个对象. 将这个值对象变成引用对象

# only 4 types, but 10000 A instance
class A(object):
    def __init__(self, type_id, type_name):
        self.type_id = type_id
        self.type_name = type_name

to

class Type(object):
    def __init__(type_id, type_name):
        self.type_id = type_id
        self.type_name = type_name

class A(object):
    def __init__(self, _type):
        self._type = _type

8.4 Change Reference to Value 将引用对象改为值对象

你有一个引用对象, 很小且值不可变, 而且不易管理. 将它变成一个值对象

手法, 将重构目标变成不可变对象. 即, 只有可以变成不可变对象的才能运用这个技巧

class Currency(object):
    def __init__(self, code):
        self.code = code

to

class Currency(object):
    def __init__(self, code):
        self._code = code

    @property
    def code(self):
        return self._code

    def __eq__(self, other):
        return self.code == other.code

8.5 Replace Array with Object 以对象取代数组

你有一个数组, 其中元素各自代表不同的东西. 以对象替换数组, 对于数组中的每个元素, 以一个字段来表示

to

claas Record(object):
    def __init__(self, name, wins):
        self.name = name
        self.wins = wins

record = Record("Liverpoo", 15)

8.6 Duplicate Observed Data 复制"被监视数据"

你有一些领域数据置身于 GUI 控件中, 而领域函数需要访问这些数据. 将数据复制到一个领域对象中. 建立Observer模式, 用以同步领域对象和GUI对象内的重复数据

observer模式, 不解释

8.7 Change Unidirectional Association to Bidirectional 将单向关联改为双向关联

两个类都需要使用对方特性, 但其间只有一条单向连接. 添加一个反向指针, 并使修改函数能够同时更新到两条连接

class Customer(object):
    def get_orders(self):
        # need a lot of codes here

class Order(object):
    def __init__(self):
        pass

    @property
    def customer(self):
        return self._customer
    @customer.setter
    def customer(self, customer):
        self._customer = customer

    def get_customer_address():
        return self._customer.address

to

class Customer(object):
    def __init__(self):
        self.orders = []

    def add_order(self, order):
        self.orders.append(order)

    def get_orders(self):
        return self.orders

class Order(object):
    def __init__(self):
        pass

    @property
    def customer(self):
        return self._customer

    @customer.setter
    def customer(self, customer):
        self._customer = customer
        self._customer.add_order(self)

    def get_customer_address():
        return self._customer.address

8.8 Change Bidirectional Association to Unidirectional 将双向关联改为单向关联

两个类之间有双向关联, 但其中一个类如今不再需要另一个类的特性了

上面的例子, 如果Customer不再需要get_orders. 则可以去掉双向连接, 防止僵尸对象出现

8.9 Replace Magic Number with Symbolic Constant 以字面常量取代魔法数

你有一个字面数值, 带有特别含义. 创建一个常量, 根据其意义为它命名, 并将上述字面数值替换为这个常量

def potential_energy(mass, height):
    return mass * 9.81 * height

to

GRAVITATIONAL_CONSTANT = 9.81
def potential_energy(mass, height):
    return mass * GRAVITATIONAL_CONSTANT * height

8.10 Encapsulate Field 封装字段

你的类中存在一个public字段, 将它声明为private, 并提供相应访问函数

class A(object):
    def __init__(self, value):
        self.value = value

to

class A(object):
    def __init__(self, value):
        self.__value = value

    @property
    def value(self):
        return self.__value

    @value.setter
    def value(self, v):
        self.__value = v

8.11 Encapsulate Collection 封装集合

有个函数返回一个集合. 让这个函数返回该集合的一个只读副本, 并在这个类中提供添加/移除集合元素的函数

class A(object):
    def __init__(self):
        self._members = []
    def get_members(self):
        return self._members

to

class A(object):
    def __init__(self):
        self._members = []
    def get_members():
        return tuple(self._members)

    def add_member(self, member):
        self.members.append(member)

    def remove_member(self, member):
        self.members.remove(member)

8.12 Replace Record with Data Class 以数据类取代记录

你需要面对传统编程环境中的记录结构. 为该记录创建一个"哑"数据对象

可能面对的是一个遗留程序, 需要与其记录进行结构交流. 例如从数据库读出来的记录, 接口调用返回数据等

8.13 Replace Type Code with Class 以类取代类型码

类之中有一个类型码, 但它并不影响类的行为. 以一个新的类替换该数值类型码

class Person(object):
    def __init__(self):
        self.O = 0
        self.A = 1
        self.B = 2
        slef.AB = 3

to

class Person(object):
    def __init__(self):
        self.O = BloodGroup.O
        self.A = BloodGroup.A
        self.B = BloodGroup.B
        slef.AB = BloodGroup.AB

8.14 Replace Type Code with Subclasses 以子类取代类型码

你有一个不可变的类型码, 它会影响到类行为. 以子类取代类型码

使用多态来处理, 需要在一个类中使用if-else或者switch来根据类型码做出不同行为的类

class Employee(object):
    def __init__(self):
        self.ENGINEER = 1
        self.SALESMAN = 0

to

class Employee(object):
    def __init__(self):
class Engineer(Employee):
    pass
class Salesman(Employee):
    pass

8.15 Replace Type Code with State/Strategy 以Stat/Strategy取代类型码

你有一个类型码, 它会影响类的行为, 但你无法通过继承手法消除它. 以状态对象取代类型码

State模式和Strategy模式

8.16 Replace Subclass with Fields 以字段取代子类

你的各个子类的唯一差别只在"返回常量数据"的函数上. 修改这些函数, 使它们返回超类中的某个(新增)字段, 然后销毁子类

class Person(object):
    def is_male(self):
        pass
    def get_code(self):
        pass

class Male(Person):
    def is_male(self):
        return True
    def get_code(self):
        return "M"

class Feale(Person):
    def is_male(self):
        return False
    def get_code(self):
        return "F"

to

class Person(object):
    def is_male(self):
        return self._is_male
    def get_code(self):
        return 'M' if self._is_male else "F"