Wetts's blog

Stay Hungry, Stay Foolish.

0%

模板方法模式(Template Method Pattren)

定义:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.(定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。)


抽象模板的方法分为两类:

  • 基本方法:也叫做基本操作,是由子类实现的方法,并且在模板方法被调用。
  • 模板方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。

一般模板方法都加上final关键字,不允许被覆写。


模板方法模式的优点:

  • 封装不变部分,扩展可变部分;
  • 提取公共部分代码,便于维护;
  • 行为由父类控制,子类实现。

模板方法模式的使用场景:

  • 多个子类有公有的方法,并且逻辑基本相同时;
  • 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现;
  • 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。

抽象工厂模式(Abstract Factory Pattern)

定义:Provide an interface for creating families of related or dependent objects without specifying their concrete classes.(为创建一组相关或互相依赖的对象提供一个接口,而且无需指定它们的具体类。)


抽象工厂模式的优点:

  • 封装性;
  • 产品族内的约束为非公开状态。

抽象工厂模式的缺点:
产品族扩展非常困难。

工厂方法模式(Factory Pattern)

定义:Define an interface for creating an object,but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个。工厂方法使一个类的实例化延迟到其子类。)


工厂方法模式的优点:

  • 良好的封装性,代码机构清晰;
  • 工厂方法模式的扩展性非常优秀;
  • 屏蔽产品类;
  • 是典型的解耦框架。

工厂方法模式的扩展:

  1. 缩小为简单工厂模式

一个模块仅需要一个工厂类,没有必要把它生产出来,使用静态的方法就可以了。
简单工厂模式(Simple Factory Pattern),也叫静态工厂模式。

  1. 升级为多个工厂类

复杂的应用中一般采用多工厂的方法,然后再增加一个协调类,避免调用者与各个子工厂交流,协调类的作用是封装子工厂类,对高层模块提供统一的访问接口。
3. 替代单例模式

1
2
3
4
Class cl = Class.forName("");
Constructor constructor = cl.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance();
  1. 延迟初始化

例如定义一个Map容器,容纳所有产生的对象,如果在Map容器中已经有的对象,则直接取出返回;如果没有,则根据需要的类型产生一个对象并放入到Map容器中,以方便下次调用。限制某一个产品类的最大实例化数量,可以通过判断Map中已有的对象数量来实现。

单一模式(SingletonPattern)

定义:Ensureaclasshasonlyinstance,andprovideaglobalpointofaccesstoit.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)


单例模式的优点:

  • 由于单利模式的内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。
  • 由于单利模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多额资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。
  • 单例模式可以避免资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。

单例模式的缺点:

  • 单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。
  • 单例模式对测试是不利的。
  • 单例模式与单一职责原则有冲突。

单例模式的使用场景:

  • 要求生成唯一序列号的环境;
  • 在整个项目中需要一个共享访问点或共享数据;
  • 创建一个对象需要消耗的资源过多;
  • 需要定义大量的静态常量和静态方法的环境。

单例模式的注意事项:

  • 若系统压力增大,并发量增加时则可能在内存中出现多个实例。
  • 需要考虑对象的复制情况。
  • 需要注意JVM的垃圾回收机制。

如何解决单利对象长久不适用被JVM回收的问题:

  • 由容器管理单例的生命周期;
  • 状态随时记录。

开闭原则

定义:Software entities like classes, modules and functions should be open for extension but cloesd for modifications.(一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。)


如何使用开闭原则:

  1. 抽象约束
  2. 元数据(metadata)控制模块行为
  3. 指定项目章程
  4. 封装变化

迪米特法则(Law of Demeter,简称LoD)

也称为最少只是原则(Least Knowledge Principle,简称LKP)

定义:一个对象应该对其他对象有最少的了解。


4层含义:

  1. 只和朋友交流(出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。)
  2. 朋友间也是有距离的
  3. 是自己的就是自己的
  4. 谨慎使用Serializable

核心观念:类间解耦,弱耦合

接口分为两种:

  • 实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实例,它是对一个类型的事物的描述,这是一种接口。
  • 类接口(Class Interface),Java中经常使用的interface关键字定义的接口。

隔离的两种定义:

  • Clients should not be forced to depend upon interaces that they don’t use.(客户端不应该依赖它不需要的接口。)
  • The dependency of one class to another one should depend on the smallest possible interface.(类间的依赖关系应该建立在最小的接口上。)

4层含义:

  1. 接口要尽量小
  2. 接口要高内聚
  3. 定制服务
  4. 接口设计是有限度的

接口隔离原则在实践中可以根据以下几个规则来衡量:

  • 一个接口只服务一个子模块或业务逻辑;
  • 通过业务逻辑压缩接口中的public方法,接口时常去回顾,尽量让接口达到“满身筋骨肉,而不是”肥嘟嘟“的一大堆方法;
  • 已经被污染了的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理;
  • 了解环境,拒绝盲从。

依赖倒置原则(Dependence Inversion Principle,简称DIP)

原始定义:Hign level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.


三层含义:

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
  • 抽象不应该依赖细节;
  • 细节应该依赖抽象。

三层含义在Java语言中的表现为:

  • 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
  • 接口或抽象类不依赖于实现类;
  • 实现类依赖接口或抽象类。

依赖的三种写法:

  1. 构造函数传递依赖对象
  2. Setter方法传递依赖对象
  3. 接口声明依赖对象

实现依赖倒置原则的规则:

  • 每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备;
  • 变量的表面类型尽量是接口或者是抽象类;
  • 任何类都不应该从具体类派生;
  • 尽量不要覆写基类的方法;
  • 结合里氏替换原则使用。

里氏替换原则(Liskov Substitution Principle,简称LSP)

里氏替换原则有两种定义:

  • 第一种定义,也是正宗的定义:If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.(如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。)
  • 第二种定义:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.(所有引用基类的地方必需能透明地使用其他其子类的对象。)

4层含义:

  1. 子类必须完全实现父类的方法
  2. 子类可以有自己的个性
  3. 覆盖或实现父类的方法时输入参数可以被放大
  4. 覆写或实现父类的方法时输出结果可以被缩小

1. 在/etc/init.d/目录下创建脚本

1
vi  /etc/init.d/php-fpm

2. 更改脚本权限

1
chmod 775 /etc/init.d/php-fpm
阅读全文 »