设计模式(2)创造型设计模式

创建型模式

  • 创建型模式
      • 1.工厂模式
          • 1.1 抽象工厂模式(Abstract factory)
          • 1.2 工厂方法模式(Factory Method)
          • 1.3 简单工厂模式(Simple Factory)
      • 2. 建造者模式(Builder)
      • 3. 原型模式(Prototypes)
      • 4. 单例模式
      • 5. 创建型模式之间的联系和区别

创建型模式

前提:为一个电脑游戏创建一个迷宫,忽略迷宫的诸多细节,仅仅关注迷宫是怎样被创建的。

定义:将迷宫定义为一系列房间(Room),房间的四面要么是一堵墙(Wall),要么是一扇门(Door)。

//房间四个面
enum Direction{ North, South, East, West};
//房间
class Room{...}
//墙
class Wall{...}
//门
class Door{...}
//迷宫
class Maze{...}
//迷宫游戏
class MazeGame{...}

一个简单的迷宫创建函数,如下:

Maze* MazeGame::CreateMaze()
{
	Maze *aMaze = new Maze;
	Room *r1 = new Room(1);
	Room *r2 = new Room(2);
	Door *dr = new Door(r1,r2);
	aMaze->addRoom(r1);
	aMaze->addRoom(r2);
	r1->setSide(North, new Wall);
	r1->setSide(South, dr);
	r1->setSide(East, new Wall);
	r1->setSide(West, new Wall);
	r2->setSide(North, new Wall);
	r2->setSide(North, new Wall);
	r2->setSide(North, new Wall);
	r2->setSide(North, dr);
	return aMaze;
}

这个函数的缺点在于: 对迷宫布局硬编码,改变布局意味着需要改变这个函数本身,容易产生错误,且不利于重利用。试想一下,重用该迷宫的布局,但是迷宫中的部件和来原来不一致了,例如现在的门是施了魔法的,需要咒语才能开启等等。在这种情况下,改变的最大障碍就是对被实例化的类进行硬编码。

创建型模型提供了多种不同方法从实例化它们的代码中除去对这些具体类的显示引用:

  1. 如果CreateMaze调用虚函数而不是显式构造来创建它需要的房间、门和墙壁;那么可以通过创建一个MazeGame的子类并重定义这些虚函数,从而改变被实列化的类。正如工厂方法模式
  2. 如果传递一个对象给CreateMaze作参数来创建房间、墙壁和门,那么可以通过传递不同的参数来改变这些部件的类。正如抽象工厂模式
  3. 如果传递一个对象给CreateMaze,这个对象可以在它所建造的迷宫中增加房间、墙壁和门的操作,来创建一个新的迷宫。那么可以通过继承当方式来改变迷宫被建造的方式,正如建造者模式
  4. 如果CreateMaze由多种原型的房间、墙壁和门对象参数化,它拷贝并将这些对象增加到迷宫中。正如原型模式
  5. 单例模式可以保证每个游戏中仅有一个迷宫存在,而且所有的游戏对象都可以迅速的访问它。

1.工厂模式

工厂模式定义:
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,而无需指定它们具体的类,实例化的类是哪一个由子类决定。工厂模式将对象的实例化过程封装在一个工厂类中,使得客户端代码与具体类解耦,提供了一种灵活、可扩展的对象创建机制。

工厂模式的核心思想是将对象的创建过程封装在工厂类中,客户端代码通过与工厂类进行交互来获取所需的对象,而不需要直接实例化具体产品类。这种解耦的设计使得客户端代码更加灵活,可以通过切换具体工厂类来创建不同的产品对象。

工厂模式有以下几种常见的变体:

  1. 简单工厂模式(Simple Factory Pattern):使用一个单独的工厂类来创建所有的产品对象,通过传递不同的参数给工厂方法来选择创建哪种产品
  2. 工厂方法模式(Factory Method Pattern):每个具体产品都有对应的工厂类,客户端通过调用具体工厂类来创建具体产品对象
  3. 抽象工厂模式(Abstract Factory Pattern):提供一个抽象工厂接口,具体工厂类实现该接口并负责创建一系列相关或相互依赖的产品对象(把一系列工厂方法归结到一起)
1.1 抽象工厂模式(Abstract factory)

抽象工厂结构图:
在这里插入图片描述

在抽象工厂模式中,通常有以下几个角色:
抽象工厂(Abstract Factory):定义了创建产品的接口,包含了创建产品的抽象方法。
具体工厂(Concrete Factory):实现了抽象工厂接口,负责实际创建具体产品的对象。
抽象产品(Abstract Product):定义了产品的接口,是具体产品类的共同父类或接口。
具体产品(Concrete Product):实现了抽象产品接口,是工厂模式所创建的对象。

用抽象工厂来实现迷宫创建,代码如下:

class MazeFactory
{
	virtual Maze *MakeMaze(){return new Maze;}
	virtual Wall *MakeWall(){return new Wall;}
	virtual Room *MakeRoom(int n){return new Room(n);}
	virtual Door *MakeDoor(Room* r1, Room* r2){return new Door(r1,r2);}
}
//建造迷宫的程序使用MazeFactory作为参数,程序便能指定创建的房间、门、墙壁类型
Maze* MazeGame::CreateMaze(MazeFactor& factory)
{
	Maze *aMaze = factory.MakeMaze();
	Room *r1 = factory.MakeRoom(1);
	Room *r2 = factory.MakeRoom(2);
	Door *dr = factory.MakeDoor(r1,r2);
	aMaze->addRoom(r1);
	aMaze->addRoom(r2);
	r1->setSide(North, factory.MakeWall());
	r1->setSide(South, dr);
	r1->setSide(East, factory.MakeWall());
	r1->setSide(West, factory.MakeWall()l);
	r2->setSide(North, factory.MakeWall());
	r2->setSide(North, factory.MakeWall());
	r2->setSide(North, factory.MakeWall());
	r2->setSide(North, dr);
	return aMaze;
}
//创建一个MazeFactory的子类EnchanteMazeFactory,这是一个创建了施加魔法的迷宫工厂,EnchanteMazeFactory将重定义不同的成员函数并返回Room、Wall等不同的子类
class EnchanteMazeFactory : public MazeFactory
{
	...
}
//创建迷宫
MazeGame game;
EnchanteMazeFactory  factory;
game.CreateMaze(factory);
1.2 工厂方法模式(Factory Method)

工厂方式模式定义:
定义一个用于创建对象的接口,让子类决定实例化具体的类。Factory Method使一个类的实例化延迟到其子类中。

工厂方法结构图,如下:
在这里插入图片描述
适用性:

  • 当一个类不知道它所必须创建的对象的类的时候。
  • 当一个类希望由它的子类来指定它所创建的对象的时候。

工厂方法的一个潜在问题是它们可能为了创建适当的Product对象而迫使你创建Creator的子类,在c++种可以通过模板解决这种问题,如下:

class Creator
{
	virtual Product* CreateProduct() = 0 ;
}

template <class TheProduct>
class StanderdCreator : public Creator
{
	virtual Product* CreateProduct();
}
template <class TheProduct>
Product* StanderdCreator<TheProduct>::CreateProduct()
{
	return new TheProduct;
}
//使用这个模板,客户只需要提供产品类
class MyProduct : public Product
{
	...
}
//使用
StanderdCreator<MyProduct> mycreator;

用工厂方法模式来实现迷宫创建,代码如下:

class MazeGame()
{
	Maze * CreateMaze();
	//工厂方法,推迟到子类中实现
	virtual Maze* makeMaze(){ return new Maze; }
	virtual Room* makeRoom(int n){ return new Room(n); }
	virtual Wall* makeWall(){ return new Wall; }
	virtual Door* makeDoor(Room* r1, Room* r2){ return new Door(r1,r2); }
}

Maze* MazeGame::CreateMaze()
{
	Maze *aMaze = makeMaze();
	Room *r1 = makeRoom(1);
	Room *r2 = makeRoom(2);
	Door *dr = makeDoor(r1,r2);
	aMaze->addRoom(r1);
	aMaze->addRoom(r2);
	r1->setSide(North, makeWall());
	r1->setSide(South, dr);
	r1->setSide(East, makeWall());
	r1->setSide(West, makeWall());
	r2->setSide(North, makeWall());
	r2->setSide(North, makeWall());
	r2->setSide(North, makeWall());
	r2->setSide(North, dr);
	return aMaze;
}

//不同的游戏可以创建MazeGame子类以特别指明一些迷宫的部件,MazeGame子类可以重定义所有或者部分工厂方法以指定产品中的变化,如下
class BombedMazeGame : public MazeGame
{
	virtual Wall* makeWall(){ return new BombedWall; }
	virtual Room* makeRoom(int n){ return new RoomWithABomb(n); }
}
1.3 简单工厂模式(Simple Factory)

简单工厂模式定义:也称为静态工厂模式,是一种创建型设计模式,它通过一个工厂类来封装对象的创建过程,根据客户端的请求返回不同的具体对象。简而言之就是在实现过程中通过指定参数来创建相应的产品。

class Creator
{
	virtual Product* Create(ProductId id)
	{
		if(id == MINE) return new MyProduct;
		if(id == YOURS) return new YoursProduct;
		return 0;
	}
}
//子类可以重写Product,并引入新的标识
class MyCreator : public Creator
{
	virtual Product* Create(ProductId id)
	{
		if(id == MINE) return new YoursProduct;
		if(id == YOURS) return new MyProduct;
		if(id == THRIRS) return new ThierProduct;
		return Creator::Create(id);
		return 0;
	}
}

2. 建造者模式(Builder)

建造者模式的定义:将一个复杂对象的构建与其表示(定义)分离,使得同样的构建过程可以创建不同的表示。
建造者模式的核心思想是将一个复杂对象的构建过程分解为多个简单的步骤,每个步骤由具体建造者来实现。通过指挥者将这些步骤按照一定的顺序组合起来,最终构建出一个完整的复杂对象。这样,客户端代码只需要与指挥者进行交互,而无需关心具体的构建过程和细节。

建造者模式适用于以下情况:

  • 当需要创建的对象具有复杂的内部结构,且内部部件的构建顺序和组合方式不稳定或多变时。
  • 当需要创建的对象的配置选项较多,构造函数参数过多且难以维护时。
  • 当希望通过一种统一的方式构建不同表示的对象时。

建造者模式结构图:
在这里插入图片描述
用建造者模式来实现迷宫创建,代码如下:

//MazeBuilder类定义下面的接口来创建迷宫
class MazeBuilder
{
	//复杂对象的构建过程分解为多个简单的步骤,每个步骤由具体建造者来实现
	virtual void BuildMaze(){}
	virtual void BuildRoom(int n){}
	virtual void BuildDoor(int roomFrom, int rootTo){}
	virtual Maze* GetMaze(){return 0;}
};

Maze* MazeGame::CreateMaze(MazeBuilder& builder)
{
	builder.BuildMaze();
	builder.BuildRoom(1);
	builder.BuildRoom(2);
	builder.BuildDoor(1,2);
	return builder.GetMaze();
}
//子类StandarMazeBuilder实现了简单迷宫的创建
class StandarMazeBuilder : public MazeBuilder
{
	...
}
//创建迷宫
Maze * maze;
MazeGame game;
StandarMazeBuilder  builder;
maze = game.CreateMaze(builder);

3. 原型模式(Prototypes)

原型模式定义:原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有对象来创建新的对象,而无需通过调用构造函数来创建。原型模式基于对象的克隆来创建新的对象,可以避免重复创建相似对象的开销。

原型模式的优点包括:

  • 可以避免重复创建相似对象的开销,提高创建对象的效率。
  • 可以通过克隆来动态地创建对象,无需依赖具体类。
  • 可以在运行时动态添加和删除原型对象。

原型模式的主要缺陷:每一个Protoypes子类都必须实现Clone操作,当类已经存在时就难以新增Clone操作,或当内部包括一些不支持拷贝或由循环引用的对象时,实现克隆可能会很困难。

原型模式特别适用于以下情形:

  • 创建一个对象需要消耗的资源较多,如数据读取、硬件访问等,可以通过原型复制来提高性能
  • 系统需要大量相同或相似对象(例如,克隆已有对象,改变值以指定新对象)的时候,可通过复制原型的方式来减少创建对象的开销
  • 对象的状态满足上述描述,并且状态需要持续变化的场景中,可以选择原型模式。

原型模式结构图,如下:
在这里插入图片描述
当实现原型时,可以考虑下面一些问题:

  1. 使用一个原型管理器。使用一个注册表存储和检索原型。在克隆一个原型前向注册表请求该原型。原型管理器是一个关联存储器,它返回一个与给定关键字相匹配的原型。
  2. 原型需要实现clone操作。
  3. 原型clone后的初始化操作。

用原型模式来实现迷宫创建(相关类声明在抽象工厂章节),代码如下:

class MazePrototypeFactory : public MazeFactory
{
	MazePrototypeFactory(Maze* m, Wall* w, Room* r, Door* d)
	{
		_prototypeMaze = m;
		_prototypeRoom = r;
		_prototypeWall = w;
		_prototpyeDoor = d;
	}
	virtual Maze *MakeMaze(){return _prototypeMaze->clone();}
	virtual Wall *MakeWall(){return _prototypeWall->clone();}
	virtual Room *MakeRoom(int n)
	{
		Room* r = _prototypeRoom->clone();
		r->init(n);
		return r;
	}
	virtual Door *MakeDoor(Room* r1, Room* r2)
	{
		Door* d = _prototpyeDoor->clone();
		d->init(r1,r2);
		return d;
	}
	
	Maze* _prototypeMaze;
	Room* _prototypeRoom;
	Wall* _prototypeWall;
	Door* _prototpyeDoor;
}

//创建迷宫
MazeGame game;
MazePrototypeFactory factory(new Maze, new Wall, new Room, new Door);
Maze * maze = game.CreateMaze(factory);

4. 单例模式

单例模式定义:单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问该实例的入口点。

单例模式优点:

  • 提供了对唯一实例的全局访问点,方便其他类使用该实例。
  • 避免了重复创建对象的开销,节省了系统资源。
  • 确保了对象的一致性,因为只有一个实例存在。

单例模式的两种实现:

  • 懒汉模式

    class Singletion;
    Singletion* Singletion::sing = NULL;
    class Singletion
    {
    public:
    	//方式1
    	static Singletion *creat_singletion()
    	{
    		if (!sing)
    		{
    			lock();
    			if(!sing)
    			{
    				sing = new Singletion();
    			}
    			unlock();
    		}
    		return sing;
    	}
    	//由于双检锁失败的原因,这里提供方式2
    	static Singletion& create_singletion1()
    	{
    		static Singletion sing1;
    		return sing1
    	}
    	void task()
    	{
    		cout << "singtion task ..." << endl;
    	}
    private:
    	Singletion();
    	Singletion(Singletion&);
    	Singletion(Singletion&&);
    	Singletion& operator=(const Singletion&);
    	static Singletion *sing;
    
    //添加无智能指针时删除https://www.cnblogs.com/ring1992/p/9592817.html
    }
    //单例模板https://www.cnblogs.com/sunchaothu/p/10389842.html
    
  • 饥汉模式

    class Singletion
    {
    public:
    	Singletion* get_instance()
    	{
    		return sing;
    	}	
    	void task ()
    	{
    		//task
    	}
    private:
    	Singletion();
    	Singletion(Singletion&);
    	Singletion(Singletion&&);
    	Singletion& operator=(const Singletion&);
    	static Singletion *sing;
    }
    Singletion* Singletion::sing = new Singletion();
    

5. 创建型模式之间的联系和区别

  1. Abstract Factory和Builder相似,两者都可以创建复杂的对象。主要的区别是builder模式着重于一步一步构造一个复杂对象,而Abstract Factory着重于多个系列的产品对象。
  2. Abstract Factory模式可以通过Factory Method模式或者Builder模式来实现。
  3. Prototype和Abstract Factory模式在某种方面是相互竞争的,但是它们也可以一起使用。Abstract Factory可以存储一个被克隆的原型集合,并且通过集合返回大量对象。
  4. 在一个框架系统中,用一个系统创建的抽象类对系统进行参数化(CreateMaze函数)的方式有两种:
    a.生成创建对象的子类,比如工厂方法模式,这种方法的缺点在于,如果要改变产品类,就需要创建一个新的子类。
    b.定义一个对象负责明确产品对象的类,并将它作为该系统的参数,比如抽象工厂、原型模式、建造者模式。抽象工厂由这个工厂对象产生多个类的对象;建造者由这个工厂对象使用一个复杂协议逐步创建一个复杂产品;原型模式由该工厂对象通过拷贝原型对象来创建产品。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/607142.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

P8799 [蓝桥杯 2022 国 B] 齿轮

P8799 [蓝桥杯 2022 国 B] 齿轮 分析 最右边的齿轮的转速是最左边齿轮的q倍 最右边的齿轮的半径是最左边齿轮的q倍 题意即为&#xff1a;查询数组中是否存在两个数&#xff0c;其中一个是另一个的q倍 题目范围&#xff1a;查询次数q:2*10^5&#xff0c;数组范围2*10^5&…

2024付费进群系统,源码及搭建变现视频课程(教程+源码)

前三节讲解搭建支付对接&#xff0c;后两节讲解一些引流变现的方法&#xff0c;还有一种变现就是帮人搭建这样的平台&#xff0c;因为全网都没有一套完整的视频教怎么搭建的&#xff0c;有也只是文字教程&#xff0c;一般新人根本看不懂&#xff0c;我视频实操演示&#xff0c;…

学习经验分享【36】论文投稿写作(非理工科文章)

业务进一步扩展&#xff0c;可辅导非理工科偏文科性质的论文辅导&#xff0c;有需要评职称但没有时间精力研究的或者其他相关需求的朋友可咨询了解。 人工智能技术在各领域的发展和思考&#xff0c;类似这种主题的文章。

压缩和归档库-LZ4介绍

1.简介 LZ4是一种快速的压缩算法&#xff0c;提供压缩和解压缩的速度&#xff0c;而牺牲了压缩率。它被设计用于快速的数据压缩和解压缩&#xff0c;特别是用于数据存储和传输。LZ4通常用于需要高速数据处理的场景&#xff0c;如数据库、日志文件处理和实时数据传输。 LZ4的特…

进一步分析并彻底解决 Flink container exit 143 问题

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

腾讯游戏海外扩张,增持芬兰游戏开发商股份持股比例增至14.8%

易采游戏网5月8日消息&#xff0c;近日腾讯再次出手&#xff0c;大幅增持了芬兰知名游戏开发商Remedy Entertainment的股份&#xff0c;持股比例猛增至14.8%。这一举动引起了业界和投资者的广泛关注。 据了解&#xff0c;腾讯此次增持是在2024年4月24日完成的。根据芬兰法律规…

Linux网络-PXE高效批量网络装机(命令+截图详细版)

目录 一.部署PXE远程安装服务 1.PXE概述 1.1.PXE批量部署的优点 1.2.要搭建PXE网络体系的前提条件 2.搭建PXE远程安装服务器 2.1.修改相关网络配置&#xff08;仅主机模式&#xff09; 2.2.关闭防火墙&#xff08;老规矩&#xff09; 2.3.保证挂载上 2.4.准备好配置文…

<网络安全>《76 概念讲解<第十课 物联网常用协议-网络层协议>》

协议简称全称名称内容说明IPv4互联网通信协议第四版IPv4是互联网的核心IPv6互联网协议第6版TCPTransmission Control Protocol传输控制协议TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务…

【Python】什么是皮尔森系数

我不完美的梦 你陪着我想 不完美的勇气 你说更勇敢 不完美的泪 你笑着擦干 不完美的歌 你都会唱 我不完美心事 你全放在心上 这不完美的我 你总当做宝贝 你给我的爱也许不完美 但却最美 &#x1f3b5; 周冬雨《不完美女孩》 皮尔森相关系数&#xff08;Pe…

FinalShell连接虚拟机Linux系统连接超时

报错信息 java.net.ConnectException: Connection timed out: connect 排除是网络问题后可以尝试一下这个方法。 解决方案: 打开虚拟机终端输入:ifconfig 会出现端口信息: 看ens33这里的端口是多少&#xff0c;改一下重新连接就ok。

springboot+vue实现登录注册,短信注册以及微信扫描登录

说明&#xff1a;微信扫描登录需要微信注册--要钱&#xff0c;感谢尚硅谷提供的免费接口&#xff1b;短信注册需要阿里云的注册很麻烦并且短信费&#xff0c;没有接口&#xff0c;所以不打算实现&#xff0c;不过能做出效果。 目录 一、建立数据库 二、后端idea实现接口 1.…

幻兽帕鲁专用服务器怎样买省钱便宜?一个月30元

在数字娱乐的浪潮中&#xff0c;幻兽帕鲁Palworld以其独特的魅力吸引了无数玩家的目光。想要拥有流畅、稳定的游戏体验&#xff0c;一台专属的游戏服务器是必不可少的。而如何以最经济的价格购买到高品质的服务器&#xff0c;正是玩家们最关心的问题。腾讯云服务器性价比是很高…

每日Attention学习6——Context Aggregation Module

模块出处 [link] [code] [IJCAI 22] Boundary-Guided Camouflaged Object Detection 模块名称 Context Aggregation Module (CAM) 模块作用 增大感受野&#xff0c;全局特征提取 模块结构 模块代码 import torch import torch.nn as nn import torch.nn.functional as Fcla…

Anaconda安装和深度学习环境的安装(TensorFlow、Pytorch)

换了新电脑&#xff0c;重新装一下anaconda这些编程环境。好久没装过了&#xff0c;自己也需要查查资料&#xff0c;然后记录一下&#xff0c;分享给别人。 目标&#xff0c;三个环境&#xff1a;1.anaconda基础环境&#xff08;包含xgboost和lightgbm&#xff09;&#xff0c…

卫星通信现状与展望三 -- 分类总结及6G应用

作者:私语茶馆 卫星通信分类总结及6G应用 一、卫星轨道类型 卫星按照轨道距离地面的距离主要分为以下几种: 卫星轨道类型 卫星用途 轨道高度 VLEO(Very Low Earth Orbit) 对地观测、通信

Python中使用tkinter模块和类结构的结合使用举例——编写制作一个简单的加数GUI界面

Python中使用tkinter模块和类结构的结合使用举例——编写制作一个简单的加数GUI界面 这里写目录标题 Python中使用tkinter模块和类结构的结合使用举例——编写制作一个简单的加数GUI界面一、tkinter模块和类的简述1.1 tkinter的简要介绍1.2 类结构的简要介绍 二、基于类机构和t…

成本降低 90%,出海社交平台 Typing 基于 Databend 的大数据探

Typing&#xff08;输入中科技&#xff09;成立于 2022 年&#xff0c;是一家主要面向东南亚、拉美、中东等海外地区提供社交平台的出海企业。其社交平台类似于国内的 Soul、陌陌等&#xff0c;提供视频直播、语音聊天室、短视频、生活分享、文字聊天等社交功能&#xff0c;注册…

【C++】零钱兑换的始端---柠檬水找零

欢迎来CILMY23的博客 本篇主题为 零钱兑换的始端---柠檬水找零 个人主页&#xff1a;CILMY23-CSDN博客 个人专栏系列&#xff1a; Python | C | C语言 | 数据结构与算法 感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言&#xff1a; 柠檬水找…

2024年最新【SpringBoot2】开发实用篇-测试_springboot2 test(1),2024年最新2024春招BAT面试真题详解

既有适合小白学习的零基础资料&#xff0c;也有适合3年以上经验的小伙伴深入学习提升的进阶课程&#xff0c;涵盖了95%以上软件测试知识点&#xff0c;真正体系化&#xff01; 由于文件比较多&#xff0c;这里只是将部分目录截图出来&#xff0c;全套包含大厂面经、学习笔记、…

吸血鬼崛起v rising皮革获取教程 v rising皮革机怎么获得

《V Rising》是一款由Stunlock Studios公司制作并发行的生存建造类游戏&#xff0c;以“吸血鬼”为题材。中文名为“吸血鬼崛起”。在游戏中&#xff0c;打boss可以获得许多掉落材料&#xff0c;有些材料需要合成&#xff0c;而制作皮革则需要使用皮革机。下面就为大家介绍一下…