首页 > 其他分享 >设计模式-建造者模式

设计模式-建造者模式

时间:2023-09-06 14:33:53浏览次数:31  
标签:建造 Builder character 模式 abstract Character new 设计模式 public

建造者模式是一种创建型的设计模式, 将一个对象的创建过程拆分成一个个小的部分, 每次决定其中的一个细节, 构建出一个复杂对象

对象的创建过程被拉长分散, 可能会经历一系列的复杂决策, 最终才会形成我们需要的对象

对象拥有多个参数, 或者拥有包含多个参数的构造函数, 通过建造者模式可以相对自由地构造对象

建造者模式的作用

  • 通过拆分对象的创建步骤, 降低对象的构建复杂度, 使用者并不需要知道复杂对象的所有创建细节
  • 由于拆分了对象的创建步骤, 可以有效降低构造对象时的心智负担
  • 拆分出的建造者可以重复使用, 大大提高了代码的复用性

建造者模式适用于什么场景

当一个类的构造函数中有多个参数(一般大于四个), 并且这些参数中有些必填, 有些非必填时, 使用建造者模式可以降低心智负担

例如需要创建一个角色, 这个角色有参数 姓名 职业 武器 防具 力量 智力 等级 等参数, 除了姓名之外的所有参数都是可选的

这种情况下使用建造者模式, 可以通过 角色建造者 类来一步一步设置这些参数, 最后调用 创建角色 方法生成角色对象

传统建造者模式的类图

--- title: 建造者模式 --- classDiagram Item <|-- Weapon Item <|-- Armor Profession <|-- Mage Weapon <|-- Staff Weapon <|-- Buckler Armor <|-- Hood Armor <|-- Leather Armor <|-- Belt CharacterDirector ..> Builder MageBuilder --|> Builder Character <.. Builder Character <.. MageBuilder Character -- CharacterDirector class Builder{ # Character character + SetName(string) + SetProfession() + AddWeapon() + AddArmor() + AddStrenght() + AddIntelligence() + GetCharacter(): Character } class MageBuilder{ # Character character + SetName(string) + SetProfession() + AddWeapon() + AddArmor() + AddStrenght() + AddIntelligence() + GetCharacter(): Character } class Character{ + string Name + Profession Profession + Weapon[] Weapons + Armor[] Armors + int Strength + int Intelligence } class CharacterDirector{ + Build(Builder): Character } class Item{ + Buff(Character) } class Weapon{ + Buff(Character) } class Staff{ + Buff(Character) } class Buckler{ + Buff(Character) } class Armor{ + Buff(Character) } class Hood{ + Buff(Character) } class Leather{ + Buff(Character) } class Belt{ + Buff(Character) } class Profession{ + string Name } class Mage{ + string Name }

代码

定义我们需要构造的 Character

// 首先构造法师职业
public abstract class Profession
{
    public string Name { get; set; }
}
public class Mage : Profession
{
    public Mage()
    {
        Name = "法师";
    }
}
// 其次定义装备, 每个不同的装备可以给任务提供不同的Buff加成
public abstract class Item
{
    public abstract void Buff(Character character);
}
public abstract class Weapon : Item { }
public abstract class Armor : Item { }
public class Staff : Weapon
{
    public override void Buff(Character character)
    {
        character.Intelligence += 10;
    }
}
public class Buckler : Weapon
{
    public override void Buff(Character character)
    {
        character.Intelligence += 2;
        character.Strength += 5;
    }
}
public class Hood : Armor
{
    public override void Buff(Character character)
    {
        character.Intelligence += 5;
        character.Strength += 5;
    }
}
public class Leather : Armor
{
    public override void Buff(Character character)
    {
        character.Intelligence += 2;
        character.Strength += 15;
    }
}
public class Belt : Armor
{
    public override void Buff(Character character)
    {
        character.Intelligence += 15;
        character.Strength += 15;
    }
}
// 最后是一个简单的角色人物

public class Character
{
    public Character() { }
    public Character(Character character)
    {
        Name = character.Name;
        Profession = character.Profession;
        Weapons = character.Weapons;
        Armors = character.Armors;
        Strength = character.Strength;
        Intelligence = character.Intelligence;
    }
    public string Name { get; set; }
    public Profession Profession { get; set; }
    public List<Weapon> Weapons { get; set; }
    public List<Armor> Armors { get; set; }
    public int Strength { get; set; }
    public int Intelligence { get; set; }
}

然后定义人物的建造者 builder

public abstract class Builder
{
    protected Character character;
    public abstract Builder SetName(string name);
    public abstract Builder SetProfession();
    public abstract Builder AddWeapon();
    public abstract Builder AddArmor();
    public abstract Builder AddStrength();
    public abstract Builder AddIntelligence();
    public abstract Character GetCharacter();
}
public class MageBuilder : Builder
{
    public MageBuilder(string name = null)
    {
        character = new Character();
        SetName(name).SetProfession();
    }
    public override Builder AddArmor()
    {
        List<Armor> armors = new List<Armor> { new Hood(), new Leather(), new Belt() };
        character.Armors ??= new List<Armor>();
        character.Armors.AddRange(armors);
        return this;
    }
    public override Builder AddIntelligence()
    {
        character.Intelligence++;
        return this;
    }
    public override Builder AddStrength()
    {
        character.Strength++;
        return this;
    }
    public override Builder AddWeapon()
    {
        List<Weapon> weapons = new List<Weapon> { new Staff(), new Buckler() };
        character.Weapons ??= new List<Weapon>();
        character.Weapons.AddRange(weapons);
        return this;
    }
    public override Character GetCharacter()
    {
        var result = new Character(character);
        result.Armors.ForEach(item => item.Buff(result));
        result.Weapons.ForEach(item => item.Buff(result));
        return result;
    }
    public override Builder SetName(string name)
    {
        character.Name = name;
        return this;
    }
    public override Builder SetProfession()
    {
        character.Profession = new Mage();
        return this;
    }
}

最后定义一个简单的装配类, 通过builder获取character

public class CharacterDirector
{
    public Character Build(Builder builder)
    {
        return builder
                .AddWeapon()
                .AddArmor()
                .AddStrength()
                .AddIntelligence()
                .GetCharacter();
    }
}

如何去使用

Builder builder = new MageBuilder();
builder.SetName("菜鸟法师");
CharacterDirector director = new CharacterDirector();
Character character1 = director.Build(builder);
// 精英法师多用点装备应该是正常的
builder.SetName("精英法师").AddIntelligence().AddStrength().AddArmor().AddWeapon();
Character character2 = director.Build(builder);

通过复用builder可以构造出不同属性的人物

简化版建造者

前面的经典版建造者模式在实际使用的时候比较繁琐, 需要经历 director --> builder --> character

下面介绍一个简化版本的建造者, 省略掉 director, 直接在 builder 里完成构建

简化版类图

--- title: 简化版建造者模式 --- classDiagram Item <|-- Weapon Item <|-- Armor Profession <|-- Mage Weapon <|-- Staff Weapon <|-- Buckler Armor <|-- Hood Armor <|-- Leather Armor <|-- Belt MageBuilder --|> Builder Character <.. Builder Character <.. MageBuilder class Builder{ # string Name # Profession Profession # Weapon[] Weapons # Armor[] Armors # int Strength # int Intelligence + SetName(string) + SetProfession(Profession) + AddWeapon(Weapon) + AddArmor(Armor) + AddStrenght(int) + AddIntelligence(int) + Build(): Character } class MageBuilder{ # string Name # Profession Profession # Weapon[] Weapons # Armor[] Armors # int Strength # int Intelligence + SetName(string) + SetProfession(Profession) + AddWeapon(Weapon) + AddArmor(Armor) + AddStrenght(int) + AddIntelligence(int) + Build(): Character } class Character{ + string Name + Profession Profession + Weapon[] Weapons + Armor[] Armors + int Strength + int Intelligence } class Item{ + Buff(Character) } class Weapon{ + Buff(Character) } class Staff{ + Buff(Character) } class Buckler{ + Buff(Character) } class Armor{ + Buff(Character) } class Hood{ + Buff(Character) } class Leather{ + Buff(Character) } class Belt{ + Buff(Character) } class Profession{ + string Name } class Mage{ + string Name }

代码

人物部分的代码不需要进行修改

只需要修改 Builder 部分, 然后移除 CharacterDirector

public class MageBuilder : Builder
{
    public override Builder AddArmor(Armor armor)
    {
        Armors ??= new List<Armor>();
        Armors.Add(armor);
        return this;
    }
    public override Builder AddIntelligence(int intelligence)
    {
        Intelligence += intelligence;
        return this;
    }
    public override Builder AddStrength(int strength)
    {
        Strength += strength;
        return this;
    }
    public override Builder AddWeapon(Weapon weapon)
    {
        Weapons ??= new List<Weapon>();
        Weapons.Add(weapon);
        return this;
    }
    public override Builder SetName(string name)
    {
        Name = name;
        return this;
    }
    public override Builder SetProfession(Profession profession)
    {
        Profession = profession;
        return this;
    }
    public override Character Build()
    {
        var character = new Character()
        {
            Name = Name,
            Weapons = Weapons.ToList(),
            Armors = Armors.ToList(),
            Profession = Profession,
            Intelligence = Intelligence,
            Strength = Strength,
        };
        Weapons.ForEach(item => item.Buff(character));
        Armors.ForEach(item => item.Buff(character));
        return character;
    }
}
public abstract class Builder
{
    protected string Name;
    protected Profession Profession;
    protected List<Weapon> Weapons;
    protected List<Armor> Armors;
    protected int Strength;
    protected int Intelligence;
    public abstract Builder SetName(string name);
    public abstract Builder SetProfession(Profession profession);
    public abstract Builder AddWeapon(Weapon weapon);
    public abstract Builder AddArmor(Armor armor);
    public abstract Builder AddStrength(int strength);
    public abstract Builder AddIntelligence(int intelligence);
    public abstract Character Build();
}

如何使用简化版建造者

Builder builder = new MageBuilder();
builder.SetName("菜鸟法师")
.SetProfession(new Mage())
.AddWeapon(new Staff())
.AddWeapon(new Buckler())
.AddArmor(new Hood())
.AddArmor(new Leather())
.AddArmor(new Belt());

var character1 = builder.Build();
builder.SetName("精英法师").AddStrength(100).AddIntelligence(100);
var character2 = builder.Build();

标签:建造,Builder,character,模式,abstract,Character,new,设计模式,public
From: https://www.cnblogs.com/CollapseNav/p/17679391.html

相关文章

  • 结构型设计模式-组合(对象树) Composite
    简介组合模式又叫对象树,将对象按照树形结构串起来,呈现出局部和整体相同的特性。树中每个节点都由两部分组成,首先节点有自己的业务数据,其次节点内可以含有子节点集合。比如盒子中可以放物品,也可以放其他小盒子,小盒子里又可以放物品和其他更小的盒子。当计算盒子的物品价格时,只......
  • 结构型设计模式-桥接(模块化) Bridge
    简介桥接模式可将一系列紧密相关的、水平等级的类,转变为组合关系,形成垂直等级关系。如抽象类Color、Shape,分别有RedColor、BlueColor、CircleShape、SquareShape的实现类,那么想创建红色方形,则可以将Shape类中持有Color引用,动态向Shape中注入Color实现即可。否则分别......
  • 结构型设计模式-适配器 Adapter
    结构型设计模式-适配器Adapterdate:April13,2021slug:design-pattern-adapterstatus:Publishedtags:设计模式type:Page简介适配器模式是一种结构型设计模式,它能使接口不兼容的对象能够相互合作角色Client接口/Target目标接口用户使用的接口Adaptee被......
  • 创建型设计模式-原型 Prototype
    简介原型模式支持按照一个对象为模板,创建出另一个一模一样的对象。简单说就是把A对象的属性,都赋值到B上,注意必须是深拷贝,即clone后的AB关联的对象是不同的对象。角色抽象原型类定义clone方法具体实现类实现clone方法类图代码classPrototype{p......
  • 创建型设计模式-单例 Singleton
    简介全局共用一个对象,好处是对象只实例化一次,减少资源占用角色单例类返回本类的唯一一个实例代码classSingleton{privatestatic$instances=[];protectedfunction__construct(){}protectedfunction__clone(){}publicfunction__wa......
  • 学习笔记-设计模式-创建型模式-工厂模式
    工厂模式工厂模式是一种创建者设计模式,细分之下可以分成三类简单工厂模式,工厂方法模式和抽象工厂模式。简单工厂模式最简单的工厂模式,它采用静态方法的方式来决定应该应该生产什么商品。publicclassStoreFactory{publicstaticICommoditygetCommodityService(Integ......
  • 【原创】基于QT编写的支持IPv4/IPv6双协议栈,TCP/UDP双模式,DLL内存加载的模块化远控木
    本人已经本科毕业一年有余,在平常实习过程中,发现大佬都对我的本科毕设--双协议栈远控木马感兴趣。据我所知,目前流行的C2远控软件中,MSF支持IPv4和IPv6,但是MSF生成的单个木马只是支持其中的一种协议,而不是双协议栈。CobaltStrike目前尚无IPv6的使用案例。其他支持双协议栈的C2软件......
  • 快速构建商业模式,企业在云服务器选购上有什么需要注意的?
    云服务器是一种基于云计算技术的虚拟化服务,它可以为用户提供灵活、可扩展、高效的计算资源。云服务器的优势在于可以根据业务需求随时调整配置,节省成本,提高效率。但是,云服务器的选择不仅仅要考虑价格和性能,还要考虑服务质量,因为这关系到用户的业务稳定性和安全性。服务质量是指云服......
  • TCC模式原理
        ......
  • 持币生息理财模式系统开发(源码搭建)
    持币生息钱包即代币持有者通过质押、投票、委托和锁定代币等行为获取区块奖励以及分红等收益。通俗一点讲,就是一种持币者“以币生币”的投资方式,有点类似于银行的储蓄生息(持币生息),所以我们通常叫它POS权益质押经济。区块链是什么意思?区块链的定义:区块链是一个共享的、不可改变的......