使用傅里叶描述子识别形状(matlab)

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

文件: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();
    

    }
    }
    复制代码
      运行结果:

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

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

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

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

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

缺点

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

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

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

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

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

猜你喜欢

转载自blog.csdn.net/gumenghua_com1/article/details/112390433