有整个程序和测试图片在文档里,测试可运行。

文件:n459.com/file/25127180-478678004

以下内容无关:

-------------------------------------------分割线---------------------------------------------

一,概述
  抽象工厂模式为一个产品家族提供了统一的创建接口。当需要这个产品家族的某一系列的时候,可以从抽象工厂中选出相对应的系列来创建一个具体的工厂类别。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

相关术语:

产品等级结构:产品的继承结构,与类的继承相似。例如笔记本是一个抽象的类,那么华为笔记本、苹果和联想笔记本就是其子类。

产品族:指同一个工厂生产的,位于不同的产品等级结构的一组产品。例如华为笔记本、手机、路由器等都产自华为,笔记本的等级结构不同,构成一个产品族。

抽象工厂:是一个接口,抽象工厂模式的核心,包含对多个产品等级结构的声明,任何工厂类都必须实现这个接口。

具体工厂:是抽象工厂的实现,负责实例化某个产品族中的产品对象。例如华为工厂生产华为笔记本、手机、路由器等。
二,产品族和产品等级结构图
  我们以一个品牌为一个产品族,电脑、手机、路由器为产品等级,每一个品牌都有自己的产品族,这就构成一个完整产品群;

横向代表一族,纵向代表一个等级,横纵交集代表某一个品牌的某一个产品(比如下图中交集的点为电脑),请看下图;

三,UML图
  这个类图其实比较简单,简单说明下:

产品顶级接口:主要被产品抽象类实现;

产品抽象类:某个具体产品要实现的类;

具体实现类:具体产品实现,比如华为路由器实现自抽象类AbstractRouter;

工厂接口:工厂接口中定义创建每个产品方法;

具体华为工厂:实现工厂接口,创建华为一族产品(路由器、手机、电脑);

四,具体代码实现
  代码中我们以华为产品为例,分别定义华为电脑、手机、路由器产品,从UML类图中可以看出我们的产品结构层级比较清晰,现在我们先设计我们产品。

下面开始定义产品;

产品顶级接口;

复制代码
package pattern.abstractfactory.product;
/**

  • 定义产品接口
  • @author ningbeibei
    */
    public interface InterfaceProduct {
    void get();
    }
    复制代码
      定义计算机抽象类并实现产品InterfaceProduct 接口;

复制代码
package pattern.abstractfactory.product;
/**

  • 定义计算机产品抽象类,并实现产品接口InterfaceProduct
  • @author ningbeibei
    */
    public abstract class AbstractComputers implements InterfaceProduct {
    public abstract void get();
    }
    复制代码
      定义手机抽象类并实现产品InterfaceProduct 接口;

复制代码
package pattern.abstractfactory.product;
/**

  • 定义手机抽象类,并实现产品接口InterfaceProduct
  • @author ningbeibei
    */
    public abstract class AbstractPhone implements InterfaceProduct {
    public abstract void get();
    }
    复制代码
      定义路由器抽象类并实现产品InterfaceProduct 接口;

复制代码
package pattern.abstractfactory.product;
/**

  • 定义路由器产品抽象类,并实现InterfaceProduct接口
  • @author ningbeibei
    */
    public abstract class AbstractRouter implements InterfaceProduct{
    public abstract void get();
    }
    复制代码
      定义华为电脑具体实现类,继承AbstractComputers抽象类;

复制代码
package pattern.abstractfactory.product;
/**

  • 华为电脑实现类
  • @author ningbeibei
    */
    public class HuaWeiComputer extends AbstractComputers{
    @Override
    public void get() {
    System.out.println(“华为笔记本”);
    }
    }
    复制代码
      定义华为手机具体实现类,继承AbstractPhone抽象类;

复制代码
package pattern.abstractfactory.product;
/**

  • 华为手机实现类,
  • @author ningbeibei
    */
    public class HuaWeiPhone extends AbstractPhone{
    @Override
    public void get() {
    System.out.println(“华为手机”);
    }
    }
    复制代码
      定义华为路由器具体实现类,继承AbstractRouter抽象类;

复制代码
package pattern.abstractfactory.product;
/**

  • 华为路由器
  • @author ningbeibei
    */
    public class HuaWeiRouter extends AbstractRouter {
    @Override
    public void get() {
    System.out.println(“华为品牌路由器”);
    }
    }
    复制代码
      下面开始定义工厂;

定义工厂接口;

复制代码
package pattern.abstractfactory.factory;
import pattern.abstractfactory.product.InterfaceProduct;
/**

  • 定义产品工厂接口,
  • @author ningbeibei
    */
    public interface InterfactFactory {
    //手机产品
    InterfaceProduct createPhone();
    //电脑产品
    InterfaceProduct createComputer();
    //路由器产品
    InterfaceProduct createRouter();
    }
    复制代码
      具体工厂实现类,实现 InterfactFactory 接口;

复制代码
package pattern.abstractfactory.factory;
import pattern.abstractfactory.product.HuaWeiComputer;
import pattern.abstractfactory.product.HuaWeiPhone;
import pattern.abstractfactory.product.HuaWeiRouter;
import pattern.abstractfactory.product.InterfaceProduct;
/**

  • 华为工厂
  • @author ningbeibei
    /
    public class HuaWeiFactory implements InterfactFactory {
    /
    *

    • 创建电脑对象并返回
      /
      @Override
      public InterfaceProduct createComputer() {
      return new HuaWeiComputer();
      }
      /
      *
    • 创建手机对象并返回
      /
      @Override
      public InterfaceProduct createPhone() {
      return new HuaWeiPhone();
      }
      /
      *
    • 创建路由器对象并返回
      */
      @Override
      public InterfaceProduct createRouter() {
      return new HuaWeiRouter();
      }
      }
      复制代码
        测试类;

复制代码
package pattern.abstractfactory;
import pattern.abstractfactory.factory.HuaWeiFactory;
import pattern.abstractfactory.factory.InterfactFactory;
import pattern.abstractfactory.product.InterfaceProduct;
/**

  • 抽象工厂模式测试类
  • @author ningbeibei
    */
    public class test {
    public static void main(String[] args) {
    //创建华为品牌工厂
    InterfactFactory huawei = new HuaWeiFactory();
    //通过华为工厂获取华为电脑对象
    InterfaceProduct computer = huawei.createComputer();
    computer.get();
    //通过华为工厂获取华为手机对象
    InterfaceProduct phone = huawei.createPhone();
    phone.get();
    //通过华为工厂获取华为路由器对象
    InterfaceProduct router = huawei.createRouter();
    router.get();
    }
    }
    复制代码
      运行结果;

五,抽象工厂方法模式如何扩展产品族
  抽象工厂模式对于横向扩展方便,对于纵向扩展非常困难,也就是说:假如我们要扩展一个新的品牌,比如扩展一个小米品牌,小米产品有电脑、手机、路由器,扩展新品牌就是横向扩展,非常方便,但是我们要给小米添加一个电饭煲产品却非常困难,这就是纵向扩展,所以在使用抽象工厂模式时一定要选择合适的场景,也就是在不同场景中使用最适合的模式才是设计模式的精髓。

下面我们就来横向扩展一个新品牌的产品族,需要添加电脑、手机、路由器具体类(小米品牌)代码如下;

小米电脑

复制代码
package pattern.abstractfactory.product;
/**

  • 小米电脑,继承自 AbstractComputers 抽象类
  • @author ningbeibei
    */
    public class MiComputer extends AbstractComputers {
    @Override
    public void get() {
    System.out.println(“小米电脑”);
    }
    }
    复制代码
      小米手机

复制代码
package pattern.abstractfactory.product;
/**

  • 小米手机,继承自 AbstractPhone 抽象类
  • @author ningbeibei
    */
    public class MiPhone extends AbstractPhone {
    @Override
    public void get() {
    System.out.println(“小米手机”);
    }
    }
    复制代码
      小米路由器

复制代码
package pattern.abstractfactory.product;
/**

  • 小米路由器,继承自 AbstractRouter 抽象类
  • @author ningbeibei
    */
    public class MiRouter extends AbstractRouter{
    @Override
    public void get() {
    System.out.println(“小米路由器”);
    }
    }
    复制代码
      添加小米具体工厂类

复制代码
package pattern.abstractfactory.factory;
import pattern.abstractfactory.product.InterfaceProduct;
import pattern.abstractfactory.product.MiComputer;
import pattern.abstractfactory.product.MiPhone;
import pattern.abstractfactory.product.MiRouter;
/**

  • 小米工厂,实现 InterfactFactory 接口
  • @author ningbeibei
    */
    public class MiFactory implements InterfactFactory{
    //小米手机
    @Override
    public InterfaceProduct createPhone() {
    return new MiPhone();
    }
    //小米电脑
    @Override
    public InterfaceProduct createComputer() {
    return new MiComputer();
    }
    //小米路由器
    @Override
    public InterfaceProduct createRouter() {
    return new MiRouter();
    }
    }
    复制代码
      最后编写测试类,代码中红色字体为新扩展的品牌产品;

复制代码
package pattern.abstractfactory;
import pattern.abstractfactory.factory.HuaWeiFactory;
import pattern.abstractfactory.factory.InterfactFactory;
import pattern.abstractfactory.factory.MiFactory;
import pattern.abstractfactory.product.InterfaceProduct;
/**

  • 抽象工厂模式测试类

  • @author ningbeibei
    */
    public class test {
    public static void main(String[] args) {
    // 创建华为品牌工厂
    InterfactFactory huawei = new HuaWeiFactory();
    // 通过华为工厂获取华为电脑对象
    InterfaceProduct computer = huawei.createComputer();
    computer.get();
    // 通过华为工厂获取华为手机对象
    InterfaceProduct phone = huawei.createPhone();
    phone.get();
    // 通过华为工厂获取华为路由器对象
    InterfaceProduct router = huawei.createRouter();
    router.get();

     // 创建小米品牌工厂InterfactFactory Mifactory = new MiFactory();// 通过小米工厂获取小米电脑对象InterfaceProduct micomputer = Mifactory.createComputer();micomputer.get();// 通过小米工厂获取小米手机对象InterfaceProduct miphone = Mifactory.createPhone();miphone.get();// 通过小米工厂获取小米路由器对象InterfaceProduct mirouter = Mifactory.createRouter();mirouter.get();
    

    }
    }
    复制代码
      运行结果:

注意:通过上面的品牌扩展我们发现,横向扩展容易,纵向扩展非常困难,代码可以非常方便的扩展一个品牌已有的产品,但要扩展一个未定义的产品却异常困难,比如要扩展一个华为平板,需要修改工厂逻辑代码,新增产品结构,这显然不符合设计模式开闭原则,所以在使用时一定要考虑清楚,确定不在有新的产品等级扩展。

六,优点和缺点及使用场景
优点

抽象工厂模式隔离了具体类的生成, 使得客户并不需要知道什么被创建。 由于这种隔离,更换一个具体工厂就变得相对容易, 所有的具体工厂都实现了抽象工厂中定义的那些公共接口, 因此只需改变具体工厂的实例, 就可以在某种程度上改变整个软件系统的行为。

当一个族中的多个对象被设计成一起工作时, 它能够保证客户端始终只使用同一个族中的对象。

增加新的族很方便, 无须修改已有系统, 符合“开闭原则”。

缺点

增加新的等级结构麻烦, 需要对原有系统进行较大的修改, 甚至需要修改抽象层代码,这显然会带来较大的不便, 违背了“开闭原则”。
使用场景

一个系统不应当依赖于具体类实例如何被创建、 组合和表达的细节, 这对于所有类型的工厂模式都是很重要的, 用户无须关心对象的创建过程, 将对象的创建和使用解耦。

系统中有多于一个的族, 而每次只使用其中某一族。 可以通过配置文件等方式来使得用户可以动态改变族, 也可以很方便地增加新的族。

等级结构稳定, 设计完成之后, 不会向系统中增加新的等级结构或者删除已有的等级结构。

七,写的不足之处还望批评指正
  写的不足之处请在评论区指出,便于我及时更正错误,避免给读者带来误解,希望大家多多提意见。

使用傅里叶描述子识别形状(matlab)相关推荐

  1. OpenCV实现傅里叶描述子(下): 形状特征提取

    简述 在前面的更新中 OpenCV实现傅里叶描述子(上): 边界重建 有简单介绍了一下傅里叶描述子的内容,并利用边界的傅里叶描述子对其进行重建,使边界变得更加的平滑.但傅里叶描述子还是以其作为图像中形 ...

  2. 傅里叶描述子、HOG特征描述子原理及matlab代码

    一.傅里叶描述子 傅里叶描述子的作用是用来描述图像的轮廓信息,具有平移.旋转.尺度不变性特征. 对于一幅图像,通过傅里叶描述子获得其图像轮廓信息,其本质就是空间.频域变换问题.通过将图像中的像素点进行 ...

  3. 图像特征之傅里叶描述子

    使用C++.opencv获取轮廓的傅里叶描述子 傅里叶描述子是一种图像特征,具体来说,是一个用来描述轮廓的特征参数.其基本思想是用物体边界信息的傅里叶变换作为形状特征,将轮廓特征从空间域变换到频域内, ...

  4. matlab求26个字母的组合方式,26个字母识别 用matlab实现的

    沉水门板别动皮孔跑进立冬派赴四坝.黏菌查找铃鸟赔率溺水冷寂.乐派梁肉娲皇常情小米厘米势篇心静.兰田青岩奴仆旗云倒班.华池不符归参鼓室孟浪灯标凄壮. 难缠六尺獾类纽卡车神拐卖风险序乐.浅薄单恋行宪工价临 ...

  5. 开发物体识别桌、_科研人员开发突破性的技术,允许盲人识别形状和物体

    一项令人难以置信的新技术正在让失明人士有能力识别形状和物体,而这些形状和物体都是在他们的大脑上"画出来"的.一篇描述该技术的研究论文刚刚发表在<细胞>杂志上,正如Sci ...

  6. 【钟表识别】基于计算机视觉实现钟表时间识别含Matlab源码

    1 简介 基于计算机视觉实现钟表时间识别含Matlab源码​ 2 部分代码 function [time_clock]= read(filepath) I = imread(filepath); [e ...

  7. 基于最优傅里叶描述子的粘连条锈病孢子图像分割

    小麦条锈病是小麦锈病的一种,是中国小麦生产中分布广.传播快.危害面积大的重要病害之一,特大流行年份减产可达60%以上,甚至绝产.小麦条锈病越夏孢子数是判断条锈病是否爆发的关键参数之一,但现有方法对粘连 ...

  8. 人脸识别 pca matlab,基于PCA的人脸识别的Matlab实现代码

    基于PCA的人脸识别算法 --Matlab Face recognition Based on PCA 目录 人脸识别技术是基于人的脸部特征,对输入的人脸图象或者视频流 . 首先判断其是否存在人脸 , ...

  9. opencv-python 人脸检测,边缘检测,识别形状,图像分割,OCR,OMR,验证码识别,二维码识别,行人检测等应用解决思路

    opencv-python作为经典的计算机视觉,图片处理平台,可以用来开发很多基础应用,关于opencv-python里边函数的应用小结如下,欢迎讨论: 人脸检测 一般用 haarCascade 车牌 ...

最新文章

  1. 创建零填充JavaScript数组的最有效方法?
  2. 替代触发器如何加判断 条件_《小逻辑》:如何设定目标,制定计划,做出更好的选择...
  3. 跨域解决请求限制(script标签)(热门搜索出现对应的词条)
  4. Windows 10如何连接和使用局域网内的打印机(非网络打印机)亲测有效、绝对管用,不定时更新!!!(更新日期2021.09.14,如有不会的可以直接私我)
  5. socket网络编程python_python之路8:Socket网络编程
  6. 使用帅气的cordic算法进行坐标系互转及log10的求解
  7. 11.频域里的卷积——介绍,傅里叶变换和卷积,快速傅里叶变换(FFT)_1
  8. linux环境下通过nginx实现tomcat集群
  9. rbf神经网络python预测代码_RBF神经网络预测
  10. java hsqldb数据库_【DataBase】Hsqldb的简单使用
  11. Android测试方法总结汇总
  12. Godot官网新闻翻译 - 2016年
  13. 用python处理excel视频教程_从零基础开始用Python处理Excel数据(第一季)课件+资料...
  14. 电脑计算机c盘打不开怎么办,电脑的c盘炸了打不开电脑了怎么处理
  15. √ JavaSE - 02.怎么打印回形数
  16. 【字符转换】——全角和半角转换
  17. 牛客练习赛51c-勾股定理
  18. IP地址,子网掩码、默认网关,DNS的设置和工作原理(总结)
  19. iOS Mansory 等间隔或等宽高排列多个控件
  20. 微信小程序直播如何提升人气

热门文章

  1. 习题 ct7_1: 卡片拼数1★
  2. 基于Android开发游戏,在百度手机应用里面上线
  3. 一些VR渲染优化方法
  4. 系统视频教学视频教程_自由泳教学视频,全套系统教程【收藏版】
  5. Learning FileMaker Go 15 学习FileMaker Go 15 Lynda课程中文字幕
  6. 【讨论会论文翻译】 The Future of Video Coding
  7. 关于组合数据类型的基础知识学习总结
  8. HyperWorks学习笔记(六)
  9. Jedis的了解和使用、Jedis使用Redis事务
  10. MySQL中delimiter的作用