我想建立一家商店,其中的产品有一个小向导,通过它可以确定价格。在这种情况下,我谈论的是印刷产品。

因此,举个(小)例子,当您来到商店想要打印名片时,您需要决定是要打印黑白还是彩色,如果您想选择厚纸还是薄纸,如果您想要打印 100、200、500 或 1000 件等。

毕竟,我们会说:黑白,厚纸,200 张 => 40,-$

事实上,你还有更多的选择可供选择。所以你可以想到有很多很多的价格,其中有 没有公式.

所以我的问题是:我该如何处理价格?

我的第一个想法:装饰器模式。

但当我转念一想,这并不是一个好主意。正如我所说,没有真正的公式,我还必须生成向导(如果您想打印贺卡,向导可能会有所不同)。我也希望能够更改价格槽管理界面或添加产品或添加新的“决定”,例如“您想要光泽纸?”要使用产品或删除一种(并且仍然保持不变)。

所以现在我正在考虑为每个产品使用一棵树,我可以在其中添加级别(新决策)、度假村级别等。

另一个想法是通过决策构建某种关键对象并在价格表中查找价格。有点像字典,我在其中添加决策,毕竟我从中生成一个键来在价格表中查找价格。

因此,在制作原型之前,我想知道我是否只是盲目的,没有看到明显的解决方案,或者也许还有另一种我不知道的更优雅的方法?

有帮助吗?

解决方案

嗯,我的想法相当复杂,但你的愿望也很复杂。

您所描述的向导的问题是,在他们做出所有选择后,他们可能想回到#2并更改一件事以查看它如何改变价格 - 但您构建向导的方式可能会影响以后是否可以做出选择,并导致您必须为每个产品自定义一组相当复杂的代码 - 而不是将所有内容很好地存储在数据库中,以便代码可以完成所需的所有操作,并且任何产品更改都会发生到数据库中,而不是代码更改。

首先,您需要了解您有定价逻辑,理想情况下这将与演示分开。换句话说,您应该能够向一个客户提供分步向导,并向另一个客户提供带有复选框选项和字段的单个页面,并让他们构建具有相同限制的相同内容。

尽量避免设计数据库,这样你就无法做到其中之一。换句话说,如果您执行“选择您自己的冒险”风格的向导,您就会限制未来的选择(以及客户的灵活性)。原因是,如果我执行 10 个步骤,然后更改步骤 2,我必须再执行 8 个步骤 - 如果你保证我不会重复我已经做出的选择,这可能没问题,但如果我只是改变纸张颜色我不想再做同样的 8 个选择。如果您确实走这条路,请确保保留大量状态,以便他们之前所做的选择下次显示为默认选择。

我会考虑向数据库添加一层抽象。我不想通过用户可以选择的树来指定路径,而是希望看到一个矩阵,其中每个选项以及产品和流程都显示出兼容性。

例如,我有 3 种纸张类型、3 种颜色和 3 种工艺:

    • 常规的
    • 卡片
  • 颜色

    • 红色的
    • 蓝色的
    • 绿色的
  • 过程

    • 打印
    • 折叠
    • 绑定

然后我会为每场比赛定价:

        Light   Regular Card    Red     Blue    Green   Print   Fold    Bind
Light                           0.05    0.05            0.001           0.50
Regular                         0.06    0.05    0.07    0.001   0.02    0.80
Card                                    0.06            0.002           0.90
Print                                                   0.002   
Fold                                                            
Bind                            

空格表示不能混合的项目。
值得注意的条目:

  • 打印和打印相结合 - 双面打印会更频繁地磨损/卡纸机器。
  • 您不能将物品多次通过折叠机(折叠操作为空) - 但您可以列出不同类型的折叠及其适用的纸张
  • 您无法装订折叠的物品
  • 我没有重复矩阵中的项目(即轻质纸打印与打印轻质纸相同 - 取决于您如何制作查询,您将想要表示这一点,或者以无关紧要的方式形成表格)

这只是一个简单体现的示例 - 每个价格实际上都是另一个表的链接,如果数量在一定范围内(即 100 个可能比 10 个便宜),则该表给出每个价格。它还可以确定费用是每张纸、每次操作还是每个订单 - 并且这可能会叠加(因此每张纸的装订费用可能为 0.001,以考虑切刀的磨损,并且 0.50每本装订书的单价,然后总共 5 美元的装订操作安装费)

考虑到你拥有的东西太多了,你可以用其他东西来处理,这很快就会变得相当复杂。

但是,一旦输入数据,您就可以在指定成本并将其呈现给用户方面获得无限的灵活性。例如,您可能会发现,值得将每种不同型号的打印机放在自己的列中(而不是仅仅将它们全部称为打印机),并根据纸张类型、颜色和打印​​操作为客户找到最低的打印价格。

您还可以在矩阵中填写人工(时间),以便可以在与价格估算相同的位置给出时间估算。

无论您是执行向导,还是立即显示页面上的所有内容,此后端都将支持它。看看戴尔在笔记本电脑配置方面的做法——你不能用其他东西来获得某些东西。因此,如果您在页面上显示所有选项,那么当它们从普通纸张更改为卡片纸时,您可以提醒他们:“您还选择了折叠,这与卡片纸不兼容。您确定要进行此更改吗?”

但首先也是最重要的 - 首先编写用例并设计整个系统。如果你现在就开始编写如此复杂的代码,你现在就会做出决定,以后很难撤消,但稍后你会发现你必须做出重大改变,或者在功能上做出妥协。

当然,选择自己的冒险风格更容易设计和开发,唯一的问题是如果你添加一个新的流程或论文,你可能必须更新200棵树,并添加50棵新树。商店中的每次变更都需要部署新的数据库(可能还包括软件),这会延迟资本支出的回报。如果你一开始就让它非常灵活,那么现在会更难,以后会更容易/更快。

此外,您不会将客户限制在树选项上 - 如果他们确实想在一侧通过 4 色印刷机进行打印,在另一侧通过廉价复印机进行打印,如果工艺和材料兼容,他们可以探索该选项。过去 20 个产品/流程,您无法真正完全填写树。

最后,它可以让您非常非常精细地控制成本。如果您的业务流程在细粒度级别跟踪机器使用情况和成本(维护等),您可以低于竞争对手出价,因为您知道您的机器成本 确切地 每页 0.00234,而他们却坚持一般的猜测。如果您开始使用该系统进行跟踪并让员工跟踪问题、维护等,您可能会发现非常奇怪的相关性,例如红色卡片库存在折叠机上的成本更高,因为它比蓝色卡片更频繁地堵塞(无论出于何种原因)。你可以调整你的定价(在这个系统中,调整到第n级),与纸张制造商交谈,停止提供该选项,或者采取一些其他策略来挤压系统。如果您的某些机器需要熟练的操作员,您可以将员工及其工资率添加到矩阵中,并开始安排工作,以便他们更高效地工作。

更新

假设我选择了淡纸,红色,印刷。我如何达到合适的价格?在二维桌上,我有三对红色/印刷,红色/灯光,打印/灯。可悲的是,在做出所有选择后,我无法计算出不断发展的公式的价格。

好吧,我已经简化了上面的内容,但让我们先假设简单的情况。

上表中我没有提及每个价格代表什么。除装订外,所有内容的费用均按页计算。绑定成本是每个绑定项目的成本。

因此,在您的示例中,您选择浅色纸、红色、打印。每张红纸为 0.05 美元(昂贵的纸张!),每张印刷品为 0.001 美元(廉价印刷),因此每张印刷纸的成本为 0.051 美元。如果您要复印 300 份,则总费用为 15.30 美元。

由于装订是按每个装订项目列出的,因此您可以将装订添加到上述订单中,并且您可能将 50 页装订在一起,总共 6 个装订项目,300 页。我们已经知道前面所有物品的成本,因此 6 个绑定物品(每件 0.50 美元)的额外成本为 3.00 美元,新的总计为 18.30 美元。

除了我上面指定的简化之外,您还需要做一些事情:

在矩阵中,我将许多单元格留空。在某些情况下,这是因为进程/对象不兼容(例如,无法绑定折叠项目),但在其他情况下,没有冲突,但它不会花费任何费用。因此,您的红色/常规与常规/红色的示例 - 因为我们将价格加在一起,所以替代组合不需要任何成本。

让我们看看我是否可以说得更清楚......

选择浅色纸、红色、印刷、装订(300 页,6 个装订项目),浏览表格并找到属于该集合的所有价格:

Pricing matrix shows cells where options collide to provide pricing information

您搜索表中的所有元素(红色/浅色和浅色/红色),然后获取价格并分别乘以数量,然后将它们相加。所有这些选择的交集以绿色显示。(浅色纸/浅色纸颜色混乱 - 也应该是绿色)

我删除了打印/打印组合,因为它不适用于此方法(我希望简化事情,但实际上使事情变得更困难)如果您想指定双面打印,您将需要表中的另一个项目(打印例如,反转),您可以同时选择打印和反转打印。交替有两个项目,“单面打印”和“双面打印”。

请记住,虽然我在每个单元格中列出了每个价格,但实际情况是每个单元格实际上描述了一些情况:

  1. 参考定价表
  2. 免费
  3. 约束(不可能组合)

#1 中的引用引用了另一个包含价格和第三个维度的表。例如,组合“light/bound”处的单元格将引用具有以下三个属性的表:

  • 每页价格
  • 每个绑定项目的价格
  • 每个作业(设置)的价格

这些将根据页数和装订项目的数量进行汇总,然后将每份作业的成本添加到顶部。

更加复杂!哇!

这可能适合您的需求,但是如果您的流程仅在某些更复杂的情况下不兼容怎么办?

现在我们可以涵盖一个进程或对象与另一个进程或对象冲突的一般情况。然而,我们无法处理更复杂的事情。

假设轻质纸可以打印,也可以折叠,但不能既打印又折叠。我们不能对打印/折叠施加限制,因为其他纸张可以打印和折叠。

您可以做以下几件事:

  • 添加第三个维度 - 但如果 4 个东西混合在一起,你可能会得到一个无法完成的序列,这意味着另一个维度,等等
  • 使用向量(map/reduce)
  • 添加一个抽象层

矢量很好,但对于这个应用程序来说可能有点过分了。它基本上是第一个项目,但没有定义您可以拥有多少个维度 - 您拥有与对象一样多的维度,因此可以表示任何可能的组合。

附加的抽象层是两者之间的折衷方案。理想情况下,您不会遇到比两个项目更复杂的冲突,但是当您遇到冲突时,您将定义一个代表组合的新对象。因此,在这种情况下,您可能有一个新的对象/过程,它是打印和折叠的组合,并且它在轻质纸张的列上有约束。

您只能针对约束执行此操作,在这种情况下,它不会修改您的定价算法(即,定价仍然来自单个进程和对象的添加。)

或者,您可以使用选择最大组合的算法 - 因此,您不必在数据库中搜索浅色、红色、打印、折叠,而是首先在数据库中搜索组合,这将返回浅色、红色、打印折叠、然后正常定价。

最后,您可以在数据库中搜索单个项目和组合项目,如果存在冲突(组合项目和单个项目的双重定价),那么您可以选择:

  • 最大的成本
  • 最伟大的组合
  • 优先成本(即,每个成本都分配有优先级,您在冲突期间对它们进行比较并选择优先的成本)

-亚当

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top