设计模式原则

  • 开闭原则 对扩展开放,对修改关闭。
  • 依赖倒置原则 通过抽象使各个类或者模块不相互影响,实现松耦合。
  • 单一职责原则一个类、接口、方法只做一件事。
  • 接口隔离原则 尽量保证接口的纯洁性,客户端不应该依赖不需要的接口。
  • 迪米特法则又叫最少知道原则,一个类对其所依赖的类知道得越少越好。
  • 里氏替换原则 子类可以扩展父类的功能但不能改变父类原有的功能。
  • 合成复用原则尽量使用对象组合、聚合,而不使用继承关系达到代码复用的目的。

简单工厂模式

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
缺点扩展性不好 违反了开闭原则 对修改关闭

工厂类

可以看到我们工厂类提供了创建的方法 有三种 都是创建不同的产品的方法

/*** @Author jyl* @Date 2021/12/9 16:18* @Version 1.0* 简单工厂类*/
public class ICourseFactory {/*第一版本的创建模式有弊端 因为无法检测name*/
//        public ICourse create(String name){//        if("java".equals(name)){//            return new JavaCourse();
//        }else if("python".equals(name)){//            return new PythonCourse();
//        }else {//            return null;
//        }
//    }/*第二版根据全类名来创建*///    public ICourse create(String className){//        try {//            if (!(null == className || "".equals(className))) {//                return (ICourse) Class.forName(className).newInstance();
//            }
//
//        }catch (Exception e){//            e.printStackTrace();
//        }
//        return null;
//    }/*第三版使用反射创建*/public ICourse create(Class<? extends ICourse> clazz){try {if (null != clazz) {return clazz.newInstance();}}catch (Exception e){e.printStackTrace();}return null;}
}

产品类

这里看到我们有一个产品类型是录课 我们两个具体产品 录java课程和 录python课程 他们都实现了录课 他们都有录课方法只是录课的内容不同 也就是具体的实现类不同 这里的打印 录制java 录制python 代表的是不同产品 的不同逻辑产品类通用接口
这样做的坏处就是 我们每次扩展一个代码就必须去修改我们的工厂类 因为有这个问题所有 出现了 工厂方法模式

/*** @Author jyl* @Date 2021/12/9 16:14* @Version 1.0* 录制视频接口*/
public interface ICourse {/*** 录制视频* @return*/void record();
}

java课程

/*** @Author jyl* @Date 2021/12/9 16:15* @Version 1.0* 子类*/
public class JavaCourse implements ICourse {public void record() {System.out.println("录制Java课程");}
}

python课程

/*** @Author jyl* @Date 2021/12/9 16:15* @Version 1.0* 子类*/
public class PythonCourse implements ICourse {public void record() {System.out.println("录制Python课程");}
}

客户端调用

/*** @Author jyl* @Date 2021/12/9 16:21* @Version 1.0* 简单工厂客户端*/
public class SimpleFactoryTest {public static void main(String[] args) {/*不使用工厂配置*/
//        ICourse course = new JavaCourse();
//        course.record();//        /*第一版配置*/
//        ICourseFactory factory = new ICourseFactory();
//        ICourse course = factory.create("java");
//        course.record();/*第二版工厂配置使用全类名*/
//        ICourseFactory factory = new ICourseFactory();
//        ICourse course = factory.create("yongli.product.impl.JavaCourse");
//        course.record();ICourseFactory factory = new ICourseFactory();ICourse course = factory.create(JavaCourse.class);course.record();/*日期类jdk使用简单工厂模式案例*/Calendar.getInstance();/*slf4j 使用简单工厂案例*/LoggerFactory.getLogger(SimpleFactoryTest.class);}

Calendar.getInstance 使用简单工厂模式的例子


LoggerFactory.getLogger(); 使用简单工厂模式的例子


这里switch case 简单工厂

简单工厂方法模式

可以看到这次把工厂抽象把每个产品的创建分担到了每个具体的工厂 这个时候一定有和我一样的人再想都这样了 为啥不能直接new对象了 可以想一下 工厂模式解决的是创建时候的难题 比如我构造这个对象有很多setget 特定的创建方式 有些东西不想暴露给客户端 所以产生了这种这个工厂使用太单一,一种工厂只能生产一种产品

抽象工厂接口

/*** @Author jyl* @Date 2021/12/9 17:14* @Version 1.0* 工厂方法模式接口*/
public interface ICourseFactory {ICourse create();
}

实现工厂接口的具体工厂

/*** @Author jyl* @Date 2021/12/9 17:15* @Version 1.0* 方法工厂模式分担责任的产品创建工厂这里用来创建产品*/
public class JavaCourseFactory implements ICourseFactory {public ICourse create() {return new JavaCourse();}
}
/*** @Author jyl* @Date 2021/12/9 17:15* @Version 1.0*/
public class PythonCourseFactory implements ICourseFactory {public ICourse create() {return new PythonCourse();}
}

客户端调用

/*** @Author jyl* @Date 2021/12/9 16:21* @Version 1.0* 方法工厂客户端*/
public class FactorymethodTest {public static void main(String[] args) {ICourseFactory iCourseFactory = new JavaCourseFactory();iCourseFactory.create().record();}}

抽象工厂模式

抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖 对象的接口,无须指定他们具体的类。客户端(应用层)不依赖于产品类实例如何被创 建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对 象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从 而使客户端不依赖于具体实现。
产品族的概念
以前我们每次都是新增一个产品现在我们是每次新增为一个产品族 比如以前我们使用 有录课工厂 就要实现 java录课工厂类 和python录课工厂类 笔记工厂就要新增笔记工厂类和 java笔记和 python笔记 现在我们 直接把他们抽取出来 变成一个综合的工厂 叫做 java课程超级工厂 相当于 java笔记工厂和 java 笔记工厂的融合,这个时候python超级工厂也一样
就算以后出golang c++ 也只是新增一个超级工厂 。 这些超级工厂又因为是一个产品族 所以抽象为一个接口供大家继承


从上图中看出有正方形,圆形和菱形三种图形,相同颜色深浅的就代表同一个产品族, 相同形状的代表同一个产品等级结构。同样可以从生活中来举例,比如,美的电器生产 多种家用电器。那么上图中,颜色最深的正方形就代表美的洗衣机、颜色最深的圆形代 表美的空调、颜色最深的菱形代表美的热水器,颜色最深的一排都属于美的品牌,都是 美的电器这个产品族。再看最右侧的菱形,颜色最深的我们指定了代表美的热水器,那 么第二排颜色稍微浅一点的菱形,代表海信的热水器。同理,同一产品结构下还有格力 热水器,格力空调,格力洗衣机。
再看下面的这张图,最左侧的小房子我们就认为具体的工厂,有美的工厂,有海信工厂, 有格力工厂。每个品牌的工厂都生产洗衣机、热水器和空调。

顶层抽象工厂

/*** @Author jyl* @Date 2021/12/9 19:57* @Version 1.0* 最顶层抽象工厂模式*  每次创建一个新的产品族就新增一个创建方法*/
public interface CourseFactory {/*创建笔记产品*/INote createINote();/*创建录课产品*/IVideo createIVideo();}

java课程产品族工厂

/*** @Author jyl* @Date 2021/12/9 20:06* @Version 1.0* java产品族的工厂类实现抽象工厂接口*/
public class JavaCourseFactory implements CourseFactory {public JavaINoteImpl createINote() {return new JavaINoteImpl();}public IVideo createIVideo() {return new JavaIVideoImpl();}
}

产品等级结构接口

类别这来就是一个产品等级结构

/*** @Author jyl* @Date 2021/12/9 20:00* @Version 1.0* 课堂笔记产品族*/
public interface INote {/*写笔记*/void edit();}
/*** @Author jyl* @Date 2021/12/9 20:00* @Version 1.0*/
/*录课产品族的接口*/
public interface IVideo {/*录视频*/void record();
}

java产品的具体实现

/*** @Author jyl* @Date 2021/12/9 20:05* @Version 1.0* java笔记产品*/
public class JavaINoteImpl  implements INote {public void edit() {System.out.println("我在写java笔记");}
}
/*** @Author jyl* @Date 2021/12/9 20:06* @Version 1.0* java录课产品*/
public class JavaIVideoImpl  implements IVideo {/*录视频*/public void record() {System.out.println("我是录java视频");}
}

java客户端调用

/*** @Author jyl* @Date 2021/12/13 8:50* @Version 1.0*/
public class AbstractFactoryTest {public static void main(String[] args) {CourseFactory factory = new JavaCourseFactory();/*创建笔记产品*/factory.createINote().edit();/*创建录课产品*/factory.createIVideo().record();}}

新增一个python产品种族

通过以上带我们我们可以穿件 java 产品的一个产品种族了
我们下面要新增一个python产品种族

python课程产品族工厂

/*** @Author jyl* @Date 2021/12/13 8:54* @Version 1.0** python产品族工厂*/
public class PythonCourseFactory implements CourseFactory {public INote createINote() {return new PythonINoteImpl();}public IVideo createIVideo() {return new JavaIVideoImpl();}
}

Python产品的具体实现

/*** @Author jyl* @Date 2021/12/13 8:55* @Version 1.0*/
public class PythonINoteImpl implements INote {public void edit() {System.out.println("写python笔记");}
}
/*** @Author jyl* @Date 2021/12/13 8:56* @Version 1.0*/
public class PythonIVideoImpl implements IVideo {public void record() {System.out.println("python录课");}
}

可以可看到我们新增一个产品族 只需要实现抽象工厂 和其中定义好的产品结构就实现了一个产品种族

新增一个产品

现在我们不止有录课 写笔记了 我们还需要看源码 所以我们要增加一个产品结构那就是 看源码 ISource
我们 此刻我们的抽象工厂改变 新增了一个产品

抽象工厂类改变

/*** @Author jyl* @Date 2021/12/9 19:57* @Version 1.0* 最顶层抽象工厂模式*  每次创建一个新的产品族就新增一个创建方法*/
public interface CourseFactory {/*创建笔记产品*/INote createINote();/*创建录课产品*/IVideo createIVideo();/*创建看源码产品*/ISource createISource();
}

工厂的改变

/*** @Author jyl* @Date 2021/12/9 20:06* @Version 1.0* java产品族的工厂类实现抽象工厂接口*/
public class JavaCourseFactory implements CourseFactory {public JavaINoteImpl createINote() {return new JavaINoteImpl();}public IVideo createIVideo() {return new JavaIVideoImpl();}public ISource createISource() {return new JavaISourceImpl();}
}
/*** @Author jyl* @Date 2021/12/13 8:54* @Version 1.0** python产品族工厂*/
public class PythonCourseFactory implements CourseFactory {public INote createINote() {return new PythonINoteImpl();}public IVideo createIVideo() {return new JavaIVideoImpl();}public ISource createISource() {return new PythonISourceImpl();}
}

新增的产品接口

/*** @Author jyl* @Date 2021/12/13 9:06* @Version 1.0* 源码产品结构*/
public interface ISource {void look();
}

新增具体产品实现类

/*** @Author jyl* @Date 2021/12/13 9:12* @Version 1.0* java源码产品*/
public class JavaISourceImpl implements ISource {public void look() {System.out.println("我在看Java源码");}
}

/*** @Author jyl* @Date 2021/12/13 9:13* @Version 1.0* python产品*/
public class PythonISourceImpl implements ISource {public void look() {System.out.println("我在看python源码");}
}

上面的代码完整地描述了两个产品族 Java 课程和 Python 课程,也描述了两个产品等级 视频和笔记。抽象工厂非常完美清晰地描述这样一层复杂的关系。但是,不知道大家有 没有发现,如果我们再继续扩展产品等级,将源码 Source 也加入到课程中,那么我们的 代码从抽象工厂,到具体工厂要全部调整,很显然不符合开闭原则。
因此抽象工厂也是 有缺点的:
1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂 的接口。
2、增加了系统的抽象性和理解难度。 但在实际应用中,我们千万不能犯强迫症甚至有洁癖。在实际需求中产品等级结构升级 是非常正常的一件事情。我们可以根据实际情况,只要不是频繁升级,可以不遵循开闭 原则。代码每半年升级一次或者每年升级一次又有何不可呢?

工厂模式演进以及部分使用场景(简单工厂,工厂方法,抽象工厂)相关推荐

  1. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)

    园子里关于23种设计模式的博文已经可以说是成千上万.车载斗量.屯街塞巷.不计其数.数不胜数.摩肩接踵.汗牛充栋.车水马龙.门庭若市.琳琅满目直至让人眼花缭乱了.在这样的大环境下之所以来写设计模式类的博 ...

  2. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂) v阅读目录

    1楼留头头大神:http://www.cnblogs.com/toutou/p/4899388.html v阅读目录 v写在前面 v简单工厂模式 v工厂方法模式 v抽象工厂模式 v博客总结 v博客前言 ...

  3. java 三种工厂模式(简单工厂+工厂方法+抽象工厂)

    一.简单工厂模式 概述   简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的 实例,被创建的实例通常都具有共同的父类.因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因 ...

  4. 抽象工厂模式(优缺点、使用场景、具体实现)

    抽象工厂模式 1.优缺点 2.使用场景 3.具体实现 抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定他们具体的类 1.优缺点 优点: 1.具体产品在应用层的代码隔离,无需关系创建 ...

  5. 工厂模式(简单工厂 工厂方法 抽象工厂)

    简单工厂模式 简单工厂模式又叫做静态工厂方法模式(static Factory Method pattern),它是通过使用静态方法接收不同的参数来返回不同的实例对象(这些产品类继承自一个父类或接口) ...

  6. java为什么用工厂模式_【Java】为什么建议没事不要随便用工厂模式创建对象?...

    一般情况下,工厂模式分为三种更加细分的类型:简单工厂.工厂方法和抽象工厂.在这三种细分的工厂模式中,简单工厂.工厂方法原理比较简单,在实际的项目中也比较常用.而抽象工厂的原理稍微复杂点,在实际的项目中 ...

  7. 简单工厂 工厂方法 抽象工厂

    [找到一篇好文章] 作者:海粟007 原文址:http://www.cnblogs.com/Seasky/archive/2009/04/28/1385609.html 今天开始这个系列之前,心里有些 ...

  8. 简单工厂-工厂方法-抽象工厂

    目录 简单工厂 工厂方法 抽象工厂 前言 之前看书认真了解过这三种模式,但因为没有做记录,都给忘完了.现在重新分析网上的博客发现跟书里讲的不太一样,哎-.现在能做的就是把现在的理解给记录一下,若以后有 ...

  9. 简单工厂 工厂方法 抽象工厂 如何理解

    文章目录 前言 一.简单工厂 二.工厂方法 三.抽象工厂 总结 前言 简单工厂,工厂方法,抽象工厂,三者有什么区别? 搞清楚他们有什么弊端,以发展的角度去观察,理解会更加深入. 提示:以下是本篇文章正 ...

  10. 创建型模式:工厂模式(简单工厂+工厂方法+抽象工厂)

    一.引子 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰).Bmw(宝马).Audi(奥迪)),还雇了司机为他开车.不过,爆发户坐车时总是这样:上Benz车后跟司机说"开奔驰车!& ...

最新文章

  1. 2021世界人工智能大会最高奖项——卓越人工智能引领者奖(Super AI Leader,简称SAIL奖)在大会开幕式揭晓...
  2. Part2_4 Sqlite基础操作
  3. Latex \bibliographystyle+修改字体字号的大小
  4. Apache PDFbox快速开发指南
  5. openjdk8之编译和debug
  6. SQL Server 2008R2 连接本地数据库引擎
  7. 数据库的主键Id不是从1开始的
  8. Delphi中对URL进行编码和解码
  9. [转]高负载并发网站架构分析
  10. Linux消息队列实现进程间通信
  11. nginx 多php项目配置文件,nginx,_nginx配置多目录访问,nginx - phpStudy
  12. 量化交易接口UFX是什么?
  13. 深度 | 国产数据库到底行不行?金仓数据库审计性能实测
  14. 苹果待处理订单要多久_一个订单管理系统帮你轻松应对复杂的生产订单管理
  15. 如何建立个人的免费网站
  16. python的输入函数是什么意思_在Python中,用于获取用户输入的函数是
  17. 301跳转有什么用?为什么要做301跳转?
  18. 【光学】基于Matlab实现二维光子晶体的能带图和场
  19. XMind 常用快捷键(思维导图总结)
  20. idea配置有道翻译引擎

热门文章

  1. Hadoop3.1.3搭建集群
  2. 电脑耳机有声外放无声的解决方法
  3. c++自动抢购_淘宝 2020双十一最新版 全自动做任务软件 超级星秀猫 来了!上车~...
  4. vue结合element 输入框输入纯数字以及限制输入小数
  5. 【数据结构】以不完整拼音搜索通讯录算法设计
  6. Sprint回顾会议
  7. 关闭Dell笔记本触摸板
  8. LaTeX 008:比较方便的键入下划线的方式
  9. Word中如何删除某一页的页眉与页眉中的横线
  10. PYTHON应用行业,PYTHON就业方向