设计模式介绍(python)

102 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

设计模式是为了更好的代码重用性,可读性,可靠性,可维护性

设计模式6大原则:

1)单一职责原则

2)里氏替换原则

3)依赖倒转原则

4)接口隔离原则

5)迪米特法则

6)开闭原则

单例设计模式(SINGLETON)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

class Singleton(object):
     def __init__(self):
         pass
 
     def __new__(cls, *args, **kwargs):
         if not hasattr(Singleton, "_instance"): # 反射
             Singleton._instance = object.__new__(cls)
         return Singleton._instance
 
 obj1 = Singleton()
 obj2 = Singleton()
 print(obj1, obj2) #<__main__.Singleton object at 0x004415F0> <__main__.Singleton object at 0x004415F0>

工厂模式(FACTORY METHOD)

定义 一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延伸到其子类。

  • 当一个类不知道它所须创建的对象的类的时候。

  • 当一个类希望由它的子类来指定它所创建的对象的时候。

  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

class Person:
    def __init__(self):
        self.name = None
        self.gender = None

    def getName(self):
        return self.name

    def getGender(self):
        return self.gender

class Male(Person):
    def __init__(self, name):
        print "Hello Mr." + name

class Female(Person):
    def __init__(self, name):
        print "Hello Miss." + name

class Factory:
    def getPerson(self, name, gender):
        if gender == ‘M':
                return Male(name)
        if gender == 'F':
            return Female(name)


if __name__ == '__main__':
    factory = Factory()
    person = factory.getPerson("Chetan", "M")

如果我们新增一个中性人类,那么需要新增一个Person的子类和修改Factory内的getPerson方法,这样就违背了软件设计中的开闭原则,即在扩展新的类时,尽量不要修改原有代码。所有我们在简单工厂的基础上把Factory抽象成不同的工厂,每个工厂对应生产自己的产品,这就是工厂方法。

class Person:
    def __init__(self):
        self.name = None
        self.gender = None

    def getName(self):
        return self.name

    def getGender(self):
        return self.gender

class Male(Person):
    def __init__(self, name):
        print "Hello Mr." + name

class Female(Person):
    def __init__(self, name):
        print "Hello Miss." + name

class Neutral(Person):
    def __init__(self, name):
        print "Hello Mr or Miss." + name



class Factory:
    def getPerson(self, name):
		pass

class FemaleFactory(Factory):
	def getPerson(self.name):
		return Female(name)

class MaleFactory(Factory):
	def getPerson(self.name):
		return Male(name)

class NeutralFactory(Factory):
	def getPerson(self.name):
		return Neutral(name)

建造者模式(BUILDER)

将一个复杂对象的构建与它表示分离,使得同样的构建过程可以创建不同的表示。

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

  • 当构造过程必须允许被构造的对象有不用的表示时。

package com.colorv.lotterydraw.v2.blackbox;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import lombok.Data;

@Data
public class LotteryBody {
    private String activeName;
    private Long userId;
    private Long activeId;
    private String property;

    private LotteryBody(Builder builder){
        this.activeName = builder.activeName;
        this.userId = builder.userId;
        this.activeId = builder.activeId;
        this.property = builder.property;
    }

    @Override
    public String toString() {
        return "LotteryBody{" +
                "userId=" + userId +
                ", activeName='" + activeName + '\'' +
                ", activeId=" + activeId +
                ", property" + property +
                '}';
    }

    public static class Builder{
        private String activeName;
        private Long userId;
        private Long activeId;
        private String property = "";

        public LotteryBody build(){
            Preconditions.checkArgument(!Strings.isNullOrEmpty(activeName), "invalid argument active_name");
            Preconditions.checkArgument(userId != null && userId.intValue() > 0, "invalid argument user_id");
            Preconditions.checkArgument(activeId != null && activeId.intValue() > 0, "invalid argument user_id");
            return new LotteryBody(this);
        }

        public Builder activeName(String activeName){
            this.activeName = activeName;
            return this;
        }

        public Builder userId(Long userId){
            this.userId = userId;
            return this;
        }
        public Builder activeId(Long activeId){
            this.activeId = activeId;
            return this;
        }
        public Builder property(String property){
            this.property = property;
            return this;
        }
    }
}