设计模式: 组合构造器

假设我们要创建一个Person类,Person类需要如下信息

  // 地址信息
  std::string street_address, post_code, city;

  // 工作信息
  std::string company_name, position;
  int annual_income = 0;

设计一个足够炫酷的构造器,ta看起来像这样

  Person p = Person::create()
    .lives().at("123 London Road").with_postcode("SW1 1GB").in("London")
    .works().at("PragmaSoft").as_a("Consultant").earning(10e6);

怎么做到的,首先我们创建了一个 PersonBuilderBase类 定义如下

class PersonBuilderBase
{
protected:
  Person& person;
  explicit PersonBuilderBase(Person& person)
    : person{ person }
  {
    cout << "PersonBuilderBase ctor, " << &person << endl;
  }
public:
  operator Person() const
  {
    return std::move(person);
  }

  // builder facets

  PersonAddressBuilder lives() const;
  PersonJobBuilder works() const;
};

看的出来构造函数是Protected的,也就是说,他作为一个基类,不要直接去使用他,而是要让子类去继承。

我们设计了三个子类去继承 PersonBuilderBase类。

分别是PersonJobBuilderPersonAddressBuilderPersonBuilder
出来PersonBuilderBaselives方法和works方法分别会返回前两个子类

其中 JobBuilder 构建工作相关的信息,AddressBuilder构建地址相关的信息
JobBuilder

class PersonJobBuilder : public PersonBuilderBase
{
  typedef PersonJobBuilder Self;
public:
  explicit PersonJobBuilder(Person& person)
  : PersonBuilderBase { person }
  {
  }

  Self& at(std::string company_name)
  {
    person.company_name = company_name;
    return *this;
  }

  Self& as_a(std::string position)
  {
    person.position = position;
    return *this;
  }

  Self& earning(int annual_income)
  {
    person.annual_income = annual_income;
    return *this;
  }
};

返回引用是为了支持流式操作
AddressBuilder

class PersonAddressBuilder : public PersonBuilderBase
{
  typedef PersonAddressBuilder Self;
public:
  explicit PersonAddressBuilder(Person& person)
  : PersonBuilderBase{person}
  {
  }

  Self& at(std::string street_address)
  {
    person.street_address = street_address;
    return *this;
  }

  Self& with_postcode(std::string post_code)
  {
    person.post_code = post_code;
    return *this;
  }

  Self& in(std::string city)
  {
    person.city = city;
    return *this;
  }
};

最后是PersonBuilder

class PersonBuilder : public PersonBuilderBase
{
  Person p;
public:
  PersonBuilder(): PersonBuilderBase{p}
  {
    cout << "PersonBuilder ctor" << endl;
  }
};

最后就可以像开头一样

  Person p = Person::create()
    .lives().at("123 London Road").with_postcode("SW1 1GB").in("London")
    .works().at("PragmaSoft").as_a("Consultant").earning(10e6);

使用了,create显然是个静态方法,返回一个PersonBuilder

PersonBuilder Person::create()
{
  return PersonBuilder{};
}

但是写这么复杂真的好吗?可能得等我遇到实际问题才知道了

总结与反思

  1. 为了使用户使用构造器,往往需要把原本被构造的对象的构造函数藏起来不让用
  2. 通常支持流式操作
  3. 构造器往往有的良好的语义性(值每个函数都清楚的解释了自己在干什么)

但是我觉得除非有良好的文档,要不然如何去构造一个对象都得去实际查看别人的代码,看看别人是怎么构造的。但是实际上就自己公司的代码来看,文档这东西属于稀罕物件。。。
构造器看上去确实挺优雅的,但是用不用,还是具体再说吧,毕竟设计模式并不是什么放之四海皆准的准则,只要大的方向没变就好

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Java设计模式是一种在Java编程中广泛应用的软件设计方法。它提供了解决常见软件设计问题的可重用方案。下面是对一些常见的设计模式的简要解释: 1. 单例模式:确保一个类只有一个实例,并提供一个全局访问点,避免了多个实例的资源浪费和冲突。 2. 工厂模式:通过一个共同的接口来创建对象,屏蔽具体实现细节,使代码解耦合,提高代码的可扩展性和可维护性。 3. 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体类,可以动态切换不同的实现。 4. 原型模式:通过复制现有对象来创建新对象,提供了一种快速创建对象的方法,并且可以修改对象的属性。 5. 建造者模式:将一个复杂的对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。 6. 适配器模式:将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而不能合作的类可以一起工作。 7. 桥接模式:将抽象部分与其实现部分分离,使它们都可以独立地变化,提高了代码的灵活性和可扩展性。 8. 装饰器模式:动态地给一个对象添加一些额外的职责,同时又不改变其接口,可以在不修改原始类代码的情况下进行功能扩展。 9. 观察者模式:定义了一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。 10. 迭代器模式:提供一种顺序访问聚合对象中的各个元素的方法,而又不暴露其内部结构。 总之,Java设计模式为开发者提供了一些有效的解决方案,有助于提高代码质量、可维护性和可扩展性。在设计和开发Java应用程序时,合理使用这些模式可以有效地提升工作效率和代码健壮性。 ### 回答2: Java设计模式是一套被广泛应用于软件开发中的指导原则和解决方案,主要用于解决特定问题或优化代码结构和性能。下面是几种常见的Java设计模式的解释: 1. 单例模式:确保一个类只有一个实例,并提供全局访问点。通过定义一个私有构造方法和静态方法来控制对象的创建和访问。 2. 工厂模式:将对象的创建和使用分离,通过工厂类创建对象实例,隐藏具体的实现细节。可以根据不同条件选择不同的工厂类。 3. 观察者模式:定义了一种一对多的关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。通过定义主题和观察者接口来进行通信。 4. 适配器模式:将一个类的接口转换成客户端所期待的另一个接口,使得原本不兼容的类可以协同工作。通过创建适配器类来进行接口的转换。 5. 装饰器模式:动态地给一个对象增加一些额外的职责,而不需要改变其原始类。通过创建装饰器类来包装原始对象,并在调用原始对象的方法前后加入新的行为。 6. 策略模式:定义了一系列的算法,并将其封装起来,使其可以互相替换。通过定义一个策略接口和多个具体策略类来实现不同的算法。 7. 外观模式:提供一个统一的接口,用来访问子系统中一群接口的集合。通过创建一个外观类来封装子系统中的多个接口,提供简化的访问方式。 8. 模板方法模式:定义一个操作中的算法骨架,并允许子类为一个或多个步骤提供实现。通过创建一个抽象模板类和多个具体实现类来实现算法骨架的复用。 总之,Java设计模式提供了一些通用的解决方案,可以帮助开发者更好地设计和组织代码,提高代码的可维护性和易读性。不同的设计模式适用于不同的场景,开发者可以根据具体的需求选择合适的模式。 ### 回答3: Java设计模式是一种对常见编程问题的解决方案的总结和抽象,它提供了一套可复用的设计思想和设计方法,通过这些思想和方法,开发人员可以更好地组织和设计自己的代码,提高代码的可维护性和可重用性。 1. 单例模式:确保一个类只有一个实例,并提供一个全局访问点来访问该实例。 2. 工厂模式:将对象的创建和使用分离,通过工厂类来创建对象,使代码更灵活、可扩展和可维护。 3. 抽象工厂模式:提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定具体的类。 4. 建造者模式:通过一个指挥者来统一组装产品的过程,使构建过程和表示分离,可以构建出不同的产品对象。 5. 原型模式:通过复制现有对象来创建新对象,避免了对象的频繁创建和销毁。 6. 适配器模式:将一个类的接口转换成客户希望的另一个接口,使得原本不兼容的类可以协同工作。 7. 装饰器模式:动态地给一个对象添加一些额外的职责,而不会影响其它对象。 8. 代理模式:用一个代理对象来控制对真实对象的访问,可以在不修改真实对象的情况下增加额外的功能。 9. 桥接模式:将抽象部分与它的实现部分分离,使它们可以独立地变化。 10. 组合模式:将对象组合成树状结构,以表示"部分整体"的层次结构,使客户端统一对待单个对象和对象的组合。 11. 迭代器模式:提供一种顺序访问容器对象的方法,不暴露容器的内部结构。 12. 观察者模式:定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会自动被通知并更新。 13. 策略模式:将可变的行为封装起来,并使其在不同的具体实现中可以互换使用。 14. 模板方法模式:定义了一个操作中的算法框架,将一些步骤延迟到子类中实现,使得子类可以改变算法的结构。 15. 状态模式:允许一个对象在其内部状态改变时改变其行为,对象看起来像是改变了其类。 16. 备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后可以将该对象恢复到原先保存的状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值