设计模式总览
回顾软件设计原则
在看设计模式之前,我们回顾一下设计原则:
设计原则 | 解释 |
---|---|
开闭原则 | 对扩展开放,对修改关闭 |
依赖倒置原则 | 通过抽象使各个类或者各个模块互不影响,实现松耦合 |
单一职责原则 | 一个类、接口和方法只做一件事情 |
接口隔离原则 | 尽量保证接口的纯洁性,客户端不应该依赖不需要的接口 |
迪米特法则 | 又叫最少知道原则,一个类对依赖的类知道的越少越好 |
里式替换原则 | 子类可以扩展父类的功能,但是不能改变父类原有的功能 |
合成复用原则 | 尽量使用对象组合、聚合,而不是使用集成关系达到代码复用的目的 |
经典框架使用的设计模式及解决的问题
Spring就是把设计模式发挥到了淋漓尽致的经典框架,我来列举一下:
设计模式名称 | 举例 |
---|---|
工厂模式 | BeanFactory |
装饰器模式 | BeanWrapper |
代理模式 | AopProxy |
委派模式 | DispatcherServlet |
策略模式 | HandlerMapping |
适配器模式 | HandlerMapping |
模板模式 | JdbdTemplate |
观察者模式 | ContextLoaderListener |
上面我简单列举了一下Spring中用的一些设计模式,它用的很多很多,上面只是冰山一角。在实际运用设计模式中,常常都是混合使用。
我们来看一下设计模式的分类:
类型 | 名称 | 说明 |
---|---|---|
创建型模式 | 工厂模式 | Factory Pattern |
单例模式 | Singleton Pattern | |
原型模式 | Prototype Pattern | |
结构性模式 | 适配器模式 | Adapter Pattern |
装饰器模式 | Decorator Pattern | |
代理模式 | Proxy Pattern | |
行为型模式 | 策略模式 | Strategy Pattern |
模板模式 | Template Pattern | |
委派模式 | Delegate Pattern | |
观察值模式 | Observer Pattern |
工厂模式详解
工厂模式的由来
在现实生活中我们都知道,原始社会自给自足(没有工厂),农耕社会会有小作坊(简单工厂、民间作坊)、工业革命流水线(工厂方法、自产自销)、现在工厂(抽象工厂)。
简单工厂模式
简单工程模式(Simple Factory Pattern)指由一个工厂对象决定生产出哪一种产品的实例。简单工厂适用于负责创建对象较少的场景,一般是调用方传入工厂类的参数,对于如何创建的对象则调用方无需关心。
接下来我们来看代码:
定义一个车辆的一个接口:
public interface ICar { void run(); }
创建一个宝马类实现车辆的接口:
public class BmwCar implements ICar { private String brand; @Override public void run() { System.out.println("宝马开始跑了..."); } }
创建一个测试类执行:
public class Test { public static void main(String[] args) { ICar car = new BmwCar(); car.run(); } } 运行结果: 宝马开始跑了...
看上面的代码,应用层依赖了BmwCar,如果需要增加奔驰车,我们将继续增加BenCar,如果增加了很多的车,这时候客户端的依赖会越来越臃肿。因此,我们就需要隐藏创建对象的过程,现在我们用简单工厂模式来对代码进行优化。
工厂类、奔驰车类、和客户端类如下代码:
public class CarFactory { public ICar create(String brand){ if("Bmw".equals(brand)){ return new BmwCar(); }else if ("Ben".equals(brand)){ return new BenCar(); } return null; } }
public class BenCar implements ICar { @Override public void run() { System.out.println("大奔驰开始跑了..."); } }
public class Test { public static void main(String[] args) { // ICar car = new BmwCar(); // car.run(); CarFactory factory = new CarFactory(); ICar car = factory.create("Ben"); car.run(); } }
类图如下:
经过上面改造客户端调用就简单多了,如果我们的业务继续增加,工厂类的create()方法需要修改,这很显然违背了开闭原则,我们来继续优化,可以采用反射技术:
// 利用反射创建车辆 public ICar create(Class<? extends ICar> classz){ try { if(classz != null){ return classz.newInstance(); } }catch (Exception e){ e.printStackTrace(); } return null; }
客户端:
public class Test { public static void main(String[] args) { CarFactory factory = new CarFactory(); ICar car = factory.create(BmwCar.class); car.run(); } } 运行结果: 宝马开始跑了...
再看一下类图:
简单工厂也有它的优缺点
优点:
隐藏了创建对象的细节,客户端无需关心怎么创建
缺点:
工厂类职责相对过重,不易扩展过于负责的产品结构
今天就分享一下简单工厂,下篇文章我将分享工厂方法模式,咱们下周四见。