1.工厂设计模式
1.1.个人心得
粗暴的开发方式可以归纳为三步:定义属性,创建方法,调用展示。虽然初次实现很快,但不便于后期维护和扩展。
真正好的代码不只是为了完成现有功能,更会考虑后续扩展。在结构设计师,讲究松耦合,易读和易扩展。在领域实现上,做到高内聚,不对外暴露实现细节,不被外部干扰。这就像家庭的三居室(MVC)、四居室(DDD)的装修,绝不允许把水电管线裸漏在外面,也绝不允许把马桶装到厨房,更不会把炉灶安装到卫生间
视觉盲区决定了你的选择
同样一本书、同样一条路、同样一座城,真的以为生活中有选择吗?有时候很多选项只是摆设,给多少次机会我们选择的都是一模一样的。这不是如何选的问题,而是认知范围决定了下一秒做的事情,下一秒做的事情又影响了再下一秒的决定。就像管中窥豹一样。总有一部分视野是黑色的,会被忽略掉,而这看不到的部分却举足轻重。但人可以学习,可以成长,可以脱胎换骨,可以努力付出,通过一次次的蜕变拓展自己的视野。
1.2.工厂模式介绍
工厂模式也称简单工厂模式,是创建型设计模式的一种,这种设计模式提供了按需创建对象的最佳方式。同时,这种创建方式不会对外暴露细节,并且会通过一个统一的接口创建所需对象。
这种设计模式也是Java开发中常见的一种模式,它的主要意图是定义一个创建对象的接口,让其子类自己决定将哪一个工厂类实例化,工厂模式使创建过程延迟到子类中进行。
简单地说,就是为了给代码结构提供扩展性,屏蔽每一个功能类中的具体实现逻辑。这种方式便于外部更加简单地调用,同时也是去掉众多if...else的最佳手段。当然,这种设计模式也有一些缺点,需要治理。例如需要实现的类比较多,难以维护、开发成本高等,但这些问题都可以通过结合不同的设计模式逐步优化。
1.2.1简单工厂模式
简单工厂模式是指一个工厂对象决定创建哪一种产品类的实例,但它不属于GOF的23中设计模式。简单工厂模式适用于工厂类复杂创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象不需要关心
我们来看代码,以课程为例。学员目前开设有Java,Python,前端等等课程,已经形成一个生态,我们可以定一一个课程标准ICourse接口
java
public interface ICourse {
//录制视频
public void record();
}
创建一个Java课程的实现JavaCourse类
java
public class JavaCourse implements ICourse{
public void record(){
System.out.println("录制java课程")
}
}
我们会这样写客户端调用代码
java
public static void main(String[] args){
ICourse course = new JavaCourse();
course.record();
}
在上面代码中,父类ICourse指向子类JavaCourse的引用,应用层代码需要依赖JavaCourse,如果业务扩展,继续增加PythonCouse甚至更多课程,那么客户端的依赖会变得越来越臃肿,因此,我们要想办法把这种依赖减弱,把创建细节隐藏起来。虽然在目前的代码中,创建对象过程并不复杂,但从代码设计的角度来讲不易于扩展。现在,我们用简单工厂模式对代码进行优化
先增加课程类PythonCourse:
java
public class PythonCourse implements ICourse{
public void record(){
System.out.println("录制Python课程")
}
}
创建工厂类CouseFactory
java
public class CourseFactory {
pubic ICourse create(String name){
if("java".equals(name)){
return new JavaCourse();
}else if("python".equals(name)){
return new PythonCourse();
}else{
return null;
}
}
}
修改客户端调用代码如下:
java
public class SimpleFactoryTest{
public static void mian(String[] args){
CourseFactory factory = new CourseFactory();
factory.create("java");
}
}
当然,为了调用方便可将工厂的create()方法改为静态方法。
客户端调用变简单了,但如果我们的业务继续扩展,要增加前端课程,那么工厂中的create方法就要每次都根据产品的增加修改代码逻辑,不符合开闭原则。因此,我们还可以对简单工厂模式继续优化,采用反射技术
java
public class CourseFactory{
public ICourse create(String className){
try{
if(!(null == className || "".equals(className))){
return (ICourse) Class.forName(className).newInstance();
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
修改客户端调用代码
java
public static void main(String[] args){
CourseFactory factory = new CourseFactory();
ICourse course = factory.create("com.tang.vip.pattern.factory.simplefactory.JavaCourse")
.course.record();
}
优化之后,产品不断丰富的过程不需要修改CourseFactory中的代码,但还有个问题是,方法参数是字符串,可控性有待提升,而且还需要强制转型。再修改一下代码:
java
public ICourse create(Class<? extends ICourse> clazz){
try{
if(null != clazz){
return clazz.newInstance();
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
优化客户端代码
java
public static void main(String[] args){
CourseFactory factory = new CourseFactory();
ICourse course = factory.create(JavaCourse.class);
course.record();
}
1.3.工厂方法模式
工厂方法模式是指定一一个穿件对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品是符合开闭原则。
工厂方法模式只要解决g产品扩展的问题。在简单工厂模式中,随着产品链的丰富,如果每一个创建逻辑有缺别,则工厂的职责会变得越来越多,有点像万能工厂,不便于维护。根据单一责任原则我们将智能继续拆分,专人干专事
工厂方法模式适用于以下场景:
(1)创建对象需要大量重复代码。
(2)客户端(应用层)不依赖于产品类实例如何被创建、如何被实现细节。
(3)一个类通过其字类来制定创建哪一个对象
工厂方法模式有很多缺点
(1)类的个数容易过多,增加复杂性
(2)增加了系统的抽象性和理解难度
1.4工厂模式总结
工程模式并不复杂。一旦理解和掌握,会发现它更加简单,同时也可以借助他提升开发效率。同时不难总结出他的优点;避免创建这与具体的产品逻辑耦合;满足单一职责,每一个业务逻辑实现都在自己所属的类中完成;满足开闭原则,无须更改适用调用方就可以在程序中引入新的产品类型。当然,这也会带来一些问题。如果已经有所收获一定要实操,找一段业务代码联系,以验证自己的想法
2.抽象工厂模式
2.1个人心得
代码一把梭,兄弟来背锅
大部分从事开发工作的技术人员,都有一颗把代码写好的初心。出来吧编程当作一份工作。同时还具备一定的工匠精神。但很多时候又很难把初心坚持下去,尤其面对烂手的项目、产品功能要的急迫、个人能力不足等问题时,这些原因导致开发的工程代码臃肿不堪,线上事故频出
懂得高并发,可还写不好代码
这就像家里面装修完之后购买家具,花了几十万元买的实木沙发,怎么摆放也不好看!代码写得不好,不一定是基础经验不足,也不一定是产品需求要的急迫。很多时候是自己对编码经验掌握得不足,以及对架构的把控能力不到位。其实大多数产品的第一个需求往往并不复杂,甚至可以说所见即所得般容易。但在接手开发时,如果不考虑后续是否需要扩展将来会在那些模块继续添加功能,这样的"病毒代码就会随着种下一个劣质种子开始蔓延"
2.2.抽象工厂模式介绍
抽象工厂模式是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们的具体类。客户端(应用层)不依赖于产品类实力如何被创建、如何被实现的细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现