策略模式:网络小说的固定套路

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

近日小舅子让我推荐几本好看的玄幻小说,下好了发给他。

想当初我唐家三少、天蚕土豆、跳舞等网络作者的小说也没少看,便满口答应了。

百度一搜“唐家三少”,好家伙,几年不见又出了这么多新书,产量惊人啊!把这些小说简介一看,啧啧,还是那个 屌丝逆袭 套路啊。

知乎上唐家三少有人喷有人捧,但有几句说的比较中肯:

因为现在的读者很多都是学生,找部小说来看着激动一下,激动过后呢?再找小说来激动,就这样以此循环,虚度光阴。

也许不能全怪作者,写太好读者看不懂,小学生作文水平刚好能迎合绝大部分读者。

铁打的小说流水的读者,导致了当前网络小说的固定套路,作家只要把故事梗概提取出来,把主角名字、背景什么的一换,就又是一本新书。唉,竟无语凝噎。

这种情况用代码怎么实现呢,我们来试试。

作者:张拭心 http://blog.csdn.net/u011240877

代码实现“如何用固定套路写小说”

1.先定义一个故事梗概接口 Synopsis ,里面设定了主要情节:

  • 不幸的开始
  • 突然有天遇到神人/捡到神器
  • 以弱胜强,暂露光芒
  • 开挂似的升级超快
  • 组团刷怪九死一生(主角怎么也死不了)
  • 功成名就 + 妻妾成群
/*** 网络玄幻小说的故事梗概接口* 固定的一些套路* Created by zhangshixin on 8/27/2016.*/
public interface Synopsis {/*** 穷困潦倒的开始*/void badStart();/*** 突然有天遇到神人/捡到神器,实力大涨*/void adventure();/*** 在一场战斗中以弱胜强*/void winABattle();/*** 从此飞速成长*/void growFast();/*** 组团刷怪,经历九死一生(主角怎么也死不了)*/void manyFights();/*** 最终功成名就,妻妾成群*/void succeed();/*** 组合起来就是小说内容*/void getContent();
}

2.有了梗概剩下的就是填内容了,我们分别创建两个具体小说类 StoryAStoryB:

故事 A ,跳舞的恶魔法则:

/*** 故事 A ,恶魔法则* Created by zhangshixin on 8/27/2016.*/
public class StoryA implements Synopsis {private String mName;public StoryA(String name) {mName = name;}@Overridepublic void badStart() {System.out.println(mName + " 无故穿越,因为没有魔法能力,成为将军家的废物,不受待见。");}@Overridepublic void adventure() {System.out.println(mName + " 因为意外来到恶魔岛,在恶魔岛上遇见了恶魔的仆人,获得了一直想要的使用魔法的能力");}@Overridepublic void winABattle() {System.out.println(mName + " 协助辰皇子夺得了帝国的权力,成为郁金香公爵");}@Overridepublic void growFast() {System.out.println(mName + " 先后在曾曾曾祖母、恶魔仆人、圣骑士、魔导师的帮助下飞速成长");}@Overridepublic void manyFights() {System.out.println(mName + " 建立魔法学院和魔法学会,与魔法工会分庭抗礼。坐拥西北十万雄兵,歼灭西北军团,打退草原人,带领人类全族击退北方的异族军队。");}@Overridepublic void succeed() {System.out.println(mName + " 娶了女皇为妻子,成为罗兰帝国的英雄。");}@Overridepublic void getContent() {badStart();adventure();winABattle();growFast();manyFights();succeed();}
}

故事 B ,萧鼎的诛仙,这个小说的文笔、情节中是我最喜欢的小说之一,但也是有一些固定套路:

/*** 故事 B ,诛仙* Created by zhangshixin on 8/27/2016.*/
public class StoryB implements Synopsis {private String mName;public StoryB(String name) {mName = name;}@Overridepublic void badStart() {System.out.println(mName + " 全村被屠,投入青云七脉中人数最少的大竹峰。");}@Overridepublic void adventure() {System.out.println(mName + " 在一次伐竹过程中,为追一只三眼灵猴,入青云山深处得到了烧火棍。");}@Overridepublic void winABattle() {System.out.println(mName + " 在七脉会武中侥幸进了前 4,和陆雪琪等人一起万蝠古窟历练。");}@Overridepublic void growFast() {System.out.println(mName + " 在魔教十年,深得鬼王器重和真传。");}@Overridepublic void manyFights() {System.out.println(mName + " 经历无数战斗,先是为鬼王卖命,后来与鬼王大战。");}@Overridepublic void succeed() {System.out.println("天地不仁,以万物为刍狗。 " + mName +" 最后成为最有资格拥有天书的人。");}@Overridepublic void getContent() {badStart();adventure();winABattle();growFast();manyFights();succeed();}
}

3.故事梗概、具体内容都有了,剩下的就是量产了,据悉 唐家三少 日产 7k 字,实在佩服:

/*** 写小说* Created by zhangshixin on 8/28/2016.*/
public class WriteNovel {private Synopsis mSynopsis;     //故事梗概private String mMainActorName;  //主角名称/*** 梗概、内容都差不多确定后,换个名称就是另一部小说* @param mainName*/public WriteNovel(String mainName){switch (mainName){case "张小凡":mSynopsis = new StoryB(mainName);break;case "杜维":mSynopsis = new StoryA(mainName);break;default:mSynopsis = new StoryB(mainName);break;}}/*** 获取小说内容*/public void getNovelDetail(){mSynopsis.getContent();}
}

可以看到,我们 把小说内容的选择封装在了 WriteNovel,减少了客户端与 WriteNovel 的耦合,这样等我们要换小说的具体实现时,客户端不用修改代码。

4.客户端只要输入主角名称,就可以得到一部小说,比如写一部类似诛仙的小说,主角名称为张拭心

@Testpublic void testGetNovelDetail() throws Exception {WriteNovel writeNovel = new WriteNovel("张拭心");writeNovel.getNovelDetail();}

我们可以把 WriteNovel 类中的 default 设置为 StoryB ,即 诛仙:

public WriteNovel(String mainName){switch (mainName){//...省略掉不关键的内容default:mSynopsis = new StoryB(mainName);break;}}

5.假如现在需求变了,要写一部穿越的小说,主角还是 张拭心,这时只需修改 WriteNovel 中的 default 设置为 StoryA ,即 恶魔法则 即可,客户端不需要修改

/*** 梗概、内容都差不多确定后,换个名称就是另一部小说* @param mainName*/public WriteNovel(String mainName){switch (mainName){case "张小凡":mSynopsis = new StoryB(mainName);break;case "杜维":mSynopsis = new StoryA(mainName);break;default:mSynopsis = new StoryA(mainName);break;}}

代码总结

用一个 UML 图表示上述代码的关系:

我们将公共的情节提取到梗概接口 Synopsis 中,然后创建不同的故事类,写小说时WriteNovel 中有一个接口的引用,根据客户端传入主角名称创建不同的实现类。

可以发现,这其实就是把在客户端代码中的判断提取了出来,让客户端减少对具体实现的依赖,转向对接口依赖,不就是我们之前说的 设计模式六大原则: 老板是如何减轻负担的 – 依赖倒置原则 吗?

其实这就是传说中的 策略模式

策略模式 Strategy

策略模式封装了变化。

策略模式又叫算法簇模式。它定义了一系列的算法用来完成相同的工作。策略模式让算法独立于使用它的客户而独立变化。

– 大话设计模式

只要遇到很多 if-else 或者有很多 caseswitch,就可以考虑使用策略模式了,将这些行为独立的封装起来,可以在公共类中消除条件语句。

在实践中,只要听到需要在不同情况下应用不同的业务,就可以考虑使用策略模式来封装这种变化的可能性。

备注

我们在 Android 编码过程中,其实也经常遇到策略模式,在了解什么是策略模式后,下一篇文章我们去看看 Android 中有哪些地方用到了策略模式

代码地址点这里

其他设计模式文章:
动态代理:1 个经纪人如何代理 N 个明星
代理模式:女朋友这么漂亮,你缺经纪人吗?

策略模式:网络小说的固定套路相关推荐

  1. 数据解读 | 中国网络小说出海:老外也逃不开屌丝逆袭的套路

    作者 | 钟黛 来源|DT财经 2014年,美国人凯文·卡扎德因为失恋自暴自弃,甚至开始服用药品导致身体状况亮起红灯.但仅仅半年后,他就彻底摆脱了毒瘾.因为他在一个叫作"WuxiaWorld ...

  2. springboot map数据类型注入_SpringBoot结合策略模式实战套路

    1. SpringBoot结合策略模式实战套路 1.1. 前言 我们都知道设计模式好,可以让我们的代码更具可读性,扩展性,易于维护,但大部分程序猿一开始都学过至少一遍设计模式吧,实战中不知用到了几成. ...

  3. 网络小说写作套路_关于网络写作的6个常见问题,已回答

    网络小说写作套路 Recently an ex-journalist friend asked me about freelance writing for the web. Although he ...

  4. 【隧道篇 / IPsec】(5.2) ❀ 03. IPsec - 拨号宽带 to 固定IP宽带 (策略模式) ❀ FortiGate 防火墙

    [简介]现在很多单位都有分公司或者分部,距离离的还比较远,但又经常需要两点之间进行安全的通迅,防火墙与防火墙之间建立IPsec可以很好满足要求,固定IP宽带和ADSL拨号宽带都很常见,这里介绍两种不同 ...

  5. 找不到网络名_书荒粮草,网络小说推荐大合集:文笔一流,拒绝套路

    网络小说走过这么多年,已经成为大家日常生活离不开的陪伴,也涌现出了众多经典.但是网文看多了,难免会感到书荒,特别是对满满的套路文和小白文丧失了兴趣. 关注小编,每天给书荒的朋友提供粮草.今天给大家介绍 ...

  6. 【白话设计模式01】小良买了卡带游戏机(策略模式)

    什么是策略模式 策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法 -- 百度百科 小良买了台带游戏卡槽的游戏机,通过不同的游戏卡带,在一台游戏机上就能玩不同的 ...

  7. 找不到网络名_强推3本冷门网络小说,水平优秀却不火,真是明珠蒙尘

    网络小说千千万,多数书虫看小说,都会找排行榜上面的热门小说来阅读.但是,很多老书虫也感觉排行榜上的热门小说不符合自己的胃口,反而一些冷门小说更有吸引力. 因此,老书虫的口碑也成为一些朋友挑选小说的重要 ...

  8. 设计模式之策略模式+工厂模式+模板模式结合

    设计模式之策略模式+模板模式 为什么总是学不好设计模式 从"登录功能"中发现问题. 首先我们简单的了解功能需求: 于是你开始干活了: 1.控制层代码如下,根据不同的登录方式调用不同 ...

  9. 【隧道篇 / IPsec】(5.2) ❀ 04. IPsec - 拨号宽带 to 拨号宽带 (策略模式) ❀ FortiGate 防火墙

    [简介]现在很多单位都有分公司或者分部,距离离的还比较远,但又经常需要两点之间进行安全的通迅,防火墙与防火墙之间建立IPsec可以很好满足要求.ADSL拨号宽带物美价廉,只可惜每次拨号生成的外网IP都 ...

  10. 【设计模式七之策略模式】你有你的张良计,我有我的过墙梯

    Strategy模式 细说策略模式 策略模式究竟是什么模式 策略模式的场景 官宣的策略模式 代码展示 代码一 细说策略模式 提示: 博主:章飞 _906285288的博客 博客地址:http://bl ...

最新文章

  1. 苹果8a1660是什么版本_iOS 13频繁“翻车”,果粉们面对苹果将情何以堪
  2. linux测试dvi接口,液晶显示器DVI接口及测试规范.pdf
  3. C++ BSS段、数据段、代码段、堆与栈及五大内存分区
  4. 数据泵工具导出的步骤(用于Oracle11G和10G之间的相互转换)
  5. 智能优化算法总结-数字孪生下的车间调度-APS预告
  6. 西门子plc烧录单片机_单片机可以替代 PLC 吗?
  7. eplan2.7在win10安装教程
  8. python抽奖游戏、某商场为了促销_详解python--模拟轮盘抽奖游戏
  9. 网络安全攻击与防护--HTML学习
  10. Ubuntu磁盘扩容(简单亲测有效)
  11. 阿里云服务器最低多少钱一个月,租阿里云服务器一年多少钱
  12. 厦门市各中巴线路途经站点
  13. 大牛养成指南(2):先实现一个小目标吧!10000小时理论如何轻松落地
  14. 树莓派摄像头无法识别 mmal
  15. 利用4G CAT1开发板制作短信网关(一)
  16. 让System.Drawing.Bitmap可以在linux运行
  17. 【计算机视觉】NCC匹配算法
  18. 有一种感觉叫清风细雨
  19. windows重装系统简易版--不需要u盘
  20. 序列化和反序列化的底层实现原理是什么

热门文章

  1. 360浏览器html文件无图标,电脑桌面360浏览器图标不见了解决方法图文教程
  2. html常用元素总结
  3. dell服务器 指示灯_服务器指示灯说明
  4. 追星女孩彩虹屁情话合集100条 ✔︎ (三)
  5. 教你用迅雷下载百度网盘的文件
  6. SpringBoot 启动时自动执行代码的几种方式
  7. Word失去焦点卡顿,从其他地方回到Word转圈圈
  8. SQLyog安装地址
  9. 软件开发培训要学多久?怎么学?软件开发培训班多少钱?
  10. 离散数学-自反性-对称性-传递性,关系的性质