Ethan's Blog


  • Home

  • Archives

  • Tags

  • Search

Builder Design Pattern

Posted on 2020-11-29

为什么需要建造者模式?

假设有这样一道设计面试题:我们需要定义一个资源池配置类 ResourcePoolConfig。这里的资源池,你可以简单理解为线程池、连接池、对象池等。在这个资源池配置类中,有以下几个成员变量,也就是可配置项。现在,请你编写代码实现这个 ResourcePoolConfig 类:

只要你稍微有点开发经验,那实现这样一个类对你来说并不是件难事。因为 maxTotal、maxIdle、minIdle 不是必填变量,所以在创建 ResourcePoolConfig 对象的时候,我们通过往构造函数中,给这几个参数传递 null 值,来表示使用默认值:

Read more »

Factory Design Pattern

Posted on 2020-11-22

简单工厂(Simple Factory)

在下面这段代码中,我们根据配置文件的后缀(json、xml…),选择不同的解析器(JsonRuleConfigParser、XmlRuleConfigParser…),将存储在文件中的配置解析成内存对象 RuleConfig:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class RuleConfigSource 
{
public RuleConfig load(String ruleConfigFilePath)
{
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
IRuleConfigParser parser = null;
if ("json".equalsIgnoreCase(ruleConfigFileExtension))
{
parser = new JsonRuleConfigParser();
}
else if ("xml".equalsIgnoreCase(ruleConfigFileExtension))
{
parser = new XmlRuleConfigParser();
}
else if ("yaml".equalsIgnoreCase(ruleConfigFileExtension))
{
parser = new YamlRuleConfigParser();
}
else if ("properties".equalsIgnoreCase(ruleConfigFileExtension))
{
parser = new PropertiesRuleConfigParser();
}
else
{
throw new InvalidRuleConfigException("Rule config file format is not supported: " + ruleConfigFilePath);
}

String configText = "";
// 从 ruleConfigFilePath 文件中读取配置文本到 configText 中
RuleConfig ruleConfig = parser.parse(configText);
return ruleConfig;
}

private String getFileExtension(String filePath)
{
//...解析文件名获取扩展名,比如 rule.json,返回 json
return "json";
}
}
Read more »

Singleton Design Pattern

Posted on 2020-11-21

为什么要使用单例?

单例设计模式(Singleton Design Pattern)理解起来非常简单。一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。

实战案例一:处理资源访问冲突

在这个例子中,我们自定义实现了一个往文件中打印日志的 Logger 类。具体的代码实现如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Logger 
{
private FileWriter writer;

public Logger()
{
File file = new File("/Users/wangzheng/log.txt");
writer = new FileWriter(file, true); // true 表示追加写入
}

public void log(String message) {
writer.write(message);
}
}

// Logger 类的应用示例:
public class UserController
{
private Logger logger = new Logger();

public void login(String username, String password)
{
//...省略业务逻辑代码...
logger.log(username + " logged-in!");
}
}

public class OrderController
{
private Logger logger = new Logger();

public void create(OrderVo order)
{
//...省略业务逻辑代码...
logger.log("Created an order: " + order.toString());
}
}
Read more »

编程技巧

Posted on 2020-11-17

把代码分割成更小的单元块

大部分人阅读代码的习惯都是,先看整体再看细节。所以,我们要有模块化和抽象思维,善于将大块的复杂逻辑提炼成类或者函数,屏蔽掉细节,让阅读代码的人不至于迷失在细节中,这样能极大地提高代码的可读性。不过,只有代码逻辑比较复杂的时候,我们其实才建议提炼类或者函数。毕竟如果提炼出的函数只包含两三行代码,在阅读代码的时候,还得跳过去看一下,这样反倒增加了阅读成本。

这里我举一个例子来进一步解释一下。重构前,在 invest() 函数中,最开始的那段关于时间处理的代码,是不是很难看懂?重构之后,我们将这部分逻辑抽象成一个函数,并且命名为 isLastDayOfMonth,从名字就能清晰地了解它的功能,判断今天是不是当月的最后一天。这里,我们就是通过将复杂的逻辑代码提炼成函数,大大提高了代码的可读性。代码具体如下所示:

Read more »

代码风格

Posted on 2020-11-17

类、函数多大才合适?

总体上来讲,类或函数的代码行数不能太多,但也不能太少。类或函数的代码行数太多,一个类上千行,一个函数几百行,逻辑过于繁杂,阅读代码的时候,很容易就会看了后面忘了前面。相反,类或函数的代码行数太少,在代码总量相同的情况下,被分割成的类和函数就会相应增多,调用关系就会变得更复杂,阅读某个代码逻辑的时候,需要频繁地在 n 多类或者 n 多函数之间跳来跳去,阅读体验也不好。

对于函数代码行数的最大限制,网上有一种说法,那就是不要超过一个显示屏的垂直高度。比如,在我的电脑上,如果要让一个函数的代码完整地显示在 IDE 中,那最大代码行数不能超过 50。这个说法我觉得挺有道理的。因为超过一屏之后,在阅读代码的时候,为了串联前后的代码逻辑,就可能需要频繁地上下滚动屏幕,阅读体验不好不说,还容易出错。

对于类的代码行数的最大限制,这个就更难给出一个确切的值了。有一个间接的判断标准 – 当一个类的代码读起来让你感觉头大了,实现某个功能时不知道该用哪个函数了,想用哪个函数翻半天都找不到了,只用到一个小功能要引入整个类(类中包含很多无关此功能实现的函数)的时候,这就说明类的行数过多了。

一行代码多长最合适?

不同的编程语言、不同的规范、不同的项目团队,对此的限制可能都不相同。不管这个限制是多少,总体上来讲我们要遵循的一个原则是:一行代码最长不能超过 IDE 显示的宽度。需要滚动鼠标才能查看一行的全部代码,显然不利于代码的阅读。当然,这个限制也不能太小,太小会导致很多稍长点的语句被折成两行,也会影响到代码的整洁,不利于阅读。

Read more »
1…363738…55
necusjz

necusjz

275 posts
16 tags
© 2016 - 2026 necusjz
Powered by Hexo
Theme - NexT.Mist