栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

软件体系结构与设计模式-孙玉山老师-第二章-抽象方法模式(创建型模式)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

软件体系结构与设计模式-孙玉山老师-第二章-抽象方法模式(创建型模式)

软件体系结构与设计模式-孙玉山老师 第二章 抽象方法模式(创建型模式) 一、抽象工厂模式的引入 01 抽象工厂模式的主要例子

现在假设有多个结构相同的产品层次类

问题:我们是否仍然使用工厂方法模式?

一些想法

对于每个产品层次类,我们构造一个工厂层次类
下图中使用的三个创建者

注释:这不是很好,因为有太多的Creator类 —— 还有其他更好的解决方法吗?

新的解决方案——请注意以下产品结构相同

二、抽象工厂模式理论 01 抽象工厂模式类图

02 抽象工厂模式介绍
  • 抽象工厂模式简介
    • 抽象工厂模式采用与工厂方法模式相同的概念
      抽象工厂创建者是一个类,它提供了一个接口来生成一组对象
      在Java编程语言中,它可以实现为一个界面和一个抽象类
  • 抽象工厂模式的组件
    • 一族(相关的)层次类
      工厂接口,带有几个实现子类(子类个数与每个产品层次类的个数相同)
      每个工厂子类都负责创建所有的Product层次类的指定的子类对象
03 抽象工厂模式使用
  • 何时使用抽象工厂模式?
    • 当客户对象想要创建一族层次类的某个子类对象,而不想知道到底是哪个子类对象被创建了。
    • 当客户端对象想要创建一组相关的、依赖的类的一个实例,而不需要知道要实例化哪个具体的类时,使用抽象工厂模式。
  • 如果不使用抽象工厂模式,将会发生什么?
    • 如果我们不使用抽象工厂,那么在创建此类实例时,选择适当类所需的实现需要出现在所有地方。
      需要使用大量的条件语句。
  • Client对象怎样使用抽象工厂模式?
    • 回答:使用具体的工厂子类创建Product子类对象,而不必知道到底哪个子类对象被创建类。
    • Client对象利用这些具体的工厂来创建对象,因此,不需要知道实际实例化的是哪个具体类。
04 工厂方法模式与抽象工厂模式的区别

1、产品不同

(1)对于工厂方法模式,产品是一个单一产品类层次结构

(2)对于抽象工厂模式,产品是一组产品类层次结构

2、有关可扩展性

(1)工厂方法模式遵循开闭原则,同时

(2)抽象工厂模式只部分遵循开闭原则

2.5、关于开闭原则——两种情况

  • Case1

    • 如果你添加一个ProductA3和ProductB3,也是创造者类层次结构需要添加类CreatorC。在此情况下,抽象工厂模式满足开闭原则
  • Case2

    • 如果你添加了一个新产品 hierarchy ProductC,然后你需要在ConcreteCreator1,ConcreteCreator2添加一个新方法“+getObjC: ProductC”
    • 这意味着您需要修改现有的工厂类层次结构,因此它不遵循开闭原则
    • 层次结构:层次结构
三、抽象工厂模式设计实例 01 实例描述

让我们设计一个web应用程序来查询不同类型建筑的特征。
考虑两种类型的建筑:住宅和共管公寓。

此外,建筑可以是任何一种——Super or Medium
因为House和Condo代表了两种产品,每一种产品都可以分为super和medium,所以我们可以使用下面的抽象工厂模式

02 实例分析
  • 设计原因

    • 如果我们不使用抽象工厂模式,而只是直接调用类House和Condo中的方法,
      然后在ClientGUI中,我们需要编写大量的条件语句,这不利于扩展和维护
  • 设计好处

    • 责任分离

      选择和实例化适当的House/Condo实现者的责任可以从应用程序对象转移到单独的指定抽象工厂类。

    • 关于建筑工厂类的层次结构
      它只声明所需的接口,而将类选择和实例化的实际实现细节留给其实现者。

  • 关于client对象AbstractFactoryGUI类:

    它使用实现BuildingFactory接口的具体工厂实例来创建对象 表示不同类型和类别的房子,而不需要知道需要实例化的实际具体类。

    Client对象不需要知道这些具体工厂类的存在。

  • AbstractFactoryGUI如何工作?

    • 当搜索按钮被点击之后,一个建筑物类别和类型组合被选中,客户端AbstractFactoryGUI调用在抽象BuildingFactory类中的静态的getBuildingFactory(String type)方法
    • getBuildingFactory(String type) 方法创建了一个适当的工厂对象并且返回它作为一个BuildingFactory类型的对象。
    • 工厂对象在内部从它控制的建筑家族(SuperHouse/SuperCondo或MediumHouse/MediumCondo)中创建一个适当类的实例,并将其作为House/Condo类型的对象返回。
    • Client类AbstractFactoryGUI甚至不知道House/Condo的存在
  • client AbstractFactoryGUI 不需要不同的具体的House/Condo类。

    • 它只是调用House/Condo接口声明的方法,比如: getHouseInfo or getCondoInfo
03 实例源代码
public interface House {
   public String getHouseInfo();
}

public class SuperHouse implements House {
   public String getHouseInfo() {
      return "superHouse.html";
   }
}

public class MediumHouse implements House{
   public String getHouseInfo() {
      return "mediumHouse.html";
   }
}

public interface Condo {
	public String getCondoInfo();
}

public class SuperCondo implements Condo{
   public String getCondoInfo(){
      return "superCondo.html";
   }
}

public class MediumCondo implements Condo{
   public String getCondoInfo(){
      return "mediumCondo.html";
   }
}

public abstract class BuildingFactory{
  	public static final String SUPER = "Super Class";
  	public static final String MEDIUM = "Medium Class";
  	public abstract House getHouse();
  	public abstract Condo getCondo();

  	public static BuildingFactory getBuildingFactory(String type){
  		 BuildingFactory bf = null;
  		 if (type.equals(BuildingFactory.SUPER)){
			bf = new SuperBuildingFactory();
		 }
  		 else if (type.equals(BuildingFactory.MEDIUM)){
			bf = new MediumBuildingFactory();
             // 真奇怪,在超类中创建子类对象。你可曾遇到过?
		 }
         return bf;
    }
}

public class MediumBuildingFactory extends BuildingFactory {
   public House getHouse(){
      return new MediumHouse();
   }
   public Condo getCondo(){
	  return new MediumCondo();
   }
}

public class SuperBuildingFactory extends BuildingFactory {

   public House getHouse(){
      return new SuperHouse();
   }
   public Condo getCondo(){
	  return new SuperCondo();
   }
}

public class AbstractFactoryGUI extends JFrame {
      class ButtonListener implements ActionListener {
      public void actionPerformed(ActionEvent ae) {
		if (ae.getActionCommand().equals(AbstractFactoryGUI.SEARCH)) {

		    String clas = (String) cmbHouseClass.getSelectedItem();
		    String type = (String) cmbHouseType.getSelectedItem();

		    BuildingFactory bf = BuildingFactory.getBuildingFactory(clas);

		    if (type.equals(AbstractFactoryGUI.HOUSE)) {
		         House hs = bf.getHouse();
		         String fileNm = hs.getHouseInfo();
		         putHouseInfoToScreen(fileNm);
		    }
		    if (type.equals(AbstractFactoryGUI.CONDO)) {
		         Condo cd = bf.getCondo();
		         String fileNm = cd.getCondoInfo();
		         putHouseInfoToScreen(fileNm);
		     }
		 }  
}}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/966921.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号