首页 技术 正文
技术 2022年11月10日
0 收藏 509 点赞 2,358 浏览 4155 个字

  提供一个创建一系列或相互依赖对象的接口,而无须指定他们具体的类。例如某些系统可能需要为用户提供一系列相关对象,但系统不希望用户直接使用new运算符实例化这些对象,而是应当由系统来控制这些对象的创建,否则用户不仅要清楚知道哪些类来创建对象,而且必须要清楚这些对象之间是如何相关的,使得用户代码和这些类型形成耦合,不利维护,一般会包括以下四种角色:

  • 抽象产品(Product):一个抽象类或接口,负责定义具体产品必须实现的方法;
  • 具体产品(ConcreteProduct):具体产品是一个类,如果Product是一个抽象类,那么具体产品是它的子类;如果Product是一个接口,那么具体产品是它的接口类;
  • 抽象工厂(AbstractFactory):一个接口或抽象类,负责定义若干个抽象方法;
  • 具体工厂(ConcreteFactory):如果抽象工厂是一个抽象类,具体工厂就是它的子类;如果是个接口就是它的实现类。具体工厂重写抽象工厂中的抽象方法,使该方法返回具体的产品实例。

  抽象工厂的UML类图如下所示:

Java的设计模式(4)–抽象工厂模式

  抽象工厂模式的优点:

    • 可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱藕。
    • 可以方便的为用户配置一系列对象,用户使用不同的具体工厂就能得到一组相关的对象,同时也能避免用户混用不同系列中的对象。
    • 可以随时增加具体工厂为用户提供一组相关的对象。

  抽象工厂模式的应用场景:

    • 系统需要为用户提供多个对象,但不希望用户直接使用new对象,希望用户和创建对象类的解耦
    • 系统需要为用户提供多个相关的对象,以便用户联合使用他们,但又不希望用户来决定这些对象是如何关联的。
    • 系统需要为用户提供一系列对象,但值需要用户知道这些对象有哪些方法可以用,不需要用户知道这些对象的创建过程

下面以服饰工厂生产衣服为例,为用户提供西装和牛仔裤:

1. 抽象产品,裤子和上衣

public abstract class Trousers {    public abstract int getWaitstSize();
public abstract int getHeight();
public abstract String getName();
}
public abstract class UpperClothes {    public abstract int getChestSize();
public abstract int getHeight();
public abstract String getName();
}

2. 具体产品

public class CowBoyTrouers  extends Trousers {
private int waistSize;
private int height;
private String name; public CowBoyTrouers(int waistSize, int height, String name) {
this.waistSize = waistSize;
this.height = height;
this.name = name;
} @Override
public int getWaitstSize() {
return waistSize;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
}}
public class WesternTrouers extends Trousers {    private int waistSize;
private int height;
private String name; public WesternTrouers(int waistSize, int height, String name) {
this.waistSize = waistSize;
this.height = height;
this.name = name;
} @Override
public int getWaitstSize() {
return waistSize;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
}
}
public class CowBoyUpperClothes extends UpperClothes {    private int chextSize;
private int height;
private String name; public CowBoyUpperClothes(int chextSize, int height, String name) {
super();
this.chextSize = chextSize;
this.height = height;
this.name = name;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
} @Override
public int getChestSize() {
return chextSize;
}
}
public class WesternUpperClothes extends UpperClothes {    private int chestSize;
private int height;
private String name; public WesternUpperClothes(int chestSize, int height, String name) {
super();
this.chestSize = chestSize;
this.height = height;
this.name = name;
} @Override
public int getChestSize() {
return chestSize;
} @Override
public int getHeight() {
return height;
} @Override
public String getName() {
return name;
}}

3. 抽象工厂

public abstract class ClotherFactory {    public abstract UpperClothes createUpperClothes(int chestSize,int height);
public abstract Trousers createTrousers(int waistSize,int height);
}

4.具体工厂,一个负责生产西装,一个负责制作牛仔

public class BJClotherFactory extends ClotherFactory {    @Override
public UpperClothes createUpperClothes(int chestSize, int height) {
return new WesternUpperClothes(chestSize,height,"北京牌西服上衣");
} @Override
public Trousers createTrousers(int waistSize, int height) {
return new WesternTrouers(waistSize, height,"北京牌西服裤子");
}}
public  class SHClothesFactory extends ClotherFactory {    @Override
public UpperClothes createUpperClothes(int chestSize, int height) {
return new CowBoyUpperClothes(chestSize, height, "上海牌牛仔上衣");
} @Override
public Trousers createTrousers(int waistSize, int height) {
return new CowBoyTrouers(waistSize, height, "上海牌牛仔裤子");
}}

上面这些类就是一个小框架,可以使用这个小框架编写自己的类。应用程序在使用抽象工厂模式时,只和抽象的产品、抽象工厂以及具体工厂打交道,用户只需要了解抽象产品有哪些方法即可,不需要知道有哪些具体产品。下列代码列出了一个应用程序的类。

public class Shop {    private UpperClothes cloth;
private Trousers trouser;
public void giveSuit(ClotherFactory factory,int chestSize,int waistSize,int height){
this.cloth = factory.createUpperClothes(chestSize, height);
this.trouser = factory.createTrousers(waistSize, height);
showMess();
}
private void showMess() {
System.out.println("<套装信息>");
System.out.println(cloth.getName()+":");
System.out.print("胸围:"+cloth.getChestSize());
System.out.println(" 身高:"+cloth.getHeight());
System.out.println(trouser.getName()+":");
System.out.print("腰围:"+trouser.getWaitstSize());
System.out.println(" 身高"+trouser.getHeight());
}
}
public class Application {    public static void main(String[] args) {
Shop shop = new Shop();
ClotherFactory facory = new BJClotherFactory();
shop.giveSuit(facory, 110, 82, 170);
facory = new SHClothesFactory();
shop.giveSuit(facory, 120, 88, 180);
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,129
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,601
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,444
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,218
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,852
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,940