1.2 什么是编程范式
-
结构化编程(structured programming) -
面向对象编程(object-oriented programming) -
函数式编程(functional programming)
-
起初是非结构化编程,指令(goto指令)可以随便跳转,数据可以随便引用。后来有了结构化编程,人们把 goto 语句去掉了,约束了指令的方向性,过程之间是单向的,但数据却是可以全局访问的; -
后来面向对象编程的时候,人们干脆将数据与其紧密耦合的方法放在一个逻辑边界内,约束了数据的作用域,靠关系来查找; -
到函数式编程的时候,人们约束了数据的可变性,通过一系列函数的组合来描述数据,从源到目标映射规则的编排,中间它是无状态的;
1.3 什么是多态特性
-
封装即信息隐藏或数据保护,“数据结构"通过暴露有限的访问接口,授权外部仅能通过"数据结构"提供的方法(函数)来访问其内部的数据; -
继承的好处是可以实现代码复用,但不应过度使用,如果继承的层次过深就会导致代码可读性和可维护性变差。因此建议少用继承而多用组合模式; -
多态可以分为变量的多态,方法的多态,类的多态。通常强调的是类的多态,多态的实现是指子类可以替换父类,在实际代码运行过程中调用子类的方法实现;
class MyFile:
def write(self):
print('I write a message into file.')
class MyDB:
def write(self):
print('I write data into db. ')
def doIt(writer):
writer.write()
def demo():
myFile= MyFile()
myDB = MyDB()
doIt(myFile)
doIt(myDB )
2.1 了解架构模式
2.2 了解设计模式
-
创建型模式:用于创建对象,就是将对象的创建与使用分离。从而降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。 -
结构型模式 :描述如何将类,对象,接口之间按某种布局组成更大的结构。 -
行为型模式 :用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
-
架构模式更像是宏观战略层面的设计,设计模式则更像是战略目标拆解出来的具体任务的实现方案; -
软件架构是软件的一种搭建形式,往往规定了软件的模块组成,通信接口(含通信数据结构),组件模型,集成框架等,往往规定了具体的细节; -
设计模式是一种软件的实现方法,是一种抽象的方法论,是为了更好地实现软件而归纳出来的有效方法; -
实现一种软件架构,不同组成部分可能用到不同的设计模式,某个部分也可能可以采用不同的设计模式来实现;
3.1 适用场景
3.2 场景案例
-
用工厂模式隔离业务实现; -
用策略模式消解业务流程分支; -
用模板方法模式提取业务分支公共流程; -
用建造者模式简化入参对象的构建难度; -
用代理模式横向扩展通用能力(日志,异常处理); -
用职责链模式对请求进行敏感词,防刷校验; -
用命令模式让指令拥有了记忆;
工厂模式
// 贫困潦倒产生的和尚过程:1.大山里;2.闹饥荒;3.要吃饭;
一号和尚 = HeShangFactoty.getOneHeshang("贫困潦倒型");
// 走投无路产生的和尚过程:1.生性耿直;2.打死恶霸;3.要赎罪;
二号和尚 = HeShangFactoty.getOneHeshang("走投无路型");
// 天选之子产生的和尚过程:1.敏而好学;2.佛学感兴趣;3.要广大佛法;
三号和尚 = HeShangFactoty.getOneHeshang("天选之子型");
public interface Waterable {
Water getWater();
}
public class TiaoShui implements Waterable{
public Water getWater(){
System.out.println("先到山下去!");
return "水是挑上来的!";
}
}
public class TaiShui implements Waterable{
public Water getWater(){
System.out.println("先到山下去!");
return "水是抬上来的!";
}
}
public class DengShui implements Waterable{
public Water getWater(){
System.out.println("就坐在原地!");
return "水是等不来的!";
}
}
public class Factory {
/**
* 按照和尚数量生成取水对象
*
* @param heShangNum 和尚数量
* @return
*/
public static Waterable getWaterable(Integer heShangNum) {
switch (heShangNum) {
case 1:
return new TiaoShui();
case 2:
return new TaiShui();
case 3:
return new DengShui();
default:
throw new RuntimeException("庙小,装不下那么多和尚!");
}
}
}
策略模式
/**
* 通过入参和尚人数,就可以动态改变Waterable.getWater()的取水模式
* @param heShangNum
* @return
*/
public void getWater(Integer heShangNum) {
Waterable waterable = Factory.getWaterable(heShangNum);
Water water = waterable.getWater();// 取水
}
-
输入参数1:挑水模式的实现(对应Tiaoshui实现类); -
输入参数2:抬水模式的实现(对应Taishui实现类); -
输入参数3:等不到水模式的实现(对应Dengshui实现类);
模板方法
-
拿起工具(扁担或者木棍); -
到寺庙南面的小河边(步行); -
装满水带回寺庙(挑水,抬水,等水) ;
public interface Waterable {
Water getWater();
}
public abstract class AbstractWaterable implements Waterable {
@Override
public Water getWater() {
takeTool();
toRiver();
return moveWater();
}
/**
* 拿起工具
*/
protected abstract String takeTool();
/**
* 到河边去
*/
protected String toRiver() {
System.out.println("走过去!");
return "步行";
}
/**
* 将水带回来
*
* @return
*/
protected abstract Water moveWater();
}
public class TiaoShui extends AbstractWaterable {
protected String takeTool() {
return "扁担";
}
protected Water moveWater() {
return "挑水";
}
}
public class Taishui extends AbstractWaterable{
protected String takeTool() {
return "木棍";
}
protected Water moveWater() {
return "抬水";
}
}
public class DengShui extends AbstractWaterable{
protected String takeTool() {
return "意念";
}
protected String toRiver() {
return "一动不动";
}
protected Water moveWater() {
return "无水";
}
}
/**
* 和尚取水:实现一个和尚挑水喝,两个和尚抬水喝,三个和尚等水喝
*/
public void fetchWater(){
//
for (int heShangNum = 1; heShangNum < 4; heShangNum++) {
Waterable waterable = Factory.getWaterable(heShangNum);
Water water = waterable.getWater();
}
}
建造者模式
public class ToolBox {
private final String bianDan;
private final String muTong;
private final String muGun;
private ToolBox(TiaoBuilder builder){
this.bianDan=builder.bianDan;
this.muTong=builder.muTong;
this.muGun = null;
}
private ToolBox(TaiBuilder builder){
this.bianDan = null;
this.muTong = null;
this.muGun=builder.muGun;
}
private ToolBox(DengBuilder builder){
this.bianDan = null;
this.muTong = null;
this.muGun=null;
}
public static class TiaoBuilder{
private String bianDan;
private String muTong;
public TiaoBuilder setBianDan(String bianDan) {
this.bianDan = bianDan;
return this;
}
public TiaoBuilder setMuTong(String muTong) {
this.muTong = muTong;
return this;
}
public ToolBox build(){
return new ToolBox(this);
}
}
public static class TaiBuilder{
private String muGun;
private String muTong;
public TaiBuilder setMuGun(String muGun) {
this.muGun = muGun;
return this;
}
public TaiBuilder setMuTong(String muTong) {
this.muTong = muTong;
return this;
}
public ToolBox build(){
return new ToolBox(this);
}
}
public static class DengBuilder{
public ToolBox build(){
return new ToolBox(this);
}
}
//省略getter方法
}
ToolBox oneHeShangToolBox = new ToolBox.TiaoBuilder().setMuTong("小号木桶").setBianDan("小号扁担").build();
ToolBox twoHeShangToolBox = new ToolBox.TaiBuilder().setMuTong("大号木桶").setMuGun("长号木棍").build();
ToolBox threeHeShangToolBox = new ToolBox.DengBuilder().build();
代理模式
public class WaterableProxy implements Waterable{
/**
* 被代理的原始对象
*/
private Waterable waterable;
public WaterableProxy(Waterable waterable) {
this.waterable = waterable;
}
public Water getWater() {
Water water = waterable.getWater();
// 增强的新功能,不管是挑水,抬水,等水,只有带回来水,就可以
if(water != "无水"){
System.out.println("我敲一下木鱼,打一次卡!");
}
return water;
}
}
public void doProxy(){
Waterable waterable = new Taishui();
WaterableProxy proxyWaterable = new WaterableProxy(waterable);
proxyWaterable.getWater();
}
责任链模式
-
禁止携带宠物; -
衣着穿戴整齐; -
其它业障,最终解释权归寺庙;
public interface SecureFilter {
void filter(Map context);
}
public class PetSecure implements SecureFilter{
public void filter(Map context) {
if(context.containsKey("宠物")){
throw new RuntimeException("请出去:禁止携带宠物进入!");
}
}
}
public class WearSecure implements SecureFilter{
public void filter(Map context) {
if(context.containsKey("光膀子")){
throw new RuntimeException("请出去:有伤风化者!");
}
}
}
public class OtherSecure implements SecureFilter{
public void filter(Map context) {
if(context.containsKey("大声喧哗")){
throw new RuntimeException("请出去:佛门乃清净之地!");
}
}
}
/**
* 安检责任链实现
*/
class SecureChain implements SecureFilter{
// 注入PetSecure,WearSecure,OtherSecure等过滤器
private List<SecureFilter> secureFilterList;
/**
* 进入寺庙,进行安检逻辑
* @param context
*/
public void filter(Map context) {
// 进行安检流程
for (SecureFilter secureFilter : secureFilterList) {
secureFilter.filter(context);
}
System.out.println("佛祖保佑,安检通过!");
}
}
命令模式
-
一号和尚做早餐; -
二号和尚扫庭院; -
三号和尚敲古钟;
public class Command implements Serializable {
// 做早餐,打扫,敲钟等指令标识
private OrderTypeEnum order;
// 正向执行OR逆向回滚
private Integer direction;
// 省略get和set方法
}
// 指令动作执行器,每种指令对应一个实现
public interface OrderHandler {
/**
* 执行逻辑
*
* @param callContext
* @return
*/
PipeResult execute(CallContext callContext);
/**
* 支持的命令类型:做早餐,打扫,敲钟等命令标识
*
* @return
*/
OrderTypeEnum getOrderType();
}
// 指令类型管理器
public interface PipelineCmd {
/**
* 指令行定义
*
* @return
*/
Command getCommand();
/**
* 执行逻辑
*
* @param pipeContext
* @return
*/
PipeResult execute(PipeContext pipeContext);
/**
* 如果可以撤消指令,则此方法应返回true ,否则返回false
*
* @return
*/
default boolean isReversible() {
return true;
}
}
// 指令执行器管理器
public interface CmdHandler {
/**
* 业务执行
*
* @param callContext
* @return
*/
PipeResult execute(CallContext callContext);
/**
* 业务回滚(只回滚当前指令)
*
* @param callContext
* @return
*/
PipeResult rollback(CallContext callContext);
/**
* 全部回滚
*
* @param pipeContext
* @return
*/
PipeResult rollbackAll(PipeContext pipeContext);
}
public class ZhuChiCmd implements PipelineCmd {
private Command command;
private transient OrderHandler orderHandler;
public StepCmd(Command command, OrderHandler orderHandler) {
this.command = command;
this.orderHandler= orderHandler;
}
public PipeResult execute(PipeContext pipeContext) {
return orderHandler.execute(new CallContext(command, pipeContext));
}
// 省略get和set方法
}
public class Breakfast implements OrderHandler {
/**
* 执行逻辑
*
* @param callContext
* @return
*/
PipeResult execute(CallContext callContext){
System.out.println("做早餐啦!");
}
/**
* 支持的指令类型:做早餐,打扫,敲钟等指令标识
*
* @return
*/
OrderTypeEnum getOrderType(){
return OrderTypeEnum.BREAKFAST;
}
}
public class Clean implements OrderHandler {
/**
* 执行逻辑
*
* @param callContext
* @return
*/
PipeResult execute(CallContext callContext){
System.out.println("打扫庭院啦!");
}
/**
* 支持的指令类型:做早餐,打扫,敲钟等命令标识
*
* @return
*/
OrderTypeEnum getOrderType(){
return OrderTypeEnum.CLEAN;
}
}
public class Ring implements OrderHandler {
/**
* 执行逻辑
*
* @param callContext
* @return
*/
PipeResult execute(CallContext callContext){
System.out.println("敲钟啦!");
}
/**
* 支持的命令类型:做早餐,打扫,敲钟等指令标识
*
* @return
*/
OrderTypeEnum getOrderType(){
return OrderTypeEnum.Ring;
}
}
public class CmdFactory {
private List<OrderHandler> orderHandlerList;
/**
* 获取指定指令条件的指令对象
*
* @param command
* @return
*/
public PipelineCmd getPipelineCmd(Command command) {
for (OrderHandler orderHandler : orderHandlerList) {
OrderTypeEnum orderTypeEnum = orderHandler.getOrderType();
if (orderTypeEnum.equals(command.getOrder())) {
return new ZhuChiCmd(command, orderHandler);
}
}
throw new RuntimeException("对不起主持:没有多余的和尚来执行新命令了!");
}
/**
* 获取给定指令的回滚操作指令对象
*
* @param command
* @return
*/
public PipelineCmd getRollbackPipelineCmd(Command command) {
Command rollbackCommand = getRollbackCommand(command);
return getPipelineCmd(rollbackCommand);
}
}
public class CmdHandlerImpl implements CmdHandler {
private CmdFactory cmdFactory;
public PipeResult execute(CallContext callContext) {
PipelineCmd pipelineCmd = cmdFactory.getPipelineCmd(callContext.getCommand());
PipeResult pipeResult = pipelineCmd.execute(callContext.getPipeContext());
return pipeResult;
}
public PipeResult rollback(CallContext callContext) {
Command rollbackCommand = cmdFactory.getRollbackCommand(callContext.getCommand());
if (rollbackCommand == null) {
return new PipeResult("不需要回滚");
}
PipelineCmd pipelineCmd = cmdFactory.getPipelineCmd(rollbackCommand);
if (!pipelineCmd.isReversible()) {
return new PipeResult("不支持回滚");
}
PipeResult pipeResult = pipelineCmd.execute(callContext.getPipeContext());
return pipeResult;
}
public PipeResult rollbackAll(PipeContext pipeContext) {
// 命令执行备忘录模式对象,这里不再展开
Caretaker<Command> caretaker = pipeContext.getCaretaker();
// 拿到上一步执行命令,依次循环回滚
Command command = caretaker.pop();
while (command != null) {
PipelineCmd pipelineCmd = cmdFactory.getRollbackPipelineCmd(command);
if (pipelineCmd != null) {
pipelineCmd.execute(pipeContext);
}
command = caretaker.pop();
}
return new PipeResult();
}
}
3.3 实践心得
设计原则
模式与原则
-
设计原则是指导思想,设计模式是实现手段之一; -
设计原则在实际开发中并不能做到完全遵守,往往是打破一些原则,遵守一些原则,来实现设计的合理性;(成本,性能) -
设计模式往往是问题解决方案的骨架,有时候可以当做开发规范和任务拆分执行落地的技术手段; -
个设计模式,往往不仅仅采用一种设计原则,而是一些设计原则的整合; -
设计模式不是一成不变的,可以根据问题场景,输出新的模式; -
一个复杂场景问题,有时候需要多种设计模式的组合; -
学设计模式,死记硬背是没用的,要从实践中习得; -
避免设计过度,使简单的问题复杂化。一定要牢记简洁原则,设计模式是为了使设计简单,而不是更复杂;
-end-
本文分享自微信公众号 - 京东云开发者(JDT_Developers)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。