设计模式java版 and python版
一、单例模式
在某些情况下,有些对象,我们只需要一个就可以了,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个。
a、java程序
namespace Singleton
{
public class Singleton
{
//定义一个私有的静态全局变量来保存该类的唯一实例
private static Singleton singleton;
/// <summary>
/// 构造函数必须是私有的
/// 这样在外部便无法使用 new 来创建该类的实例
/// </summary>
private Singleton()
{
}
/// <summary>
/// 定义一个全局访问点
/// 设置为静态方法
/// 则在类的外部便无需实例化就可以调用该方法
/// </summary>
/// <returns></returns>
public static Singleton GetInstance()
{
//这里可以保证只实例化一次
//即在第一次调用时实例化
//以后调用便不会再实例化
if (singleton == null)
{
singleton = new Singleton();
}
return singleton;
}
}
}
结论:
单例模式使类在程序生命周期的任何时刻都只有一个实例,然后,单例的构造函数是私有的,外部程序如果想要访问这个单例类的话,必须通过 GetInstance()来请求(注意是请求)得到这个单例类的实例。
b、python程序
1、单例是只有一个实例
2、通过静态字段+静态字段伪造出一个单例效果
3、什么时候用:当所有实例中封装的数据相同时,创建单例模式(eg:连接池)
class CP: __instance = None def __init__(self): self.ip = "1.1.1.1" self.port = 3306 self.pwd = "123123" self.user = "xxx" self.conn_list = [1,2,3,4,5,6] @staticmethod def get_instance(): if CP.__instance: return CP.__instance else: # 创建一个对象,并将对象赋值给静态字段__instance CP.__instance = CP() #执行init方且创建对象,并赋值给私有静态字段 return CP.__instance #将赋值的返回给私有静态字段 obj1 = CP.get_instance() # 静态字段类调用 print(obj1)
二、简单工厂模式
用一句话来说:简单工厂模式用来解决实例化的问题。
例如:存在加法,减法、乘法、除法的类时,当要利用加法时,就需要工厂来对加法类进行实例化,并返回此实例,当要使用乘法,也需要工厂来对乘法类进行实例化,并返回实例。即:对于有选择性的去实例化类的操作都在一个【工厂类】中执行。
下面就看一个工厂类:
java版:
public class OperateFactory { public static Operate GetInstace(string strOperate) { Operate oper = null; switch (strOperate) { case "加法": oper=new OperateAdd(); break; case "减法": oper=new OperateSubtraction(); break; default: oper= null; break; } return oper; } }
python版:
class OperateFactory: oper=None def __init__(self,arg): self.handle(arg) def handle(self,arg): if arg== "加法": oper=OperateAdd() elif arg== "减法": oper=OperateSubtraction() else: oper= None return oper obj=OperateFactory('加法')
注:obj=OperateFactory('加法') 等价于obj=OperateAdd(),因此简单工厂模式相当于集中解决实例化。
三、工厂方法模式
对于上面的简单工厂模式,它利用一个【工厂类】来有选择型的实例化指定的对象(要利用加法类时,传入参数“加法”之后工厂类就会去实例化OperateAdd类,并返回该实例),而对于工厂方法模式来说,他为每个操作类都创建一个工厂类,调用工厂类再来实例化指定对象!
java版:
首先来创建一个接口,来统一各个工厂类的行为
interface IFactory
{
Operation CreateOperation(); //返回值类型为所有操作类的父类
}
public AddFactory:IFactory { public Operation CreateOperation() { return new OperationAdd(); } }
public SubFactory:IFactory { public Operation CreateOperation() { return new OperationSub(); } }
上述这些工厂类都返回给自对应的操作类的实例,当想要利用加法操作时,只需要调用工厂类中的CreateOperation方法即可,那么对于到底该调用那个工厂类的逻辑判断,就需要自己来写了,这一点工厂方法模式和简单工厂模式是不同的!
python版:
python中并没有接口,要实现类似java中的接口功能,我们需要借助抽象类和抽象方法:
from abc import ABCMeta from abc import abstractmethod #导入抽象方法 class Father(metaclass=ABCMeta):#创建抽象类 @abstractmethod def CreateOperation(self):pass
下面的类如果需要使用接口,需要继承father类,并且含有CreateOperation方法。
加法工厂类:
class AddFactory(Father): def __init__(self): self.CreateOperation() def CreateOperation(self):return OperationAdd()
减法工厂类:
class SubFactory(Father): def __init__(self): self.CreateOperation() def CreateOperation(self):return OperationSub()
工厂方法模式与简单工厂模式对比:
1、工厂方法模式需要调用哪一个工厂类,需要用户自己写方法判断,简单工厂模式根据用户传入的参数选择即可。
2、工厂方法模式遵循了 开放-封闭原则,对于工厂方法模式来说,如果要对其进行扩展(添加除法操作),需要添加一个实现IFactory接口的除法工厂类即可,而如果对简单工厂模式进行扩展的话,不仅需要增加操作类,还需要去对工厂类进行逻辑的修改,这么一来就违背了开放-封闭原则。其实,两者本质的差别是因为在工厂方法模式中判断到底调用那一个工厂类的操作抛给了客户端代码来实现,所以在组件的范围内就不需要修改,只扩展即可。
四、策略模式
在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中,通过if…else…或者case等条件判断语句来进行选择。这两种实现方法我们都可以称之为硬编码,如果需要增加一种新的查找算法,需要修改封装算法类的源代码;更换查找算法,也需要修改客户端调用代码。在这个算法类中封装了大量查找算法,该类代码将较复杂,维护较为困难。如果我们将这些策略包含在客户端,这种做法更不可取,将导致客户端程序庞大而且难以维护,如果存在大量可供选择的算法时问题将变得更加严重。
例子1:一个菜单功能能够根据用户的“皮肤”首选项来决定是否采用水平的还是垂直的排列形式。同事可以灵活增加菜单那的显示样式。
例子2:出行旅游:我们可以有几个策略可以考虑:可以骑自行车,汽车,做火车,飞机。每个策略都可以得到相同的结果,但是它们使用了不同的资源。选择策略的依据是费用,时间,使用工具还有每种方式的方便程度 。
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
当存在以下情况时使用Strategy模式
1)• 许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
2)• 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
3)• 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4)• 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。