六大学习设计模式的关键准则
设计模式六大原则:
1、单一职责原则(Single Responsibility Principle)
2、里式替换原则(Liskov Substitution Principle)
3、依赖倒置原则(Dependence Inversion Principle)
4、接口隔离原则(Interface Segregation Principle)
5、迪米特法则(Law Of Demeter)//最少知道原则
6、开闭原则(Open Closed Principle)
设计模式:
面向对象语言开发过程中,遇到种种的场景和问题,提出的解决方案和思路,沉淀下来,设计模式是解决具体问题的套路
设计模式六大原则:
面向对象语言开发过程中,推荐的一些指导性原则;没有明确的招数,而且也会经常被忽视/违背;也是前辈总结,也是为了站在前辈的肩膀上。
实际上真实项目很难全部遵循,更多的时候会有一些侧重性。设计模式六大原则要能灵活运用,离不开时间的锤炼和思考,把这个真的融入到骨子里,设计确实会不一样。
1、单一职责(Single Responsibility Principle)
类T负责两个不同的职责,职责P1和职责P2。由于职责P1需求发生改变需要修改T时,有可能会导致原本运行正常 职责P2功能发生故障。
一个类只负责一件事,面向对象语言开发,类是一个基本单位,单一职责原则就是封装的粒度。
下面我们来看一个动物类:
public class Animal { private string _Name = null; public Animal(string name) { this._Name = name; } /// <summary> /// 这个方法就挺不稳定,经常各种分支变化经常修改 /// </summary> public void Breath() { if (this._Name.Equals("鸡")) Console.WriteLine($"{this._Name} 呼吸空气"); else if (this._Name.Equals("牛")) Console.WriteLine($"{this._Name} 呼吸空气"); else if (this._Name.Equals("鱼")) Console.WriteLine($"{this._Name} 呼吸水"); else if (this._Name.Equals("蚯蚓")) Console.WriteLine($"{this._Name} 呼吸泥土"); } //BreathChicken BreathFish //应该拆分了 public void Action() { if (this._Name.Equals("鸡")) Console.WriteLine($"{this._Name} flying"); else if (this._Name.Equals("牛")) Console.WriteLine($"{this._Name} walking"); else if (this._Name.Equals("鱼")) Console.WriteLine($"{this._Name} Swimming"); else if (this._Name.Equals("蚯蚓")) Console.WriteLine($"{this._Name} Crawling"); } }
这样在不同动物过来时,只要在Animal的构造函数中传递动物的名字即可:
{ Animal animal = new Animal("鸡");//呼吸空气 animal.Breath(); animal.Action(); } { Animal animal = new Animal("牛");//呼吸空气 animal.Breath(); animal.Action(); } { Animal animal = new Animal("鱼");//呼吸水 animal.Breath(); animal.Action(); }
但是这样不好,写了分支判断,然后执行不同的逻辑,其实这就违背了单一职责,但是功能是可以实现的。
需要拆分,拆分父类+子类,每个类很简单,意味着稳定,意味着强大。现在的东西没有以前警用,因为功能多了,这不坏就那坏了。
下面抽象出一个父类:
public abstract class AbstractAnimal { protected string _Name = null; public AbstractAnimal(string name) { this._Name = name; } public abstract void Breath(); public abstract void Action(); }
现在,有一种动物,只要继承这个父类,重写抽象类中的方法即可:
public class Chicken : AbstractAnimal { public Chicken(string name) : base(name) { } public Chicken() : base("鸡") { } public override void Breath() { Console.WriteLine($"{base._Name} 呼吸空气"); } public override void Action() { Console.WriteLine($"{base._Name} flying"); } }
AbstractAnimal animal = new Chicken(); animal.Breath(); animal.Action();
拆分之后,也会造成代码量的增加,类多了,使用成本(理解成本)也高了。
那么,什么时候使用单一职责呢?
如果类型足够简单,方法够少,是可以在类级别去违背单一职责的;如果类型复杂了,方法多了,建议遵循单一职责原则。
方法级别的单一职责原则:一个方法只负责一件事
类级别的单一职责原则:一个类只负责一件事
类库级别的单一职责原则:一个类库职责要清晰
项目级别的单一职责:一个项目应该职责要清晰(客户端/管理后台/后台服务/定时任务/分布式引擎)
系统级别的单一职责:为通用功能拆分系统(IP定位/日志/在线统计)
2、里氏替换原则(Liskov Substitution Principle)
任何使用基类的地方,都可以透明(安全,不会出现行为不一致)的使用其子类
继承:子类拥有父类的一切属性和行为,任何父类出现的地方,都可以用子类来代替
a、父类有的,子类必须有,如果父类中出现了子类不应该有的东西,那么就应该断掉继承,再来一个父类,包含了都有的东西。
b、子类可以有自己的属性和行为,子类出现的地方,父类不一定能代替(白马非马)。
c、父类实现的东西,子类就不要再写了(就是不要new隐藏),有时候会出现意想不到的地方,行为不一致,如果想修改父类的行为,通过abstract或者virtual。声明属性、字段、变量,尽量声明为父类。
3、依赖倒置原则(Dependence Inversion Principle)
高层模块不应该依赖于低层模块,二者应该是通过抽象依赖,依赖抽象,而不是依赖细节。面向对象,尽量使用抽象,80%的设计模式都是跟抽象有关(接口也可以)。属性、字段、方法参数、返回值。。。。尽量都是抽象
抽象:接口/抽象类---可以包含没有实现的元素
细节:普通类(子类)---一切都是确定的
Student-------使用--------手机
高层--------------------------低层
就好像三层中:
BLL---------------------------DAL
如果在一开始,每个手机都定义通用的方法,学生在调用的时候,正常去调用,会出现高层依赖低层
//Student-使用-手机 //高层---------底层 { iPhone phone = new iPhone(); student.PlayiPhone(phone); student.PlayT(phone); student.Play(phone); } { Lumia phone = new Lumia(); student.PlayLumia(phone); student.PlayT(phone); student.Play(phone); } { Honor phone = new Honor(); student.PlayHonor(phone); student.PlayT(phone); student.Play(phone); }
解决上面出现的问题,定义一个手机的抽象父类,里面定义手机通用的功能。
/// <summary> /// 定义一个手机抽象父类 /// </summary> public abstract class AbstractPhone { public int Id { get; set; } public string Branch { get; set; } public abstract void Call(); public abstract void Text(); }
/// <summary> /// 荣耀手机 /// </summary> public class Honor : AbstractPhone { public override void Call() { Console.WriteLine("User {0} Call", this.GetType().Name); } public override void Text() { Console.WriteLine("User {0} Call", this.GetType().Name); } }
/// <summary> /// iPhone /// </summary> public class iPhone : AbstractPhone { public override void Call() { Console.WriteLine("User {0} Call", this.GetType().Name); } public override void Text() { Console.WriteLine("User {0} Call", this.GetType().Name); } }
/// <summary> /// 小米手机 /// </summary> public class Mi : AbstractPhone { public override void Call() { Console.WriteLine("User {0} Call", this.GetType().Name); } public override void Text() { Console.WriteLine("User {0} Text", this.GetType().Name); } public void Bracelet() { Console.WriteLine("User {0} Bracelet", this.GetType().Name); } }
......只要是一部手机,只要继承了抽象父类,都可以重写父类中的抽象方法,实现通用的功能,也可以加上自己特有的功能(增加自己的功能,是不是很强大?后面就看出来了是否合理了)。
下面有两种方式去调用:泛型+父类约束=========》用抽象类,是等价的
public void PlayT<T>(T phone) where T : AbstractPhone { Console.WriteLine("这里是{0}", this.Name); phone.Call(); phone.Text(); }
public void Play(AbstractPhone phone) { Console.WriteLine("这里是{0}", this.Name); phone.Call(); phone.Text(); //phone.Bracelet(); }
面向抽象有啥好处?
一个方法既满足不同类型的参数,只要是实现了这个抽象类,都可以用;还支持扩展,不用修改Student类;面向抽象后,不能使用子类特别的内容。
在调用的时候,studen.Play(phone);如果,这个phone是一个小Mi手机的子类呢?Bracelet(手环功能)是有的,但是方法不能用,编译器决定了是不能用Bracelet(dynamic/反射是可以调用的),不能常规调用,这个问题是解决不了的。
你这样想,如果小米手机都是自己特有的功能,那还用抽象父类干嘛?直接小米手机自己搞一个不就行了?因为面向对象不止一个类型,用的就是通用功能;非通用功能,那就不应该面向对象了。
面向对象语言开发,只要抽象不变,高层就不变。
面向对象语言开发,就是类与类之间进行交互,如果高层直接依赖低层的细节,细节是多变的,那么低层的变化就导致上层的变化;如果层数多了,低层的修改会直接水波效应传递到最上层,一点细微的改动,都会导致整个系统从下往上的修改(这就是大家经常加班的原因)。
面向抽象,如果高层和低层没有直接依赖,而是依赖于抽象,抽象一般是稳定的,低层细节的变化扩展就不会影响到高层,这样就能支持层内部的横向扩展,不会影响到其他地方,这样的程序架构就是稳定的。
依赖倒置原则(理论基础)------IOC控制反转(实践封装)-----DI依赖注入(实现IOC的手段)。
4、接口隔离原则(Interface Segregation Principle)
客户端不应该依赖它不需要的接口,一个类对另外一个类的依赖应该建立在最小的接口上,在工作中,80%都是用接口的。
AbstractPhone定义了Id、Branch、Call()、Text(),现在的智能手机,都有map、movie、online、game等功能,是否应该把这几个功能上升到AbstractPhone里面去?
答案是不应该的,OldManPhone也是手机,但是没有这些功能,AbstractPhone就只能放入任何手机都有的功能。
虽然这些东西不适合放在抽象类中,但是面向抽象编程,还有一个接口。抽象类 is a,接口 can do,面向对象编程中,是单继承多实现的。将这些东西定义在接口中,不局限产品。
接口是什么?
简单来说,接口就是,当一些东西都有相同的功能,但是有不能抽象出合理的父类的时候,这个时候就可以抽象为接口。
public interface IExtend { void Photo(); void Online(); void Game(); void Record(); void Movie(); void Map();// void Pay(); }//都拆成一个方法一个接口
Camera能拍照,也能录像,既然面向抽象,那么有些功能的对象都能传递进来,那就让Camera也去实现IExtend接口?
不可以的,实现了IExtend接口,Camera出现了很多自己没有的功能,不应该使用这种大而全的接口,所以要把接口的功能进一步拆分,因为接口是可以多实现的。
public interface IExtend { //void Photo(); //void Online(); //void Game(); void Record(); //void Movie(); void Map();// void Pay(); }//都拆成一个方法一个接口 //电视--上网 玩游戏 public interface IExtendHappy : IExtendGame { void Online(); //void Game(); } //掌中游戏机:俄罗斯方块--玩游戏不能上网 public interface IExtendGame { void Game(); } public interface IExtendVideo { void Photo(); void Movie();//打开相机--切换模式--start--Suspend--End }
这样拆分下去,都拆成一个方法一个接口了,肯定也不好。
在.Net中,有IList<T>,是索引相关;ICollection<T>,集合相关操作;IEnumerable<T>,迭代器foreach....
接口到底该怎么定义?
a、既不能是大而全,会强迫实现没有的东西,也会依赖自己不需要的东西
b、也不能一个方法一个接口,这样,面向抽象也没意义了。
按照功能的密不可分可定义接口,而且应该是动态的,随着业务发展会有变化的,但是在设计的时候,要留好提前量,避免抽象变化。这里没有标准答案,随着业务来调整的。
c、接口合并,Map----定位/导航/搜索,这种就属于固定步骤,业务细节,尽量的内聚,在接口也不要暴露太多细节。
5、迪米特法则(Law Of Demeter)最少知道原则:高内聚低耦合
一个对象应该对其他对象保持最少的了解,只与直接的朋友通信。
面向对象----万物皆对象-----类与类交互才能产生功能,这不就是耦合了吗?要高内聚低耦合
类与类之间的关系:
纵向:继承≈实现(最密切)
横向:聚合>组合>包含>依赖(出现在方法内部)
迪米特法则:降低类与类之间的耦合,只与直接的朋友通信,就是要尽量避免依赖更多类型。
基类库(BCL-系统/框架内置)的类型除外
迪米特,也会增加一些成本
工作中,会去早一个中介(中间层)
上层UI下订单-----订单系统&支付&支付系统&仓储&物流
门面模式----上层交互门面----门面依赖子系统
三层架构中:UI----BLL-----DAL
去掉内部依赖
降低访问修饰符权限,private、protected、internal、protected internal、public
迪米特,依赖别人更少,让别人了解更少
/// <summary> /// 学生 /// </summary> public class Student { public int Id { get; set; } public string StudentName { get; set; } public int Height { private get; set; } public int Salay; public void ManageStudent() { Console.WriteLine(" {0}Manage {1} ", this.GetType().Name, this.StudentName); } }
/// <summary> /// 班级 /// </summary> public class Class { public int Id { get; set; } public string ClassName { get; set; } public List<Student> StudentList { get; set; } public void ManageClass() { Console.WriteLine(" {0}Manage {1} ", this.GetType().Name, this.ClassName); foreach (Student s in this.StudentList) { s.ManageStudent(); //Console.WriteLine(" {0}Manage {1} ", s.GetType().Name, s.StudentName); } } }
/// 学校 /// </summary> public class School { public int Id { get; set; } public string SchoolName { get; set; } public List<Class> ClassList { get; set; } public void Manage() { Console.WriteLine("Manage {0}", this.GetType().Name); foreach (Class c in this.ClassList) { //Console.WriteLine(" {0}Manage {1} ", c.GetType().Name, c.ClassName); c.ManageClass();//1 遵循了迪米特 //List<Student> studentList = c.StudentList; //foreach (Student s in studentList) //{ // Console.WriteLine(" {0}Manage {1} ", s.GetType().Name, s.StudentName); //}//2 违背了迪米特法则 } } }
6、开闭原则(Open Closed Principle)
对扩展开放,对修改关闭
修改:修改现有代码(类)
扩展:增加代码(类)
面向对象语言是一种静态语言,最害怕变化,会波及很多东西,全面测试。嘴里将就是新增类,对原有代码没有改动,原有的代码才是可信的。
开闭原则只是一个目标,并没有任何的手段,也别成为总则。其他5个原则的建议,就是为了更好的做到OCP。开闭原则也是面向对象语言开发的一个终极目标。
如果有功能增加/修改的需求,那么就修改现有的方法---增加方法---增加类----增加/替换类库。
推荐阅读
-
设计模式学习 (IV) - UML 中的类图和类图之间的关系
-
向过去学习生成器的设计模式
-
NeurIPS 2022 | 最强斗地主AI!网易互娱AI Lab提出基于完美信息蒸馏的方法-完美信息蒸馏(PTIE) 在斗地主游戏中,非完美信息的引入主要是由于三位玩家均不能看到别人的手牌,对于任意一位玩家而言,仅可知道其余两位玩家当前手牌的并集,而难于精准判断每位玩家当前手牌。完美信息蒸馏的思路是针对这种非完美问题,构建一个第三方角色,该角色可以看到三位玩家的手牌,该角色在不告知每位玩家完美信息的情况下通过信息蒸馏的方式引导玩家打出当前情况下合理的出牌。 以强化学习常用的 Actor-Critic 算法为例,PTIE 在 Actor-Critic 算法的应用中可以利用 Critic 的 Value 输出作为蒸馏手段来提升 Actor 的表现。具体而言即在训练中 Critic 的输入为完美信息(包含所有玩家的手牌信息),Actor 的输入为非完美信息(仅包含自己手牌信息),此种情况下 Critic 给予的 Value 值包含了完美信息,可以更好地帮助 Actor 学习到更好的策略。 从更新公式上来看,正常的 Actor-Critic 算法 Actor 更新的方式如下: 在 PTIE 模式下,对于每个非完美信息状态 h,我们可以在 Critic 中构建对应的完美信息状态 D(h),并用 Critic 的输出来更新 Actor 的策略梯度,从而达到完美信息蒸馏的效果。 PTIE 框架的整体结构如下图所示: 无论是训练还是执行过程中智能体都不会直接使用完美信息,在训练中通过蒸馏将完美信息用于提升策略,从而帮助智能体达到一个更高的强度。 PTIE 的另一种蒸馏方式是将完美信息奖励引入到奖励值函数的训练中,PerfectDou 提出了基于阵营设计的完美信息奖励 node reward,以引导智能体学习到斗地主游戏中的合作策略,其定义如下: 如上所示,完美信息部分 代表 t 时刻地主手牌最少几步可以出完,在斗地主游戏中可以近似理解为是距游戏获胜的距离, 代表 t 时刻地主阵营和农民阵营距游戏获胜的距离之差, 为调节系数。通过此种奖励设计,在训练时既可以一定程度地引入各玩家的手牌信息(出完的步数需要知道具体手牌才能计算),同时也鼓励农民以阵营的角度做出决策,提升农民的合作性。 特征构建: PerfectDou 针对牌类游戏的特点主要构建了两部分特征:牌局状态特征和动作特征。其中牌局状态特征主要包括当前玩家手牌牌型特征、当前玩家打出的卡牌牌型特征、玩家角色、玩家手牌数目等常用特征,动作特征主要用于刻画当前状态下玩家的所有可能出牌,包括了每种出牌动作的牌型特征、动作的卡牌数目、是否为最大动作等特征。 牌型特征为 12 * 15 的矩阵,如下图所示: 该矩阵前 4 行代表对应每种卡牌的张数,5-12 行代表该种卡牌的种类和对应位置。 网络结构和动作空间设计 针对斗地主游戏出牌组合数较多的问题,PerfectDou 基于 RLCard 的工作上对动作空间进行了简化,对占比最大的两个出牌牌型:飞机带翅膀和四带二进行了动作压缩,将整体动作空间由 27472 种缩减到 621 种。 PerfectDou 策略网络结构如下图所示: 策略网络结构同样分为两部分:状态特征部分和动作特征部分。 在状态特征部分,LSTM 网络用于提取玩家的历史行为特征,当前牌局状态特征和提取后的行为特征会再通过多层的 MLP 网络输出当前的状态信息 embedding。 在动作特征部分,每个可行动作同样会经过多层 MLP 网络进行编码,编码后的动作特征会与其对应的状态信息 embedding 经过一层 MLP 网络计算两者间的相似度,并经由 softmax 函数输出对应的动作概率。 实验结果
-
设计模式的六大原则
-
41 个下载免费 3D 模型的最佳网站-使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 17. Clara.io Clara.io 是一个创建 3D 内容的全球平台,也是一个培养新 3D 艺术家的社区。Clara.io 提供+100,000个免费的3D模型,包括OBJ,Blend,STL,FBX,DAE,Babylon.JS,Three.JS格式,用于 Clara.io,Unity 3D,Blender,Sketchup,Cinema 4D,3DS Max和Maya。 使用说明:免费,标准和专业帐户仅供个人使用,如果您需要将 clara.io 用于商业用途,请与销售团队联系。 18. 3DExport 3DExport是一个市场,您可以在其中购买和销售用于CG项目的3D模型,3D打印模型和纹理。它提供15 +不同的3D格式供下载,如3DS MAX(.max),Cinema4D(.c4d),Maya(.mb,.ma),Lightwave(.lwo),Softimage(.xsi),Wavefront OBJ(.obj),Autodesk FBX(.fbx)等。它还提供15种不同的语言! 使用说明:免费下载仅供个人和非商业用途。 19. 3D Warehouse 3D Warehouse是一个开放的库,允许用户共享和下载SketchUp 3D模型,用于建筑,设计,施工和娱乐!任何人都可以免费制作,修改和重新上传内容到3D仓库,您可以找到任何您能想到的东西,如家具,电子产品,室内产品等。 使用说明:3D Warehouse中的所有模型都是免费的,因此任何人都可以下载文件以用于SketchUp甚至其他软件,如AutoCAD,Revit和ArchiCAD。 20. CadNav.com CadNav是CGI平面设计师和CAD / CAM / CAE工程师的在线3D模型库,我们提供超过50000 +免费3D模型和CAD模型下载。在CadNav网站上,您可以下载高质量的多边形网格3D模型,3D CAD实体对象,纹理,Vray材料,3D作品,CAD图纸等。 使用说明:免费下载仅供个人和非商业用途。 21. All3dfree.net 就像网站名称一样,它提供免费的3D模型,还包括Vray材料,CAD块,2d和3d纹理集合,无需注册即可免费下载。它是不断更新的,因此您可以查找或请求3DS,MAX,C4D,skp,OBJ,FBX,MTL等格式的模型。 使用说明:所有资源均不允许用于商业用途,否则您将承担责任。 22. Hum3D 自2005年以来,Hum3D帮助来自3多个国家的80D艺术家节省3D建模时间,并制作逼真的3D模型,用于电影,视频游戏,AR应用程序和可视化。所有模型均由首席3D艺术家进行验证,他们检查其是否符合专业要求和最新的3D建模标准。 使用说明:免费下载仅供个人和非商业用途。 23. Artist-3D.com 艺术家-3D 库存的免费 3D 模型下载按通用类别排序。它为人体解剖学、汽车、家具、火箭、卫星等模型提供 AutoDesk 3DS Max 格式。您还可以在浏览他们的网站时找到教程和类似类型的建模。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 24. Free the models 就像本网站的标题一样,它为3d应用程序和3d游戏引擎提供免费的内容模型。您可以为您的任何项目找到许多有趣且有用的模型!它提供3ds,wavefront,bryce,poser,lightwave,md2和unity3d格式的模型。还有一个很棒的纹理集合,可以在您最喜欢的建模和渲染程序中使用。 使用说明:您从这里下载的所有内容都可以免费使用,除非它不能包含在另一个免费的网络或CD收藏中,也不能单独出售。否则,您可以在商业游戏,3D应用程序或渲染作品中使用它。您不必提供信用,但如果您这样做,那就太好了。 25. Resources.blogscopia 本网站由一家名为Scopia的公司创建。他们制作3D图像和视频,您可以找到许多为CGI工作的信息架构设计的模型,所有这些都可以在现实生活中使用。您可以免费下载它们,但是,如果您想一次下载它们,您可以支付 3 到 9 欧元。 使用说明:您可以免费下载模型部分的所有文件。每个压缩文件都包含您也可以在此处找到的许可证。基本上,您可以对文件执行任何操作。唯一的限制是不归属于Scopia的重新分发。 26.ambientCG 1000+公共领域PBR材料适合所有人!环境CG是使用许多不同的方法和资产类型创建的,例如照片纹理(PBR),贴花(PBR),图集(PBR),照片纹理(普通),物质存档(SBSAR),雕刻画笔,3D模型和地形。您可以在所有项目中*使用它们! 使用说明:在 ambientCG 上提供下载的所有 PBR 材料、画笔、照片和 3D 模型均根据知识共享 CC0 1.0 通用许可提供。您可以复制、修改、分发和执行作品,即使是出于商业目的,也无需征得许可。信用将不胜感激。 不要满足于平庸的大理石纹理 - 立即使用我们的免费PBR大理石纹理升级您的3D设计。 27.Pixar One Twenty Eight 这是一个提供官方动画行业经典纹理的网站:皮克斯,创建于 1993 年,该纹理库包括 128 个重复纹理,现在免费提供。 它包含您来到的纹理,包括砖块和动物毛皮。肯定会有一些你可以使用的东西。 使用说明:皮克斯动画工作室的《Pixar One Twenty Eight》根据知识共享署名4.0国际许可协议进行许可。即使出于商业目的,您也可以重新混合、调整和构建您的作品,只要您以相同的条款对新创作进行信用和许可。 访问数以千计的免费纹理并提升您的设计游戏 - 立即开始下载! 28. 3DXO 即使有近 620 个免费贴纸可供下载,3DXO 也不是最大的资源,但它的内容非常有用,不需要注册。无论是简单的墙壁或地板,还是一些奇怪的小东西,您都需要的纹理都可以在此网站上看到。 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 29. 3DModelsCC0 3DModelsCC0 与其他产品的不同之处在于它包含超过 250+ 个高质量 3D 模型,并且本网站上的所有内容都是免费的,完全是公共领域!使用我们的模型时无需信用或归属! 使用说明:为每个人提供完全免费的公共领域内容。 30.Sketch up texture club Sketchup Texture Club是一个非营利性的教育和信息门户网站,由3D社区的图像促进协会管理,特别强调面向学生和建筑和室内设计专业人士的可视化和渲染技术,以及所有正在学习3D可视化的人。 使用说明:您无需支付版税或使用费。纹理可以免费下载和使用。不允许将纹理作为竞争产品出售或重新分发,即使图像被修改也是如此。 31. FlippedNormals FlippedNormal 是一个提供计算机图形和 3D 资产的市场,您可以找到许多用于雕刻、建模、纹理、概念艺术、3D 模型、游戏资产或课程的高级资产! 使用说明:使用权限可能因型号而异。因此,在下载文件之前,请仔细检查每个下载页面上的许可证和使用权限。 32. NASA 3D NASA 3D网站是一个在线门户,提供与太空和各种NASA任务相关的大量三维模型和模拟。该网站是用户友好的,并提供有关每个型号的详细信息。该网站允许用户探索和下载几种不同格式的模型,包括 OBJ、STL 和 FBX,只需单击下载按钮即可。 使用说明: 要下载模型,只需单击模型页面上的下载按钮并选择所需的格式。 33. 3DAGOGO (Astroprint) 3DAGOGO 是一个提供广泛 3D 模型的网站,包括角色、车辆和建筑物。3DAGOGO 的独特功能之一是它专注于适合 3D 打印的模型,使其成为希望创建物理原型或模型的设计师的绝佳资源。要使用 3DAGOGO,设计师只需在网站上搜索他们正在寻找的模型类型,然后下载 STL 格式的文件。 使用说明: 要使用 3DAGOGO,只需搜索所需的 3D 模型类型并下载 STL 格式的文件。根据需要自定义模型,并确保在将其用于商业目的之前检查使用权限。 34. FreeCAD FreeCAD是一款了不起的3D建模软件,可让您在计算机上创建令人难以置信的3D设计。该软件可免费下载和使用,它提供了广泛的工具和功能,可用于创建用于各种目的的3D模型。 该网站易于浏览,您可以找到开始使用FreeCAD的所有必要信息。此外,该网站还提供一系列教程和指南,可帮助您了解 3D 建模的来龙去脉。 使用说明: 要下载模型,请访问网站并从库中选择所需的模型。该网站还提供了一系列使用该软件的教程和指南。 35. Pinshape Pinshape是一个提供一系列3D打印模型的网站。网站上提供的型号质量很高,因此您可以确保您的最终印刷产品看起来很棒。该网站提供了广泛的模型,包括从家居用品到小雕像和珠宝的所有物品。 但这还不是Pinshape所能提供的全部!该网站还允许用户上传和共享自己的3D模型。这意味着您不仅可以下载出色的模型,还可以通过分享自己的设计为社区做出贡献。此外,Pinshape 提供了一系列自定义选项,因此您可以调整和调整模型以满足您的特定需求。 使用说明: 要下载模型,请在网站上创建一个帐户,搜索所需的模型,然后单击下载按钮。该网站还为每种型号提供了一系列定制选项。 36.Yeggi Yeggi 提供了大量免费的 3D 模型,您可以下载各种格式的模型,例如 STL、OBJ 和 FBX。该网站易于使用,您可以按关键字、类别或特定网站搜索模型。 Yeggi 对于任何寻找 3D 模型的人来说都是一个很好的资源。它提供了大量的模型集合,从日常物品到复杂的机械,以及介于两者之间的一切。该网站的收藏量在不断增长,每天都有新的型号增加。 使用说明: 要下载模型,请在网站上搜索所需的模型,然后单击下载按钮。该网站还提供指向托管模型的原始网站的链接。 37. Open3DModel 来自开放3D模型的图像 Open3DModel具有各种类别的模型,包括建筑,车辆和角色。无论您需要建筑物,汽车还是人的3D模型,都可以在此网站上找到。 该网站易于浏览,您可以按类别或关键字搜索模型。每个模型都附带预览图像和详细信息,例如文件格式、大小和多边形数量。此信息可以帮助您选择适合您需求的模型。 使用说明: 要下载模型,请访问网站,从库中选择所需的模型,然后单击下载按钮。 使用最好的 3D 资产管理工具简化您的 3D 制作流程。立即试用它们,将您的 3D 项目提升到一个新的水平! 38. 3DExport 对于那些为其 3D 设计项目寻找 3D 模型、纹理和其他资源的人来说,该平台是一个很好的资源。该网站有大量模型可供选择,包括 3D 打印对象、游戏资产等。用户可以按类别、文件格式或价格范围浏览,以找到适合其项目的完美资源。此外,3DExport 还提供一系列教程和其他 3D 资源,以帮助用户提高技能并创建更令人印象深刻的设计。 使用说明: 要使用 3DExport,只需创建一个帐户并浏览可用型号。您可以按类别、格式和价格进行搜索,以找到所需的型号。找到喜欢的模型后,只需下载它并开始在您的项目中使用它。 39.Blend Swap Blend Swap是一个社区驱动的市场,提供与Blender软件兼容的各种免费3D模型。该平台允许用户共享和下载模型、纹理和其他资产,以便在他们的项目中使用。 使用说明: 创建免费帐户后,您可以浏览社区上传的大量3D模型。当您找到要使用的一个时,只需下载它并将其导入您选择的 3D 软件即可。 40. 3DShook 3DShook 是一个高级 3D 模型市场,提供一系列用于建筑、游戏等各个行业的高质量模型。该平台提供基于订阅的模型,具有不同的定价计划,允许用户访问一系列模型。 使用说明: 注册免费帐户后,只需浏览3D模型库,选择您喜欢的模型,然后以您需要的格式下载它们。 41. Smithsonian X 3D 史密森尼 X 3D 对于正在寻找历史文物和文物的高质量 3D 模型的设计师来说,这是一个独特的资源。该平台提供了大量3D模型,这些模型是根据史密森尼博物馆和研究中心中的真实物体扫描创建的。 使用说明:
-
创新报告:伯克利大学研发新分布式框架Ray - 推动实时动态AI学习新时代:强调系统需求四大关键点 - (1) 混合型并行计算能力, (2) 灵活动态的任务流程图设计, (3) 高效能与低延迟的调度, (4) 自动故障修复的透明特性
-
创新报告:伯克利大学研发新分布式框架Ray - 推动实时动态AI学习新时代:强调系统需求四大关键点 - (1) 混合型并行计算能力, (2) 灵活动态的任务流程图设计, (3) 高效能与低延迟的调度, (4) 自动故障修复的透明特性
-
原题简化版: 1. 赚6万每月的大咖秘籍:不能透漏细节的职业智慧,只有在未设防的领域不断探索、积累,到某天突然亮剑,旁人惊讶之余难以轻易赶超,这时候你就筑起了自我优势的"护城河"。 2. 成功达人秘诀揭秘:广泛交往、善言推销或直接跑业务的人总能在短时间内发现商机,关键在于抓住每一次客户互动中的机遇。 3. 编程族别再低头苦干:要学会抬头看看,发掘自身还能挖掘哪些潜力技能,尝试将其转化为创新商业模式,这才是值得我们在闲暇时光深思的问题。 4. "望洋兴叹"不如实际行动:尽管无法复制他人的整套成功路径,但我们能学习他们的思维方式和财富增长策略。看到马云早期互联网的成功,固然令人艳羡,但别沉溺于羡慕嫉妒恨,而要思考如何突破自我局限。 5. 对待心灵鸡汤和焦虑营销需理性:别被鸡汤和焦虑文章牵着鼻子走,它们只会制造紧张情绪,实际对你的成长帮助有限。与其慌乱不安,不如冷静分析,找出真正适合自己的改变之道。
-
六大学习设计模式的关键准则
-
搞定设计模式六大原则(五):迪米特法则,让你的设计更上一层楼!