首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

RefactoringGuru 代码异味和重构技巧总结

另一个重要的结果是解开了类的关联,这使得类更具可移植性和可重用性。 自封装字段 问题:你直接访问类内的私有字段。 解决方案:为字段创建一个获取器和设置器,并仅使用它们访问字段。...封装集合 问题:一个类包含一个集合字段和一个用于处理集合的简单获取器和设置器。 解决方案:将获取器的返回值设为只读,并创建用于添加/删除集合元素的方法。...保存整个对象 问题:从一个对象中获取多个值,然后将它们作为参数传递给一个方法。 解决方案:相反,尝试传递整个对象。...处理泛化 抽象有自己的一组重构技术,主要关于沿着类继承层次结构移动功能、创建新的类和接口、用委托代替继承以及相反。 上移字段 问题:两个类具有相同的字段。...解决方案:从子类中删除字段,并将其移动到超类。 上移方法 问题:你的子类具有执行类似工作的方法。 解决方案:使方法相同,然后将它们移动到相关的超类。

1.9K40

Unity Demo教程系列——Unity塔防游戏(二)敌人(Moving Through a Maze)

将方法设置为protected状态,这意味着该方法只能由类本身及其扩展的所有类型访问。这是基类所做的所有事情,并不打算用作功能齐全的工厂。因此,将其标记为抽象,就不可能创建它的对象实例。 ?...(敌人出现在出生点上) 3 移动敌人 一旦敌人出现,它应该开始沿着路径移动到最近的目的地。我们必须为它们设置动画,以实现这一目标。我们首先简单地将它们在图块之间滑动,然后使它们的移动更加复杂。...这是一个可序列化的类,不扩展任何内容。给它一个公共的方法来添加一个敌人,并给另一个方法来更新整个集合。 ? 现在,游戏就可以创建一个这样的集合,在每个帧中对其进行更新,并向其中添加生成的敌人。...(敌人沿着最短路径) 敌人现在从一个方块的中心移动到另一个方块的中心。请注意,由于它们仅在瓦片中心更改其移动状态,因此不会立即响应瓦片的更改。这意味着有时敌人会穿过刚放置的墙壁。...我们将使它们沿着四分之一圆移动,而不是从一端到另一端直线移动。该圆的中心位于“From”和“To”瓦片共享的角上,与敌人进入“From”瓦片的边缘相同。 ?

2.3K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    编译过程中的并行性优化(二):基本块与全局代码调度算法

    算法伪代码: 列表调度算法不进行回溯,对每个节点只进行一次指令调度,并使用一个启发式的优先级函数函数从已就绪的节点中选择下一个调度的节点。...为了更好地利用机器资源,我们还可以考虑将一些指令从一个基本块移动到另一个基本块的代码调度,这种策略就称为全局调度。...; 在沿着控制流路径向上(向下)的代码移动中,如果目标基本块不支配(反向支配)源基本块,就可能需要补偿一些相应的代码; 如果在沿着控制流路径向上(向下)的代码移动中,源和目的基本块之中既不支配,也不反向支配...对于一个简单的全局调度器,可以采用基于区域的调度算法,它支持吧运算向上移动到控制等价的基本块,或把运算向上移动一个分支,到一个支配前驱中: 输入:一个控制流图和一个机器资源描述 输出:一个调度方案S...,以改进它们的执行时间。

    72030

    MerkleTree验证思路

    它的核心思想是通过将数据分成小块,并使用哈希函数构建出树状结构,以快速验证任意一块数据是否包含在整体中。...这些哈希值就是 Merkle 树的叶子节点(leaf nodes)。构建中间节点:依次将相邻的叶子节点两两组合,计算它们的哈希值,然后再次哈希得到它们的父节点的哈希值。...验证一个数据是否在 Merkle 树的根节点当你想要验证一个特定的数据块是否包含在 Merkle 树中时,可以使用以下步骤:获取数据块的哈希:首先,你需要获取该数据块的哈希值。...验证路径:从该数据块的哈希值开始,沿着 Merkle 树的路径向上移动到根节点,通过逐步验证每个节点的哈希值来确保它们与下一个层级的父节点哈希一致。...如果它们匹配,那么你的数据块就被确认包含在这个 Merkle 树中。

    14810

    WPF面试题大全,秒杀面试官必备

    它根据它们的逻辑层次结构(例如窗口包含面板、控件和其他UI元素)定义UI元素之间的关系。 依赖属性:依赖属性是WPF中的一个关键概念。它们允许UI元素具有可以设置、获取或绑定到其他属性的属性。...当一个元素触发一个直接路由事件时,该事件会沿着元素树向上或向下进行传播,直到找到一个处理该事件的元素。处理直接路由事件的元素可以是触发事件的元素本身,也可以是其父级或子级元素。....处理隧道路由事件的元素通常是根元素或目标元素的父级元素。. 冒泡路由事件(Bubbling Routed Events):冒泡路由事件从触发事件的元素开始,沿着元素树向上传播,直到根元素。...答:在 WPF 中,路由事件和命令是两种用于处理用户输入和应用程序行为的常用机制。路由事件是一种事件,可以沿着元素树从一个元素传播到另一个元素。...在C#代码中,编写查询数据库的代码,并将结果绑定到DataGrid控件上。可以使用SQLDataAdapter和DataSet来执行查询并获取结果集。

    90710

    自动驾驶路径规划技术-A*启发式搜索算法

    蔡鸿于南开大学软件学院 2007年6月9日 我们尝试解决的问题是把一个游戏对象(game object)从出发点移动到目的地。...一种极端情况是,当游戏对象开始移动时,一个老练的路径搜索器(pathfinder)外加一个琐细的运动算法(movement algorithm)可以找到一条路径,游戏对象将会沿着该路径移动而忽略其它的一切...对于一个具有正南正北、正东正西方向规则布局的城镇街道,从一点到达另一点的距离正是在南北方向上旅行的距离加上在东西方向上旅行的距离因此曼哈顿距离又称为出租车距离,曼哈顿距离不是距离不变量,当坐标轴变动时,...然而,问题是在A*算法中,通常的情况是,一个代价小的节点被移除(花费O(log F)的代价,因为其他结点必须从树的底部向上移动),而紧接着一些代价小的节点被添加(花费O(log F)的代价,因为这些结点被添加到底部并且被移动到最顶部...此时移动过程将包含检查下一结点和沿着直线向前移动。 6.2.2 方向存储 保存方向时,有一种情况是同一个方向保存了很多次。可以用简单的方法节省空间。 一种方法是保存方向以及朝着该方向移动的次数。

    2.3K10

    高级 Vue 技巧:控制父类的 slot

    来看看我想到的第一个解决方案。 向下使用 props,向上使用 event 数据流经组件树的唯一途径是使用props。 而向上通信的方法是使用事件。...使用 $options 由于Vue组件只是 JS 对象,因此我们可以向它们添加所需的任何属性。...另一种方式就是定义一套组件,将组件内的 vnode 转移到另外一个组件中去,然后各自渲染。 它们的工作方式和你想象的完全一样。你可以把任何东西从一个地方传送到另一个地方。...还有一个很大的问题,稍后我们会讲到。 提升状态 “提升状态”是指将状态从子组件移动到父组件或祖父组件,将它向上移动到组件树中。 这可能对应用程序的体系结构产生较大的影响。...通过这个镜头检查我们提出的每个解决方案,都会为我们提供一个有趣的新视角。 向父组件发出事件 数据流经组件树的唯一途径是使用 props。 而向上通信的方法是使用事件。

    1.8K20

    Flutter | 基础Widget

    StatelessWidget 或 StatefulWidget 来间接继承 Widget 类,这两个类都继承自 Widget 类,并且这两个是非常重要的抽象类,它们引入了 Widget 中的两种模型...实际上,context 是当前 widget 在 widget 树中位置中执行 “相关操作”的一个句柄,比如它提供了从当前 widget 开始向上遍历widget树,以及查找父类 widget 方法 class...在一些场景下,Flutter framework 会将 State 对象重新插入到树中,如果包含次 State 对象的子树在树的一个位置移动到另一个位置时(可以通过 GlobalKey 来实现)。...State 对象 由于 StatefulWidget 的具体逻辑都在其 State 中,所有很多时候,我们都需要获取 StatefulWidget 对应的 State 对象来调用一些方法,对此,我们有两种方法在子...widget 树中获取父级 StatefulWidget 的 State 对象 通过 Context 获取 context 对象有一个 findAncestorStateOfType() 方法,该方法可以从当前节点沿着

    1.2K20

    浅谈路径规划算法_rrt路径规划算法

    物体扫描的区域中(粉红色部分)没有任何东西显示它不能向上移动,因此它持续向上移动。在靠近顶部时,它探测到一个障碍物然后改变移动方向。然后它沿着U形障碍物找到它的红色的路径。...考虑你的代价函数并找到从一个位置移动到邻近位置的最小代价D。...对于一个具有正南正北、正东正西方向规则布局的城镇街道,从一点到达另一点的距离正是在南北方向上旅行的距离加上在东西方向上旅行的距离因此曼哈顿距离又称为出租车距离,曼哈顿距离不是距离不变量,当坐标轴变动时,...然而,问题是在A*算法中,通常的情况是,一个代价小的节点被移除(花费O(log F)的代价,因为其他结点必须从树的底部向上移动),而紧接着一些代价小的节点被添加(花费O(log F)的代价,因为这些结点被添加到底部并且被移动到最顶部...此时移动过程将包含检查下一结点和沿着直线向前移动。 6.2.2 方向存储 保存方向时,有一种情况是同一个方向保存了很多次。可以用简单的方法节省空间。 一种方法是保存方向以及朝着该方向移动的次数。

    1.6K10

    Kaggle初体验心得分享:PLAsTiCC天文分类比赛(附前五方案链接)

    2.如果你能行,那就从一个工作编译环境开始吧。一个好的环境总是能够节省你的时间。 3.阅读公开的workspace时,需要知道两件事情:该领域的专业知识和经过验证的方法。...特征工程的方法多种多样但是你应该思考: 通过以潜在有用的方式组合现有特征,并让模型决定如何使用它们来构建显式的新特征。...hostgal_specz:光源的光谱红移这是一个非常精确的红移测量,可用于训练集和测试集的一小部分。Float32类型变量。...Float32类型变量。 注意:如果一个物体的红移为0,那么这个物体就是一个星系物体(意味着它属于我们的星系)如果一个物体的红移大于0,那么这个物体就是银河系外的。...targe:天文学源的类别培训数据中提供了这一点正确确定目标(正确分配对象的分类概率)是测试数据分类挑战的“目标”注意,测试集中有一个类在训练集中没有出现:类99用作不属于训练集中14个类中任何一个的对象的

    1.3K20

    堆排序(向下调整法,向上调整法详解)

    二、 堆的概念及结构 如果有一个关键码的集合k ={ },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足: 且 且 i = 0, 2…,则称为小堆(或大堆)。...因为每次调整都涉及沿着树的一条路径向上移动,而树的深度为logN。...因为每次调整都涉及沿着树的一条路径向下移动,而树的深度为logN。 如何删除堆顶数据后插入数据?...如果存在右孩子且右孩子的值小于左孩子,则选择右孩子作为更小的孩子。 如果更小的孩子的值小于父节点,则交换它们的值,并将parent移动到新的位置,再次检查新的子节点。...child = parent * 2 + 1; // 获取新的左孩子索引 } else { break; // 不需要交换,退出循环 } } } 首先,对数组a建立一个小根堆

    43610

    重构-改善既有代码的设计:处理概括关系 (九)

    Pull Up Method (方法上移)常常紧随其他重构而被使用。也许你能找出若干个身处不同子类的函数,而它们又可以通过某种形式的参数调整成为相同的函数。...Pull Up Method (方法上移)过程中最麻烦的一点就是:被提升的函数可能会引用只出现于子类而不出现于超类的特性。...“使用一个类”通常意味着用到该类的所有责任区。另一种情况是,某一组客户只使用类责任区中的一个特定子集。再一种情况是,这个类需要与所有协助处理某些特定请求的类合作。...将这些操作分别放进独立的函数中,并保持它们都有相同的签名,于是原函数也就变得相同了,然后将原函数上移至超类。 继承是避免重复行为的一个强大工具。...或者,你可能发现你从超类中继承了一大堆子类并不需要的数据,抑或你可能发现超类中的某些protected函数对子类并没有什么意义。 你可以选择容忍,并接受传统说法:子类可以只使用超类功能的一部分。

    48810

    年前端react面试打怪升级之路

    而不是为每个状态更新编写一个事件处理程序。React官方的解释:要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数,你可以使用 ref来从 DOM 节点中获取表单数据。...可以用ref来获取某个子节点的实例,然后通过当前class组件实例的一些特定属性来直接获取子节点实例。...被废弃的三个函数都是在render之前,因为fber的出现,很可能因为高优先级任务的出现而打断现有任务导致它们会被执行多次。...对象;子类必须在constructor方法中调用super方法;否则新建实例时会报错;因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。...通过对比,从形态上可以对两种组件做区分,它们之间的区别如下:类组件需要继承 class,函数组件不需要;类组件可以访问生命周期方法,函数组件不能;类组件中可以获取到实例化后的 this,并基于这个 this

    2.2K10

    Java编程思想精粹(九)-接口

    创建抽象类和抽象方法是有意义的,因为它们使得类的抽象性很明确,并能告知用户和编译器使用意图。 抽象类同时也是一种有用的重构工具,使用它们使得我们很容易地将沿着继承层级结构上移公共方法。...除非必须使用,否则不要用接口和抽象类。 大多数时候,普通类已经做得很好,如果不行的话,再移动到接口或抽象类中。 4 完全解耦 当方法操纵的是一个类而非接口时,它就只能作用于那个类或其子类。...使用接口的核心原因之一:为了能够向上转型为多个基类型(以及由此带来的灵活性)。 然而,使用接口的第二个原因与使用抽象基类相同:防止客户端程序员创建这个类的对象,确保这仅仅只是一个接口。...在简单情况下体现在一个方法接受接口作为参数,该接口的实现和传递对象给方法则交由你来做。 因此,接口的一种常见用法是策略设计模式。 编写一个方法执行某些操作并接受一个指定的接口作为参数。...可以说:“只要对象遵循接口,就可以调用方法” ,这使得方法更加灵活,通用,并更具可复用性。 例如,类 Scanner 的构造器接受的是一个 Readable 接口。 ?

    52021

    Java编程思想精粹(On Java8)(十)-接口

    创建抽象类和抽象方法是有意义的,因为它们使得类的抽象性很明确,并能告知用户和编译器使用意图。 抽象类同时也是一种有用的重构工具,使用它们使得我们很容易地将沿着继承层级结构上移公共方法。...除非必须使用,否则不要用接口和抽象类。 大多数时候,普通类已经做得很好,如果不行的话,再移动到接口或抽象类中。 4 完全解耦 当方法操纵的是一个类而非接口时,它就只能作用于那个类或其子类。...使用接口的核心原因之一:为了能够向上转型为多个基类型(以及由此带来的灵活性)。 然而,使用接口的第二个原因与使用抽象基类相同:防止客户端程序员创建这个类的对象,确保这仅仅只是一个接口。...在简单情况下体现在一个方法接受接口作为参数,该接口的实现和传递对象给方法则交由你来做。 因此,接口的一种常见用法是策略设计模式。 编写一个方法执行某些操作并接受一个指定的接口作为参数。...可以说:“只要对象遵循接口,就可以调用方法” ,这使得方法更加灵活,通用,并更具可复用性。 例如,类 Scanner 的构造器接受的是一个 Readable 接口。 ?

    43520

    数据结构与算法:堆排序和TOP-K问题

    ,我们可以实现一个特定的PrintTopK函数,其目的是从数组a中找到最大的k个元素。...将剩余n-k个元素与堆顶比较,替换并调整 测试代码: 3.向上调整建堆与向下调整建堆 对于数组a,进行向上调整建堆: for (int i = 1; i < n; i++) { Ajustup(...每个节点需要执行的向下调整操作取决于其高度,而数组中大约一半的节点是叶子节点,它们不需要被向下调整。对于剩下的节点,只有很少的节点需要移动到树的较低层次。...; 向上调整建堆 对于一个节点来说,向上调整可能需要比较和移动直到它的根节点,这在最坏的情况下是树的高度,对于一个完全二叉树来说,树的高度是 O(\log n) 。...对于数组中的第i个元素,最坏情况下向上调整操作需要沿着一条从叶节点到根节点的路径移动,路径的长度大约等于树的高度 h ,即 O(\log i) 。

    17510

    .NET Core的一个关键特性是性能

    在此之前,从该集合中获取最小或最大对象需要向下遍历树(或向上),调用每个元素的委托,并将返回值设置为当前元素的最小值或最大值,最终到达树的顶部或底部。调用该委托并传递对象意味着有相当多的开销。...直到有一个开发人员看到了这棵树,并删除了不需要的委托调用,因为它没有提供任何值。他自己的基准测试显示有30%-50%的性能提升。...减少使用System.ValueTuple的分配 假设我们想从一个方法返回多个值。以前,我们要么使用out参数,这让人用起来非常不爽,而且在编写async方法时也不支持。...第三种选择是使用特定类型或匿名类型,但是在编写代码时这种做法会引入开销,因为我们需要定义类型,而且如果我们需要的是嵌入在该对象中的值,它也会造成不必要的内存分配。...我们需要获取一个System.String并返回一个新System.String的方法,即要处理的托管版本的子字符串。非托管/堆栈版本将使用char*(是的,一个指针!)

    72820

    Java中摆脱equals,compareTo和toString

    更简明的职责——摆脱equals、compareTo和toString方法 你曾经查看过java文档中的Object类吗?也许吧。每当你向上追溯继承树的时候都会止步于这个类。...本篇文章中我将提出一种使用到Speedment 开源项目上的软件设计方法,这里的对象的方法被定义为存储于变量上的方法引用,而不是重写它们。...这样做确有一些好处:你的POJO将会更短小简洁,通用的方法可以不需要继承而进行复用并且你可以因地制宜地使用它们。 原始的代码 首先我们来看下面的代码:这里有一个典型的Java类Person。...在使用中需要从一个Set中打印出每一个person对象,并且按照姓在前和名在后的顺序排列(以防出现两个相同姓氏的人)。 Person.java ? Main.java ? Output ?...替代这些代码 相比于将所有这些方法写入Person类中,我们可以让它保持尽量的简洁,使用方法引用去处理它们。

    63220

    Java中摆脱equals,compareTo和toString

    更简明的职责——摆脱equals、compareTo和toString方法 你曾经查看过java文档中的Object类吗?也许吧。每当你向上追溯继承树的时候都会止步于这个类。...本篇文章中我将提出一种使用到Speedment 开源项目上的软件设计方法,这里的对象的方法被定义为存储于变量上的方法引用,而不是重写它们。...这样做确有一些好处:你的POJO将会更短小简洁,通用的方法可以不需要继承而进行复用并且你可以因地制宜地使用它们。 原始的代码 首先我们来看下面的代码:这里有一个典型的Java类Person。...在使用中需要从一个Set中打印出每一个person对象,并且按照姓在前和名在后的顺序排列(以防出现两个相同姓氏的人)。 Person.java ? Main.java ? Output ?...替代这些代码 相比于将所有这些方法写入Person类中,我们可以让它保持尽量的简洁,使用方法引用去处理它们。

    65320

    SparkSql的优化器-Catalyst

    Catalyst支持基于规则(rule-based)和基于成本(cost-based)的优化。 其核心是Catalyst包含一个用于表示树并应用规则来操纵它们的通用库。...二,语法树 Catalyst 的主要数据类型就是有节点对象组成的树。每个node都有一个node类型和零个或者多个子节点。Scala中新定义的node类型是TreeNode类的子类。...虽然一个规则可以在其输入树上运行任意代码(给定这个树只是一个Scala对象),但最常见的方法是使用一组模式匹配函数来查找和替换子树为特定结构。...1,语法解析-Analysis SparkSql开始relation计算,既不是从一个SQL parser生成的抽象语法树,也不是从DataFrame对象。...Quasiquotes也适用于我们在原生Java对象上运行的目标:当访问这些对象的字段时,我们可以对所需字段进行代码生成直接访问,而不必将对象复制到Spark SQL Row中,并使用Row 存取方法。

    2.7K90
    领券