写点什么

架构师训练营 - 第 3 周学习总结

用户头像
红了哟
关注
发布于: 2020 年 06 月 27 日
架构师训练营 - 第 3 周学习总结

本周课程中学习到的更多的是从设计模式中感受如何写好代码,如何让代码优雅又简洁。同时在多人协作开发时更加的规范高效易于扩展。



设计模式:

1、每一种模式都描述了一种文体的通用解决方案。这种问题再我们的环境中,不停地出现。

2、设计模式是一种可重复使用的解决方案。



设计模式

创建模式(Creational Patterns):对类的实例化过程的抽象

结构模式(Structural Patterns):将类或者对象结合在一起形成更大的结构

行为模式(Behavioral Patterns):对在不同的对象之间划分责任和算法的抽象化

从方式分:

类模式:以继承的方式实现模式,静态的

对象模式:以组合的方式实现模式,动态的



工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

介绍

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时。

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

关键代码:创建过程在其子类执行。

应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

//抽象产品
abstract class AudiCar{
private String name;
public abstract void makeCar();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//具体产品
class AudiA6 extends AudiCar{
public void makeCar(){
System.out.println(this.getName()+"----go-----------------------");
}
}
class AudiA4 extends AudiCar{
public void makeCar(){
System.out.println(this.getName()+"----go-----------------------");
}
}
//销售部门----服务端
class CarContext {
AudiCar audiCar = null;
public CarContext(AudiCar audiCar) {
this.audiCar = audiCar;
}
public void orderCar(){
this.audiCar.makeCar();
}
}
//客户----客户端(这个客户是内行,什么都懂,他说我要A6,销售部门立刻给他a6,所以销售部门不用很懂)
public class SimplyFactoryAndStrategy2 {
public static void main(String[] args) throws IOException {
//客户说我要什么什么样子的车子,销售人员才知道他要什么样子的车子
AudiCar car = new AudiA6();
car.setName("a6");
CarContext context = new CarContext(car);
context.orderCar();
}
}
//工厂模式---与上面的策略模式比较
//抽象产品
abstract class AudiCar{
private String name;
public abstract void makeCar();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//具体产品
class AudiA6 extends AudiCar{
public void makeCar(){
System.out.println(this.getName()+"----go-----------------------");
}
}
class AudiA4 extends AudiCar{
public void makeCar(){
System.out.println(this.getName()+"----go-----------------------");
}
}
//简单工厂---销售部门----服务端
class CarFactroy{
public static AudiCar createCar(String car){
AudiCar c = null;
if("A6".equalsIgnoreCase(car))
c = new AudiA6();
else if("A4".equalsIgnoreCase(car))
c = new AudiA4();
return c;
}
}
//客户----客户端(这个客户是外行,什么都不懂,只要随便描述下车,销售部门才能知道他要那款车,所以销售部门比较牛)
public class SimplyFactoryAndStrategy {
public static void main(String[] args) throws IOException {
System.out.print("请输入您要坐的车:(A6、A4)");
String carName = new BufferedReader(new InputStreamReader(System.in)).readLine();
//客户说我要什么什么样子的车子,销售人员才知道他要什么样子的车子
AudiCar car = CarFactroy.createCar(carName);
car.setName(carName);
car.makeCar();
}
}



适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

我们通过下面的实例来演示适配器模式的使用。其中,音频播放器设备只能播放 mp3 文件,通过使用一个更高级的音频播放器来播放 vlc 和 mp4 文件。

介绍

意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。

何时使用: 1、系统需要使用现有的类,而此类的接口不符合系统的需要。 2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。 3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)

如何解决:继承或依赖(推荐)。

关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。

应用实例: 1、美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。 2、JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。 3、在 LINUX 上运行 WINDOWS 程序。 4、JAVA 中的 jdbc。

优点: 1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性好。

缺点: 1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。

注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。



一个类的适配器(由于原 Sortable 接口和ArrayList 不兼容,只好定义一个NewSortable)

public interface NewSortable<T> {
int size();
T getElement(int i);
void setElement(int i, T o);
}
public class SortableList<T> extends ArrayList<T> implements NewSortable<T> {
public T getElement(int i) {
return get(i);
}
public void setElement(int i, T o) {
set(i, o);
}
}

实现一个单元测试的步骤:

1、创建测试类,从TestCase派生

2、初始化:覆盖积累的方法(protected void setUp())

3、清除环境:覆盖积累的方法(protected void tearDown())

4、书写测试方法:命名规范(public void testXxx())



模板方法模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

介绍

意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

主要解决:一些方法通用,却在每一个子类都重新写了这一方法。

何时使用:有一些通用的方法。

如何解决:将这些通用算法抽象出来。

关键代码:在抽象类实现,其他步骤在子类实现。

应用实例: 1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。 2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。 3、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。

优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。

缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。

注意事项:为防止恶意操作,一般模板方法都加上 final 关键词。



发布于: 2020 年 06 月 27 日阅读数: 55
用户头像

红了哟

关注

还未添加个人签名 2019.08.15 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 - 第 3 周学习总结