
设计模式基础与原则
- 设计模式基础:
    - 抽象
- 封装
- 继承
- 多态
 
- 设计模式的原则
    - 开闭原则(Open Close Principle)
        - 对扩展开放,对修改关闭。想要达到这样的效果,我们需要使用接口和抽象类
 
- 里氏代换原则(Liskov Substitution Principle)
        - 任何基类可以出现的地方,子类一定可以出现
- LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
- 实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
 
- 依赖倒转原则(Dependence Inversion Principle)
        - 针对接口编程,依赖于抽象而不依赖于具体。
 
- 接口隔离原则(Interface Segregation Principle)
        - 降低类之间的耦合度
 
- 迪米特法则,又称最少知道原则(Demeter Principle)
        - 一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
 
- 合成复用原则(Composite Reuse Principle)
        - 尽量使用合成/聚合的方式,而不是使用继承。
 
 
- 开闭原则(Open Close Principle)
        
# mother can only read book, 依赖的具体Book
class Book{
	public String getContent(){
		return "很久很久以前有一个阿拉伯的故事……";
	}
}
class Mother{
	public void narrate(Book book){
		System.out.println("妈妈开始讲故事");
		System.out.println(book.getContent());
	}
}
public class Client{
	public static void main(String[] args){
		Mother mother = new Mother();
		mother.narrate(new Book());
	}
} 
# 依赖接口,方便扩展
interface IReader{
	public String getContent();
} 
class Newspaper implements IReader {
	public String getContent(){
		return "林书豪17+9助尼克斯击败老鹰……";
	}
}
class Book implements IReader{
	public String getContent(){
		return "很久很久以前有一个阿拉伯的故事……";
	}
}
class Mother{
    # 依赖IReader接口,子类(Book,Newspaper可以替换IReader)
	public void narrate(IReader reader){
		System.out.println("妈妈开始讲故事");
		System.out.println(reader.getContent());
	}
}
public class Client{
	public static void main(String[] args){
		Mother mother = new Mother();
		mother.narrate(new Book());
		mother.narrate(new Newspaper());
	}
}
设计模式分类
- 创建型模式:主要用于描述如何创建对象
    - 简单工厂,工厂方法,抽象工厂方法,单例,建造者
 
- 结构型模式:主要用于描述如何实现类或对象的组合
    - 适配,桥接,装饰,外观,享元,代理
 
- 行为型模式:主要用于描述类或对象怎样交互以及怎样分配职责
    - 命令,观察者,中介者,状态,策略
 
具体例子
1. 工厂方法模式(Factory Method Pattern)

import abc
class Leifeng:
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def wash(self):
        """"wash"""
    @abc.abstractmethod
    def sweep(self):
        """sweep"""
    @abc.abstractmethod
    def buy_rice(self):
        """buy rice"""
class Undergraduate(Leifeng):
    def wash(self):
        print "undergraduate wash"
    def sweep(self):
        print "undergraduate sweep"
    def buy_rice(self):
        print "undergraduate buy rice"
class Volunteer(Leifeng):
    def wash(self):
        print "volunteer wash"
    def sweep(self):
        print "volunteer sweep"
    def buy_rice(self):
        print "volunteer buy rice"
class IFactory:
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def CreateLeifeng(self):
        """create class leifeng"""
class UndergraduateFactory(IFactory):
    def CreateLeifeng(self):
        return Undergraduate()
class VolunteerFactory(IFactory):
    def CreateLeifeng(self):
        return Volunteer()
if __name__ == "__main__":
    # create undergraduate to sweep
    i_factory = UndergraduateFactory()
    leifeng = i_factory.CreateLeifeng()
    leifeng.sweep()
    # create volunteer to wash
    i_factory = VolunteerFactory()  # just replace UndergraduateFactory with VolunteerFactory
    leifeng = i_factory.CreateLeifeng()
    leifeng.wash()
2. 单例模式

import threading
class Singleton(object):
    instance = None
    lock = threading.RLock()
    @classmethod
    def __new__(cls):
        if cls.instance is None:
            cls.lock.acquire()
            if cls.instance is None:
                cls.instance = super(Singleton, cls).__new__(cls)
            cls.lock.release()
        return cls.instance
if __name__ == "__main__":
    instance1 = Singleton()
    instance2 = Singleton()
    print id(instance1) == id(instance2)
3. 装饰模式

import abc
class Person:
    def show(self):
        print "person"
class Finery(Person):
    def __init__(self, c):
        self.component = c
    def show(self):
        """finery show"""
class Tie(Finery):
    def show(self):
        print "tie ",
        self.component.show()
class Suit(Finery):
    def show(self):
        print "suit ",
        self.component.show()
class Shoes(Finery):
    def show(self):
        print "shoes ",
        self.component.show()
if __name__ == "__main__":
    person = Person()
    tie = Tie(person)
    suit = Suit(tie)
    shoes = Shoes(suit)
    shoes.show()
4. 观察者模式

import abc
class Observer:
    __metaclass__ = abc.ABCMeta
    def __init__(self, n, nr):
        self.name = n
        self.notifier = nr
    @abc.abstractmethod
    def update(self):
        """updated by notifier"""
class NbaObserver(Observer):
    def update(self):
        print self.name + ", " + self.notifier.state + ", close NBA"
class StockObserver(Observer):
    def update(self):
        print self.name + ", " + self.notifier.state + ", close stock"
class Notifier:
    def __init__(self):
        self.observers = []
        self.state = ""
    def attach(self, o):
        self.observers.append(o)
    def detach(self, o):
        self.observers.remove(o)
    def notify(self):
        for observer in self.observers:
            observer.update()
class Boss(Notifier):
    pass
if __name__ == "__main__":
    boss = Boss()
    nba_observer = NbaObserver("Bob", boss)
    boss.attach(nba_observer)
    stock_observer = StockObserver("Alice", boss)
    boss.attach(stock_observer)
    boss.state = "boss's back himself"
    boss.notify()