封装和接口

时间:2017-06-12 17:49:50

标签: c# interface encapsulation

几天后,我一直在微软网站上的.NET教程中研究和学习这一特定课程。 LINK

你可能已经知道有一个"家庭作业"在每节课结束时。 这次我应该使用一些新功能升级给定项目并实现Encapsulation和Interfaces。

新功能应包括:

  • 客户有一个公开其历史订单的财产

    //更新:已实施

  • 客户公开了添加订单的方法

  • 尝试添加空订单应该什么都不做

  • 尝试添加包含现有OrderNumber的订单应替换现有订单(不添加重复订单)

    //我唯一成功的就是删除之前的"命令"使用相同的名称而不是仅替换它。

  • 订单应公开OrderDate(可以读/写)

  • 将来尝试使用OrderDate添加订单应该什么都不做

我确实设法添加了大部分功能。我的项目目前(已更新):

namespace ConsoleApp2
{
class Program
{
    static void Main()
    {
        Customer customer1 = new Customer("John");
        Customer customer2 = new Customer("George");
        var customers = new List<Customer>() { customer1, customer2 };
        customer1.AddOrder("car", "12/7/1999"); // will be removed due to same name
        customer1.AddOrder("vase", "20/6/2024");// will not be added to the list because of the future time
        customer1.AddOrder("car", "3/12/2014");
        customer1.AddOrder("headphones", "3/12/2022");// will not be added to the list because of the future time
        customer2.AddOrder("headphones", "10/3/2002");
        customer2.AddOrder("", "");// will not be added to the list due to empty values

        //print customers

        foreach (var customer in customers)
        {
            customer.Print();
        }
    }
}
public class Customer
{
    public string Name { get; }
    private List<Order> orders = new List<Order>();
    private List<Order> ordersHistory = new List<Order>();


    public Customer(string name)
    {
        Name = name;
    }

    public void AddOrder(string name, string date)
    {
        if (name == null) { return; }
        else if (name == "" || date == "") { return; }
        else
        {
            AddHistoricOrder(name, date);
            AddRegularOrder(name, date);
        }


    }
    public void Print()
    {
        Console.WriteLine(Name);
        Console.Write("Orders: ");
        orders.ForEach(Console.Write);
        Console.WriteLine();
        Console.Write("Historic Orders: ");
        ordersHistory.ForEach(Console.Write);
        Console.WriteLine();
        Console.WriteLine($"Order Count: {orders.Count}");
        Console.WriteLine();
        Console.WriteLine();
    }

    private void AddRegularOrder(string name, string date)
    {

        if (DateTime.Parse(date) > DateTime.Now) { return; }
        else
        {

            for (int i = 0; i < orders.Count; i++)
            {
                if (orders[i].OrderName == name)
                {
                    orders.RemoveAt(i);
                }
            }
            orders.Add(new Order(name, date));

        }
    }
    private void AddHistoricOrder(string name, string date)
    {
        ordersHistory.Add(new Order(name, date));
    }
    public override string ToString()
    {
        return $"{Name}";
    }

}
public class Order
{
    public string OrderName { get; }
    public DateTime OrderDate { get; set; }

    public Order(string orderName, string date)
    {
        OrderName = orderName;
        OrderDate = DateTime.Parse(date);;
    }
    public override string ToString()
    {
        return $"{OrderName} ({OrderDate.ToShortDateString()}), ";
    }
}
}

即使我搜索并观看了各种视频的封装和界面,我仍然不确定如何在这里实现它们。 你能帮我提高我的代码效率吗?

我没有实施暴露历史订单的财产(我只是不确定应该做什么)

此外,我并没有真正理解课程的一部分,即#34; New is Glue&#34;这说我们应该避免在我们的代码中添加新的关键字,并展示一些使用接口的例子。我没有找到给定LINK之外的任何信息 我怎么想避免在这个特定项目中创建新实例? 提前谢谢!

2 个答案:

答案 0 :(得分:1)

  1. 客户有一个展示其历史订单的房产: 只需添加一个getter即可显示订单列表。

    公共列表订单{get;} = new List();

  2. 尝试添加null订单应该什么都不做:

    我认为这里所需的功能是忽略空对象

    public void AddOrder(Order o){  
      if (o == null){  
        return;
      }
    
      //rest of your implememntaton
    }  
    

    您正在使用名称和日期添加订单,而不是尝试传递 将对象命令为函数,为简单起见,假设名称为 唯一标识符。

  3. New is Glue

    除了依赖注入(现在它只是一个流行词)。

    他们试图强调的是“new”关键字会产生依赖关系 在您创建的特定课程上,您应该在将来决定 改变照顾您需要的订单/客户等的班级 回到您的代码并修改它,可能在多个位置。

    目前,您可以使用有限的工具来代替 添加一个为你创建对象的函数,即使是在函数内部 功能你正在使用“新”。

    例如:

    public Order CreateNewOrder(string name, string date) { return new Order (name, date); }

答案 1 :(得分:0)

没有一种完美的方法可以完成任务,总有一种更好的方法可以做到这一点,所以不要担心拥有完美的代码,尤其是当你开始使用时。

我已经阅读了教程并且检查了你的代码我认为你到目前为止做得很好。

关于揭露历史秩序的财产我相信这可以用不同的方式解释,因为它太笼统了。例如,我可以创建另一个列表,添加客户请求的每个订单,而不必担心日期,名称或它是否为空。

另一种方法是添加另一个列表作为主要列表,但是如果您添加一个具有相同名称的订单,它将存储它而不删除前一个,因为它是历史记录。

你可以这样做。

public class Customer
{
    public string Name { get; }
    private List<Order> orders = new List<Order>();
    public List<Order> historicOrders = new List<Order>();


    public Customer(string name)
    {
        Name = name;
    }

    public void AddOrder(string name, string date)
    {
        if (name == "" || date == "" ) ;
        else if (DateTime.Parse(date) > DateTime.Now) ; 
        else
        {

            for (int i = 0; i < orders.Count; i++)
            {
                if (orders[i].OrderName == name)
                {
                    orders.RemoveAt(i);
                }
            }
            orders.Add(new Order(name, date));
            historicOrders.Add(new Order(name, date));

        }
    }

    public void Print()
    {
        Console.WriteLine(Name);
        Console.Write("Orders: ");
        orders.ForEach(Console.Write);
        Console.WriteLine();
        Console.WriteLine($"Order Count: {orders.Count}");
        Console.WriteLine();
        Console.WriteLine();
    }
    public override string ToString()
    {
        return $"{Name}";
    }

}