通过适当的软件工程原则消除复杂问题

时间:2016-06-07 09:57:00

标签: oop design-patterns polymorphism software-design solid-principles

存在CRM系统,可以说有40种不同产品的60种不同订单类型。尽管可能存在相似之处,但每种产品的每个订单的处理是不同的。这些订单的流程逻辑代码涉及复杂的if else语句。代码中的更改是非常危险的,因为它通常会在其他地方破坏一致性,因为长期和复杂的if else。开发人员很难跟踪其他情况。

如何使用OOP原则或其他方式设计系统,以便我们可以将代码更改的效果仅限制为该订单类型和产品。

更新

我们销售服务(s)。 服务可以组合使用并称为捆绑服务是可自定义的,也可以添加子组件。 在购买服务或修改现有服务时,将使用指定为 OrderItems 的自定义组件引发订单。在OrderItems中,有些是 MainOrderItem ,其余与 MainOrderItem (记住捆绑服务)之一有关。 MainOrderItem 与特定的服务直接相关。其他OrderItem与所选子组件相关。每个 OrderItem 都有自己的属性资源

订单的处理方式基于订单类型订单的处理分为几个阶段,有时可能需要一两天。此时复杂的逻辑是,对于60种不同的服务

,对40种不同的订单类型进行了其他条件检查

我的想法是在不同的类(40 * 60类)中使用不同的订单类型服务的处理逻辑,并以某种方式链接它们。在订单处理的起点,基于服务订单类型程序应解析特定类的对象以处理订单和这是唯一的条件检查发生。不同的处理逻辑封装在特定的类中。因此,订单服务的处理逻辑没有任何组合。但是在多个订单服务之间存在一些共同的逻辑,我不想在不同的类中复制这些逻辑。所有这些结合在一起,我正在寻找想法,概念和模式(战略?,模板方法?等)。

2 个答案:

答案 0 :(得分:0)

下面只是一个简单的例子,说明如何解决问题。示例仅考虑服务而不是订单类型,因为在您的问题中它太模糊了。我同意您的问题下面的评论,需要更多细节。

using System;
using System.Collections;
using System.Collections.Generic;  
using System.Linq;

public class Program
{
    public static void Main()
    {
        // Set-up services
        var availableServices = new[]{
            new Service{ServiceId = 1, Name = "Consulting"},
            new Service{ServiceId = 2, Name = "Marketing"}
        };

        // Set-up processors (aka DI container)
        var processors = new Dictionary<int, IOrderProcessor>
        {
            {1, new ConsultingServiceProcessor()},
            {2, new MarketingServiceProcessor()}
        };

        // Generate orders
        var randOrderNumber = new Random();
        var listoOfOrders = availableServices
            .Select(s => new Order{
                Service = s,
                OrderNumber = randOrderNumber.Next(1000, 9999)
            })
            .ToList();


        // Process orders
        listoOfOrders
            .ForEach(order => 
                processors[order.Service.ServiceId]
                .Process(order));

    }

    public class Service
    {
        public int ServiceId {get;set;}
        public string Name {get;set;}
    }
    public interface IOrder
    {
        int OrderNumber {get;set;}
        Service Service  {get;set;}
    }

    public class Order : IOrder
    {
        public int OrderNumber  {get;set;}
        public Service Service  {get;set;}
    }
    public interface IOrderProcessor
    {
        void Process(IOrder order);
    }
    public abstract class BaseOrderProcessor : IOrderProcessor
    {
        // Common data
        public virtual void Process(IOrder order)
        {
            // Common logic
            Console.WriteLine(string.Format("Base logic executed for order nr. {0}", order.OrderNumber));
        }

        protected int CommonMethod()
        {
            return 1;
        }
        // Common internal logic
    }
    public class ConsultingServiceProcessor : BaseOrderProcessor
    {
        // Service specific implementation
        public override void Process(IOrder order)
        {
            // Service specific logic           
            base.Process(order); // skip if not needed

            var commonValue = CommonMethod();

            Console.WriteLine(string.Format("Consuling logic executed for order nr. {0}", order.OrderNumber));
        }
    }
    public class MarketingServiceProcessor : BaseOrderProcessor
    {
        // Service specific implementation
        public override void Process(IOrder order)
        {
            // Service specific logic

            base.Process(order); // skip if not needed

            var commonValue = CommonMethod();

            Console.WriteLine(string.Format("Consuling logic executed for order nr. {0}", order.OrderNumber));
        }
    }

}

答案 1 :(得分:0)

在高级抽象中,您要做的是隔离代码中抽象的各个部分。

所以问题是,40个OrderType中有什么不同,60个服务中有什么不同?

如果答案是我们有大量的投资组合,并且可以维持40 + 60个案例,那么仍然存在组合问题,40 * 60是巨大的。

所以你需要改进和表达服务如何与产品互动,是否只有几类互动,或者所有40 * 60个案例都不同?

可能你想要一个在Abstract策略上有相当多操作的策略,然后你装饰它来表达服务,因为它们可以结合起来,这种方法提供了很好的分层功能。

产品本身可能会覆盖某些行为,也许是一个基本上属于Strategy ++适合的Bridge(服务与产品无关)。