有两件事会让软件研发过程变得很糟糕,一是糟糕的团队文化,二是由于设计不佳而导致的技术债。我无法告诉你,由于不理解自己的代码,我放弃了多少个人项目。以及和一群到处都是WET(Write Everything Twice)代码的人一起工作是多么的令人沮丧。
这让我感到十分厌恶。
编写糟糕的代码是人性的一部分,这无可避免。有时候我们会忘记一些重要的事情,或者产生新的想法,或者分心去做其他事情。因而完全忘记了软件项目的结构,从而忽略了项目中的一些小的警告信息,而这些往往可能导致后期出现巨大的技术债。
我的警告
作为一个拥有非传统背景的开发者,理解软件工程的“为什么”可能会很有挑战性。我记得我曾经询问过某个应用程序中某个功能是如何工作的,并且得到了很好的解释,但我还需要进一步理解为什么选择了这样的解决方案。
其他问题包括:
为什么项目是这样构建的?
为什么你要这样编写你的类?
在一个数字医疗机构工作时,我有幸直接与其他一些工程师们合作,他们为我分解了这一理论。他们正在使用工厂设计模式,我认为这是刚开始接触设计模式的工程师们的一个很好的起点。
我也常常会问问题,这样我就不会在以后让自己变得难堪。其实,问问题是最好的一种学习方式,因为我们都不知道自己不知道什么。
“现在看起来毫无意义,但我完全理解了!”
这就是当我经理第一次向我解释工厂设计模式后,我对自己说的话。在我习惯了这种模式的编码后,开发速度更快了,测试和调试也变得不那么痛苦了,而且它可以让我用更少的代码来完成像添加和删除这样的功能。良好的软件设计让开发人员能够将复杂的问题分解成更小、更易于管理的小问题,逐一解决。
良好的软件设计能够在某些问题出现之前就解决它们。
对于单组件应用程序和小型项目而言,软件设计可能并不是一个真正的问题。
而当你开始在一个大型项目中与大型团队合作时,你才会真正理解某些问题。就像有的人直到他们的车辆在 12 万至 15 万英里左右开始出现问题时,他才会意识到合成机油对他们的发动机有多好。
工厂设计模式
工厂设计模式(Factory Design Pattern)是一种编程概念,允许你以更灵活和受控的方式创建对象。
想象一下,你需要为你的商店创建许多产品,但每个对象的创建都基于某些条件而有所不同。例如,如果你在生产汽车,你知道它们都将至少需要四个轮子、一个油箱、一个发动机等等,但每辆汽车都会有独特的颜色、形状、年份和型号。与其从零开始创建每辆汽车,你也可以构建一个蓝图来确定每辆汽车应该如何设计。
无需不断回到起点重新设计。
工厂有一个方法,它接受一些参数,并根据这些参数创建适当的对象然后将其返回给你。这样,你就可以轻松地创建许多对象,并且你可以通过更改工厂的方法来改变对象的创建方式,而不是更改整个程序。
让我们看看下面的例子。
// Define an interface for the Product object
interface Product {
name: string;
price: number;
}
// Define the concrete product classes that implement the Product interface
class Book implements Product {
public name: string;
public price: number;
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
}
class Shirt implements Product {
public name: string;
public price: number;
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
}
// Define the factory class that creates the Product objects
class ProductFactory {
public createProduct(type: string, name: string, price: number): Product {
if (type === 'book') {
return new Book(name, price);
} else if (type === 'shirt') {
return new Shirt(name, price);
} else {
throw new Error('Invalid product type.');
}
}
}
// Usage example
const factory = new ProductFactory();
const book = factory.createProduct('book', 'The Lord of the Rings', 20.99);
const shirt = factory.createProduct('shirt', 'Blue T-Shirt', 12.99);
console.log(book);
console.log(shirt);
我们首先声明了一个包含名称和价格的接口,每个产品将仅具有这两个变量,ProductFactory
负责处理这些产品的类别,并且在 createProduct
方法中,每个产品都作为第一个参数传入。
下面是一个工厂设计模式的错误实现示例。
class Product {
public name: string;
public price: number;
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
}
class ProductFactory {
public createProduct(type: string, name: string, price: number): Product {
if (type === 'book') {
return new Product(name, price);
} else if (type === 'shirt') {
return new Product(name, price);
} else {
throw new Error('Invalid product type.');
}
}
}
// Usage example
const factory = new ProductFactory();
const book = factory.createProduct('book', 'The Lord of the Rings', 20.99);
const shirt = factory.createProduct('shirt', 'Blue T-Shirt', 12.99);
console.log(book);
console.log(shirt);
如您所见,createProduct
方法用于处理类型,但程序的后续逻辑无法确定产品属于哪个类别。
即使我们在 productFactory
中添加了其他类,我们也会违反要求所有类具有单一职责的规则。现在这可能看起来没什么大不了的,但随着应用程序的增长,由于单个更改会影响项目中的多个模块,你可能会发现将来很难维护它。
最后的思考
在你构建一个应用程序并打算稍后扩展和添加更多功能时,软件设计是应该采取的关键步骤。它还有助于保持代码结构的整洁和组织性,以便你以后不会遇到任何意外情况。