想说的话:
在大学的时候曾经学过这23种设计模式,但是那时没啥编程经验,糊里糊涂过了一遍,没多久就忘记了,工作之后将精力主要集中在学习新技术上,比如springboot,cloud,docker,vue。毕业两年后去面试,发现设计模式还是java程序员需要迈过的一道坎,面试的时候问到代理模式和适配器模式有什么区别,你在工作中用到了什么设计模式,怎么用的?答不上来的特别尴尬,所以决定重新学习这几种设计模式,争取在工作中使用上。
本文所有案例代码
码云:https://gitee.com/helloworld6379/designPattern
Github:Github地址
1 设计模式是程序员在面对同类软件工程设计问题所总结出来的有用的经验,模式不是代码,而是某类问题的通
用解决方案,设计模式(Design pattern)代表了最佳的实践。这些解决方案是众多软件开发人员经过相当长的
一段时间的试验和错误总结出来的。
2 设计模式的本质提高 软件的维护性,通用性和扩展性,并降低软件的复杂度。
3 设计模式并不局限于某种语言,java,php,c++ 都有设计模式.
设计模式类型
设计模式分为三种类型,共 23 种
1 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式。
2 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
3 行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter 模式)、状态模式、策略模式、职责链模式(责任链模式)。
不同的资料上对分类和名称略有差别
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
1 简单工厂模式
2 工厂方法模式
3 抽象工厂模式
意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不同条件下创建不同实例时。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
关键代码:创建过程在其子类执行。
应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。
注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
我们将创建一个 Phone接口和实现 Phone接口的实体类。下一步是定义工厂类 PhoneFactory。
public interface Phone {
public Phone make();
}
public class XiaoMiPhone implements Phone{
public XiaoMiPhone(){
}
private XiaoMiPhone(String cpuType){
System.out.println("制造小米手机:" + cpuType);
}
@Override
public Phone make() {
return new XiaoMiPhone("骁龙");
}
}
public class HuaWeiPhone implements Phone{
public HuaWeiPhone(){
}
public HuaWeiPhone(String cpuType){
System.out.println("制造华为手机:" + cpuType);
}
@Override
public Phone make() {
return new HuaWeiPhone("麒麟");
}
}
public class PhoneFactory {
public Phone makePhone(String phoneType) {
if("XiaoMi".equalsIgnoreCase(phoneType)){
return new XiaoMiPhone().make();
}
else if("HuaWei".equalsIgnoreCase(phoneType)) {
return new HuaWeiPhone().make();
}
return null;
}
}
public class SimpleFactoryTest {
public static void main(String[] args) {
PhoneFactory factory = new PhoneFactory();
Phone xiaomi = factory.makePhone("XiaoMi");
Phone huawei = factory.makePhone("HuaWei");
}
}
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂
UML图:
package com.fighting.pattern.factory.factorymethod;
public interface Phone {
public Phone make();
}
package com.fighting.pattern.factory.factorymethod;
public class XiaoMiPhone implements Phone {
public XiaoMiPhone(){
}
private XiaoMiPhone(String cpuType){
System.out.println("制造小米手机:" + cpuType);
}
@Override
public Phone make() {
return new XiaoMiPhone("骁龙");
}
}
package com.fighting.pattern.factory.factorymethod;
public class HuaWeiPhone implements Phone {
public HuaWeiPhone(){
}
public HuaWeiPhone(String cpuType){
System.out.println("制造华为手机:" + cpuType);
}
@Override
public Phone make() {
return new HuaWeiPhone("麒麟");
}
}
package com.fighting.pattern.factory.factorymethod;
public interface PhoneFactory {
Phone makePhone();
}
package com.fighting.pattern.factory.factorymethod;
public class XiaoMiFactory implements PhoneFactory{
@Override
public Phone makePhone() {
return new XiaoMiPhone().make();
}
}
package com.fighting.pattern.factory.factorymethod;
public class HuaWeiFactory implements PhoneFactory{
@Override
public Phone makePhone() {
return new HuaWeiPhone().make();
}
}
package com.fighting.pattern.factory.factorymethod;
public class FactoryMethodTest {
public static void main(String[] args) {
PhoneFactory xiaomiFactory = new XiaoMiFactory();
PhoneFactory huaWeiFactory = new HuaWeiFactory();
Phone xiaomiPhone = xiaomiFactory.makePhone();
Phone huaweiPhone = huaWeiFactory.makePhone();
}
}
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
应用实例:比如小米和华为工厂除了生产手机,现在还要生产笔记本电脑。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
注意事项:产品族难扩展,产品等级易扩展。
public interface Phone {
Phone make();
}
public class XiaoMiPhone implements Phone {
public XiaoMiPhone(){
}
private XiaoMiPhone(String cpuType){
System.out.println("制造小米手机:" + cpuType);
}
@Override
public Phone make() {
return new XiaoMiPhone("骁龙");
}
}
public class HuaWeiPhone implements Phone {
public HuaWeiPhone(){
}
public HuaWeiPhone(String cpuType){
System.out.println("制造华为手机:" + cpuType);
}
@Override
public Phone make() {
return new HuaWeiPhone("麒麟");
}
}
public interface Computer {
Computer make();
}
public class XiaoMiComputer implements Computer {
public XiaoMiComputer (){
}
public XiaoMiComputer (String cpuType){
System.out.println("制造小米电脑:" + cpuType);
}
@Override
public Computer make() {
return new XiaoMiComputer("Inter");
}
}
public class HuaWeiComputer implements Computer {
public HuaWeiComputer(){
}
public HuaWeiComputer(String cpuType){
System.out.println("制造华为笔记本:" + cpuType);
}
@Override
public Computer make() {
return new HuaWeiComputer("麒麟");
}
}
public interface AbstractFactory {
Phone makePhone();
Computer makeComputer();
}
public class XiaoMiFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new XiaoMiPhone().make();
}
@Override
public Computer makeComputer() {
return new XiaoMiComputer().make();
}
}
public class HuaWeiFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new HuaWeiPhone().make();
}
@Override
public Computer makeComputer() {
return new HuaWeiComputer().make();
}
}
public class AbstractFactoryTest {
public static void main(String[] args) {
AbstractFactory xiaoMiFactory = new XiaoMiFactory();
Phone xiaoMiPhone = xiaoMiFactory.makePhone();
Computer xiaoMicomputer = xiaoMiFactory.makeComputer();
AbstractFactory huaWeiFactory = new HuaWeiFactory();
Phone huaweiPhone = huaWeiFactory.makePhone();
Computer huaWeiComputer = huaWeiFactory.makeComputer();
}
}
在JDK 中,java.util.Calendar的getInstance方法 就是经典的工厂模式(简单工厂)
根据 TimeZone zone, locale 创建对应的实例
工厂模式的意义
将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。
PS:看了这个JDK的源码,突然发现其实工作中经常写到这种代码,根据不同的type new不同的对象。
只不过用的都是if else。