设计模式 - 创建型模式考点篇:工厂模式、建造者模式

这篇具有很好参考价值的文章主要介绍了设计模式 - 创建型模式考点篇:工厂模式、建造者模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、创建型模式

一句话概括

1.1、工厂模式

1.1.1、简单工厂模式(非 23 种经典设计模式)

概述

案例

1.1.2、静态工厂(扩展)

1.1.3、工厂方法模式

概念

案例

1.2、建造者模式

1.2.1、概念

1.2.2、案例

1.2.3、建造者模式扩展:链式编程底层

1.3、工厂方法模式 VS 建造者模式


一、创建型模式


一句话概括

创建型模式:教你如果创建对象.

1.1、工厂模式

1.1.1、简单工厂模式(非 23 种经典设计模式)

概述

简单工厂不是一种设计模式,反而比较像是一种编程习惯.

简单工厂包含一下角色:

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品 :实现或者继承抽象产品的子类
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品
案例

需求:设计一个咖啡店点餐系统.

思路:设计一个咖啡类(Coffee),并定义其两个子类(美式咖啡【AmericanCoffee】和拿铁咖啡 【LatteCoffee】);再设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。

以下代码为空架.

/**
 * 咖啡
 */
public abstract class Coffee {

    public abstract String getName();

    public void addSugar() {
        System.out.println("加糖");
    }

    public void addWeight() {
        System.out.println("加量");
    }

}
/**
 * 美式咖啡
 */
public class AmericanCoffee extends Coffee{

    @Override
    public String getName() {
        return "美式咖啡";
    }

}
/**
 * 拿铁咖啡
 */
public class LatteCoffee extends Coffee{

    @Override
    public String getName() {
        return "拿铁咖啡";
    }

}
/**
 * 咖啡店
 */
public class CoffeeStore {

    public Coffee orderCoffee(String type) {
        //1.根据订单类型选取对应的咖啡
        Coffee coffee = null;
        if (type == null || type.equals("")) {
            throw new RuntimeException("type 非法");
        } else if (type.equals("ac")) {
            coffee = new AmericanCoffee();
        } else if(type.equals("lc")) {
            coffee = new LatteCoffee();
        } else {
            throw new RuntimeException("type 非法");
        }
        //2.加糖加量
        coffee.addSugar();
        coffee.addWeight();
        return coffee;
    }

}
/**
 * 测试客户端
 */
public class ClientCoffee {

    public static void main(String[] args) {
        CoffeeStore store = new CoffeeStore();
        Coffee coffee = store.orderCoffee("ac");
        System.out.println(coffee.getName());
    }

}

可以产出上述代码中 Coffee 类为抽象产品,AmericanCoffee 和 LatteCoffee 为具体产品,但是没有抽象工厂.  以下使用 简单工厂模式 对上述代码进行改造.

public abstract class Coffee {

    public abstract String getName();

    public void addSugar() {
        System.out.println("加糖");
    }

    public void addWeight() {
        System.out.println("加量");
    }

}
public class AmericanCoffee extends Coffee {

    @Override
    public String getName() {
        return "美式咖啡";
    }

}
public class LatteCoffee extends Coffee {

    @Override
    public String getName() {
        return "拿铁咖啡";
    }

}
/**
 * 简单工厂模式
 */
public class SimpleCoffeeFactory {

    public Coffee createCoffee(String type) {
        //1.根据订单类型选取对应的咖啡
        Coffee coffee = null;
        if (type == null || type.equals("")) {
            throw new RuntimeException("type 非法");
        } else if (type.equals("ac")) {
            coffee = new AmericanCoffee();
        } else if(type.equals("lc")) {
            coffee = new LatteCoffee();
        } else {
            throw new RuntimeException("type 非法");
        }
        //2.加糖加量
        coffee.addSugar();
        coffee.addWeight();
        return coffee;
    }

}
public class CoffeeStore {

    public Coffee orderCoffee(String type) {
        //1.让工厂来创建对象
        SimpleCoffeeFactory factory = new SimpleCoffeeFactory();
        Coffee coffee = factory.createCoffee(type);
        //2.加料
        coffee.addWeight();
        coffee.addSugar();
        return coffee;
    }

}
public class ClientCoffee {

    public static void main(String[] args) {
        CoffeeStore store = new CoffeeStore();
        Coffee coffee = store.orderCoffee("ac");
        System.out.println(coffee.getName());
    }

}

上述代码中有了 SimpleCoffeeFactory ,使得 Coffee 的具体实现类和 CoffeeStore 解耦合,但是又产生了 CoffeeStore 和 SimpleCoffeeFactory 对象的耦合. 后期我们如果要加新的咖啡品种,势必需要修改 SimpleCoffeeFactory 的代码,违反了开闭原则.

优点:

解耦合:将对象的创建和业务逻辑层分开,避免将来修改客户端代码.  入股偶要实现新产品,直接修改工厂类,不需要再原客户端代码,更容易扩展.

缺点:

违背“开闭原则”:增加新产品时还需要修改工厂类代码.

1.1.2、静态工厂(扩展)

在实际的开发中也有一部分人将工厂类中的创建对象的功能定义为静态的,这个就是静态工厂模式,避免对象的重复创建.  他也不是属于 23 中设计模式中的.

/**
 * 简单工厂模式
 */
public class StaticCoffeeFactory {

    public static Coffee createCoffee(String type) {
        //1.根据订单类型选取对应的咖啡
        Coffee coffee = null;
        if (type == null || type.equals("")) {
            throw new RuntimeException("type 非法");
        } else if (type.equals("ac")) {
            coffee = new AmericanCoffee();
        } else if(type.equals("lc")) {
            coffee = new LatteCoffee();
        } else {
            throw new RuntimeException("type 非法");
        }
        //2.加糖加量
        coffee.addSugar();
        coffee.addWeight();
        return coffee;
    }

}

1.1.3、工厂方法模式

概念

定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。

工厂方法模式包含以下角色:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂 方法来创建产品。
  • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同 具体工厂之间一一对应。
案例

需求:设计一个咖啡店点餐系统,咖啡种类有美式咖啡和拿铁咖啡.

/**
 * 抽象产品: 咖啡类
 */
public abstract class Coffee {

    public abstract String getName();

    public void addSugar() {
        System.out.println("加糖");
    }

    public void addWeight() {
        System.out.println("加量");
    }

}
/**
 * 具体产品:美式咖啡类
 */
public class AmericanCoffee extends Coffee {

    @Override
    public String getName() {
        return "美式咖啡";
    }

}
/**
 * 具体产品:拿铁咖啡类
 */
public class LatteCoffee extends Coffee {

    @Override
    public String getName() {
        return "拿铁咖啡";
    }

}
/**
 * 抽象工厂: 咖啡工厂
 */
public interface CoffeeFactory {

    Coffee createCoffee();

}
/**
 * 具体工厂:美式咖啡工厂
 */
public class AmericanCoffeeFactory implements CoffeeFactory{

    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }

}
/**
 * 具体工厂:拿铁咖啡工厂
 */
public class LatteCoffeeFactory implements CoffeeFactory{

    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }

}
/**
 * 咖啡商店
 */
public class CoffeeStore {

    private CoffeeFactory factory;

    public void setFactory(CoffeeFactory factory) {
        this.factory = factory;
    }

    public Coffee orderCoffee() {
        //1.创建咖啡对象
        Coffee coffee = factory.createCoffee();
        //2.加料
        coffee.addWeight();
        coffee.addSugar();
        return coffee;
    }

}
public class ClientCoffee {

    public static void main(String[] args) {
        CoffeeStore store = new CoffeeStore();
//        AmericanCoffeeFactory factory = new AmericanCoffeeFactory();
        LatteCoffeeFactory factory = new LatteCoffeeFactory();
        store.setFactory(factory);
        Coffee coffee = store.orderCoffee();
        System.out.println(coffee.getName());
    }

}

优点:

使用便利:用户只需要知道具体的工厂名称就可以拿到产品,无须知道产品的具体创建过程.

满足“开闭原则”:当需要添加新的产品时,无需对原工厂进行修改,只需要添加具体的产品类和工厂即可.

缺点:

“类爆炸”:每增加一个产品就需要增加一个具体产品类和一个对应的具体工厂类,增加系统复杂度.

使用场景:

  • 重复代码 : 创建对象需要使用大量重复的代码 ;
  • 不关心创建过程 : 客户端 不依赖 产品类 , 不关心 实例 如何被创建 , 实现等细节 ;
  • 创建对象 : 一个类通过其子类来指定创建哪个对象 ;

1.2、建造者模式

1.2.1、概念

将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。例如电脑的主机由 cpu、内存、主板、显卡 构成,用户只需要指定主机的类型就可以得到相应的主机,无需知道内部的具体构造细节.

建造者模式包含如下角色:

  • 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
  • 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体 创建方法。在构造过程完成后,提供产品的实例。
  • 产品类(Product):要创建的复杂对象。
  • 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产 品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

1.2.2、案例

生产自行车是一个复杂的过程,它包含了车架,车座等组件的生产。而车架又有碳纤维,铝合金等材质 的,车座有橡胶,真皮等材质。对于自行车的生产就可以使用建造者模式。

/**
 * 产品类:自行车类
 */
public class Bike {

    //车架
    private String frame;
    //车座
    private String seat;

    public String getFrame() {
        return frame;
    }

    public void setFrame(String frame) {
        this.frame = frame;
    }

    public String getSeat() {
        return seat;
    }

    public void setSeat(String seat) {
        this.seat = seat;
    }

}
/**
 * 抽象建造者类
 */
public abstract class Builder {

    //这里只是一个空架子,还需要具体实现
    protected Bike bike = new Bike();

    //自行车的组成部分
    public abstract void buildFrame();
    public abstract void buildSeat();

    //构建自行车
    public abstract Bike createBike();

}
/**
 * 具体建造者类:捷安特建造者类
 */
public class GiantBuilder extends Builder{

    @Override
    public void buildFrame() {
        this.bike.setFrame("碳纤维车架");
    }

    @Override
    public void buildSeat() {
        this.bike.setSeat("橡胶车座");
    }

    @Override
    public Bike createBike() {
        return this.bike;
    }

}
/**
 * 具体建造者类:摩拜建造者类
 */
public class MobikeBuilder extends Builder {

    @Override
    public void buildFrame() {
        this.bike.setFrame("铝合金车架");
    }

    @Override
    public void buildSeat() {
        this.bike.setSeat("真皮车座");
    }

    @Override
    public Bike createBike() {
        return this.bike;
    }

}
/**
 * 指挥者类
 */
public class Director {

    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    /**
     * 指导构造
     * @return
     */
    public Bike construct() {
        //开始构建
        builder.buildFrame();
        builder.buildSeat();
        return builder.createBike();
    }

}
/**
 * 测试类
 */
public class Client {

    public static void main(String[] args) {
        //建造捷安特自行车
        showBike(new GiantBuilder());
        //建造摩拜自行车
        showBike(new MobikeBuilder());
    }

    private static void showBike(Builder builder) {
        Director director = new Director(builder);
        Bike bike = director.construct();
        System.out.println(bike.getFrame());
        System.out.println(bike.getSeat());
    }

}

优点:

解耦合:客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得 相同的创建过程可以创建不同的产品对象。

易扩展,符合开闭原则:如果有新的需求,通过实现一个新的建造者就可以完成,基本上不用修改其他代码.

缺点:

如果产品之间的差异性比较大,则不适合使用,因此使用范围受到一定的限制.

使用场景:

创建对象的过程比较负责,由多个部件构成,但构建的顺序是稳定的.

产品的构建过程和最终的表示是独立的.

1.2.3、建造者模式扩展:链式编程底层

建造者模式除了上述用途以外,在开发中还有一种常用的使用方式,就是当一个类构造器需要传入多个参数,此时创建这个类的实例,代码的可读性就会非常差,而且很容易引入新的错误. 此时就可以使用 链式编程底层 的方式对 建造者模式进行重构.

 重构后代码如下:

public class Phone {

    private String cpu;
    private String screen;
    private String memory;
    private String mainBoard;

    //私有构造,只对内提供
    private Phone(Builder builder) {
        this.cpu = builder.cpu;
        this.screen = builder.screen;
        this.memory = builder.memory;
        this.mainBoard = builder.mainBoard;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainBoard='" + mainBoard + '\'' +
                '}';
    }

    //链式编程构建
    public static class Builder {
        private String cpu;
        private String screen;
        private String memory;
        private String mainBoard;

        public Builder cpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        public Builder screen(String screen) {
            this.screen = screen;
            return this;
        }

        public Builder memory(String memory) {
            this.memory = memory;
            return this;
        }

        public Builder mainBoard(String mainBoard) {
            this.mainBoard = mainBoard;
            return this;
        }

        public Phone build() {
            return new Phone(this);
        }
    }

}
public class Client {

    public static void main(String[] args) {
        Phone phone = new Phone.Builder()
                .cpu("intel")
                .screen("三星屏幕")
                .mainBoard("华硕")
                .memory("金士顿")
                .build();
        System.out.println(phone);
    }

}

重构后使用起来更加方便,提高开发效率.  但是从软件设计上,对程序员的要求比较高.

1.3、工厂方法模式 VS 建造者模式

工厂方法模式注重是整体对象的创建方式;而建造者模式注重的是部件一步一步的创建出一个复杂对象的过程 .

比如我要制造一个超人,如果使用工厂方法模式,直接产生出来就是一个力大无穷、能飞,内裤外穿的超人;而如果使用建造者模式,则需要组装 手、头、脚、躯干、裤头... 一个超人就诞生了.

设计模式 - 创建型模式考点篇:工厂模式、建造者模式,设计模式,设计模式,建造者模式文章来源地址https://www.toymoban.com/news/detail-726711.html

到了这里,关于设计模式 - 创建型模式考点篇:工厂模式、建造者模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式:创建者模式 - 建造者模式

    将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况。 由于实现了构建和装配的解耦。不同的构建器,相同的

    2023年04月24日
    浏览(47)
  • 设计模式—创建型模式之建造者模式

    如果我们创建的对象比较复杂,但其细节还要暴露给使用者,这样就需要用到建造者模式。 建造者设计模式, 屏蔽过程,而不屏蔽细节。 比如我们有一个手机类,定义如下: 我们想定制自己的一个手机,可以先定义一个抽象的构建者; 如果我们想定制一个 香蕉手机 ,就可

    2024年02月06日
    浏览(43)
  • 设计模式之创建型模式---建造者模式

    建造者模式是一种创建型设计模式,其核心思想是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。该模式将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合起来构建出复杂对象。 建造者模式的基本构成通常包括

    2024年04月15日
    浏览(48)
  • 【创建型设计模式】C#设计模式之建造者模式

    参考代码:

    2024年02月13日
    浏览(42)
  • 设计模式(四):创建型之建造者模式

    设计模式系列文章 设计模式(一):创建型之单例模式 设计模式(二、三):创建型之工厂方法和抽象工厂模式 设计模式(四):创建型之原型模式 设计模式(五):创建型之建造者模式 设计模式(六):结构型之代理模式 设计模式(七):结构型之适配器模式 设计模式(八):结构型之装

    2024年02月07日
    浏览(49)
  • 【设计模式】第7节:创建型模式之“建造者模式”

    Builder模式 ,中文翻译为 建造者模式 或者 构建者模式 ,也有人叫它 生成器模式 。 在创建对象时,一般可以通过构造函数、set()方法等设置初始化参数,但当参数比较多,或者参数之间有依赖关系,需要进行复杂校验时,以上两种方法就不适用了。此时可以采用建造者模式

    2024年02月06日
    浏览(33)
  • 【Java 设计模式】创建型之建造者模式

    在软件开发中,建造者模式是一种创建型设计模式, 它将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示 。建造者模式通常包括一个指导者(Director)类和多个建造者(Builder)类,指导者负责组织建造者的构建过程,而建造者负责具体的构建步

    2024年01月21日
    浏览(56)
  • 23种设计模式【创建型模式】详细介绍之【建造者模式】

    可以查看专栏设计模式:设计模式 建造者模式是一种创建型设计模式,用于构建复杂对象。它将对象的构建过程与其表示分离,允许您以可控和可扩展的方式构建对象。在本文中,我们将深入探讨建造者模式,解释其核心概念,并提供Java示例代码来演示如何使用建造者模式

    2024年02月08日
    浏览(42)
  • (一)创建型设计模式:3、建造者模式(Builder Pattern)

    目录 1、建造者模式含义 2、建造者模式的讲解 3、使用C++实现建造者模式的实例 4、建造者模式的优缺点 5、建造者模式VS工厂模式 1、建造者模式含义 The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process ca

    2024年02月13日
    浏览(39)
  • Java设计模式之创建型-建造者模式(UML类图+案例分析)

    目录 一、基本概念 二、UML类图 三、角色设计  四、案例分析 五、总结 建造者模式是一种创建型设计模式,它使我们将一个复杂对象的构建步骤分离出来,使得同样的构建过程可以创建不同的表示。该模式的目的是将构建复杂对象的过程抽象化,从而减少代码的重复和复杂

    2024年02月15日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包