【非暴力沟通】2

“如果我们通过批评来提出主张,人们的反应常常是申辩或反击。反之,如果我们直接说出需要,其他人就较有可能作出积极的回应。

一旦人们开始谈论需要,而不指责对方,他们就有可能找到办法来满足双方的需要。

以下是一些我们每个人都有的基本需要:
1.自由选择(Autonomy)

选择梦想/目标/方向Choosing dreams/goals/values
自由制定计划来实现这些梦想、目标和方向
Choosing plans for fulfilling one’s dreams, goals, values


2.庆祝(Celebration)
庆祝生命的创造力以及梦想的实现
Celebrate the creation of life and dreams fulfilled
纪念人生的失落:亲人的去世或梦想的破灭等(表达悲伤)
Celebrate losses: loved ones, dreams, etc. mourning

3.言行一致(Integrity)
真诚Authenticity创造Creativity意义Meaning自我肯定Self-worth


4.滋养身体(Physical Nurturance)
空气Air食物Food运动Movement, exercise
免于病毒、细菌、昆虫及肉食性动物的伤害
Protection from life-threatening forms of life:
Viruses, bacteria, insects, Predatory animals
休息Rest住所Shelter触摸Touch水Water


5.玩耍(Play)
乐趣Fun欢笑Laughter


6.情意相通(Spiritual Communion)
美Beauty和谐Harmony激励Inspiration秩序Order平静Peace


7.相互依存(Interdependence)
接纳Acceptance欣赏Apprecation亲密关系Closeness社区Com-munity体贴Consideration成长Contribute to the enrichment of life
安全感Emotional Safety倾听Empathy
诚实(诚实使我们能够认识和超越自己的局限性)
Honesty(the empowering honesty that enables us to learn from our limi-tations)
爱Love信心Reassurance尊重Respect支持Support信任Trust理解Understanding


非暴力沟通把需要看作是有助于生命健康成长的要素,而不是某种具体的行为。一种要素是否被当作需要,关键在于它能否促进生命的健康成长。”

《重构》读后感(第十二章)

第十二章:处理继承关系

一、函数上移
动机:
避免重复代码是很重要的。

如果某个函数在各个子类中的函数体都相同,这就是显而易见的函数上移适合场景。

具体展现:

// 重构前
class Employee { ... }

class Salesman extends Employee {
    get name() { ... } 
}

class Enginner extends Employee {
    get name() { ... }
} 

// 重构后
class Employee { 
    get name() { ... } 
}

class Salesman extends Employee { ... } 
class Enginner extends Employee { ... }

二、字段上移
动机:
其实跟函数上移一样,只不过变成了重复的特性或字段等。

具体展现:

// 重构前
class Employee  { ... } // Java

class Salesman extends Employee {
    private String name;    
}

class Enginner extends Employee {
    private String name;    
} 

// 重构后
class Employee { 
    private String name;    
}

class Salesman extends Employee { ... } 
class Enginner extends Employee { ... }

三、构造函数本体上移
动机:
构造函数是很奇妙的东西。它们不是普通函数,使用它们比使用普通函数受到更多的限制。它们附加了特殊的规则,对一些做法与函数的调用次序有所限制。
如果构造过程过于复杂,可以考虑以工厂函数取代构造函数。

具体展现:

// 重构前
class Party { ... } 

class Employee extends Party {
    constructor(name, id, monthlyCost) {
        super();
        this._id = id;
        this._name = name;
        this._monthlyCost = monthlyCost;
    }
}

// 重构后
class Party { 
    constructor(name) {
        this._name = name;
    }
} 

class Employee  extends Party {
    constructor(name, id, monthlyCost) {
        super(name);
        this._id = id;
        this._monthlyCost = monthlyCost;
    }
}

四、函数下移
动机:
如果超类中的某个函数只与一个(或少于几个)子类有关,那么最好将其从超类中移走,放到真正关心它的子类中去。

具体展现:

// 重构前
class Employee { 
    get quota() { ... } 
}

class Enginner extends Employee { ... }
class Salesman extends Employee { ... } 

// 重构后
class Employee { ... } 

class Enginner extends Employee { ... }
class Salesman extends Employee { 
    get quota() { ... } 
} 

五、字段下移
动机:
同上。

具体展现:

// 重构前
class Employee { //Java
    protected String quota;
}

class Enginner extends Employee { ... }
class Salesman extends Employee { ... } 

// 重构后
class Employee { ... } 
class Enginner extends Employee { ... }

class Salesman extends Employee { 
    protected String quota;
} 

六、以子类取代类型码
动机:
表现分类关系的第一种工具是类型码字段——根据具体的编程语言,可以分为枚举、符号、字符串或者数字。大多数时候,有这样的类型码就足够了。但也有些时候,我们可以更进一步,引入子类。继承有两个诱人之处:一是,可以用多态来处理条件逻辑。二是,有些字段或函数只对特定的类型码取值才有意义。

具体展现:

// 重构前
class createEmployee(name, type) { 
    return new Emplpyee(name, type);
}

// 重构后
function createEmployee(name, type) {
    switch (type) {
        case "engineer": return new Engineer(name);
        case "salesman": return new Salesman(name);
        case "manager":  return new Manager(name);
    }
}

七、移除子类
动机:
随着软件的演化,子类所支持的变化可能会被搬移到别处,甚至完全去除,这时子类就失去了价值。子类存在着就有成本,阅读者需要花心思去理解它的用意,所以如果子类的用处太少,就不值得存在,此时最好的选择就是移除子类,将其替换为超类中的一个字段。

具体展现:

// 重构前
class Person { 
    get genderCode() { return "X"; }
}
class Male extends Person { 
    get genderCode() { return "M"; }
}
class Female extends Person { 
    get genderCode() { return "F"; }
}

// 重构后
class Person { 
    get genderCode() { return this._genderCode; }
}

八、提炼超类
动机:
如果看到两个类在做相似的事,可以利用基本的继承机制把他们的相似之处提炼到超类。
很多时候合理的继承关系是在程序演化的过程中才浮现出来的:我发现了一些共同元素,希望把它们抽取到一处,于是就有了继承关系。

具体展现:

// 重构前
class Department { 
    get totalAnnualCost() { ... }
    get name() { ... }
    get headCount() { ... }
}

class Employee { 
    get annualCost() { ... }
    get name() { ... }
    get id() { ... }
}

// 重构后
class Party {
    get name() { ... }
    get annualCost() { ... }
}

class Department extends Party { 
    get annualCost() { ... }
    get headCount() { ... }
}

class Employee extends Party { 
    get annualCost() { ... }
    get id() { ... }
}

九、折叠继承体系
动机:
在重构类继承体系时,我们经常把函数和字段上下移动。随着继承体系的演化,我们有时会发现一个类与其超类已经没有多大差别,不值得再作为独立的类存在。此时就可以把超类和子类合并起来。

具体展现:

// 重构前
class Employee { ... }
class Salesman extends Employee { ... }

// 重构后
class Employee { ... }

十、以委托取代子类
动机:
继承也有其短板。最明显的是:继承这张牌只能打一次。例如:可以是“年轻人”或“老人”、“富人”或“穷人”,但不能同时采用两种继承方式。另外更大的问题在于继承给类之间引入了非常紧密的关系。在超类上的任何修改,都很可能会破坏子类。

这两个问题,委托都能解决。委托是对象之间常规的关系。与继承关系相比,使用委托关系时接口更清晰、耦合更少。

具体展现:

// 重构前
class Order { 
    get daysToShip() {
        return this._warehouse.daysToShip;
    }
}

class PriorityOrder extends Order {
    get daysToShip() {
        return this._priorityPlan.daysToShip;
    }
}

// 重构后
class Order { 
    get daysToShip() {
        return (this._priorityDelegate)
            ? this._priorityDelegate.daysToShip;
            : this._warehouse.daysToShip;
    }
}

class PriorityOrderDelegate {
    get daysToShip() {
        return this._priorityPlan.daysToShip;
    }
}

十一、以委托取代超类
动机:
如果超类的一些函数对子类并不使用,就说明我们不应该通过继承来获得超类的功能。
合理的继承关系还有一个重要特征:子类的所有实例都应该是超类的实例,通过超类的接口来使用子类的实例应该完全不出问题。
其实这个重构方法跟上边那个“以委托取代子类”本质上是一样的,只不过取代的对象是超类中不适合子类的内容。

具体展现:

// 重构前
class List { ... }
class Stack extends List { ... }

// 重构后
class Stack { 
    constructor() {
        this._storage = new List();
    }
}
class List { ... }