Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这是单一责任原则的一个例子吗?_C#_Design Patterns_Solid Principles - Fatal编程技术网

C# 这是单一责任原则的一个例子吗?

C# 这是单一责任原则的一个例子吗?,c#,design-patterns,solid-principles,C#,Design Patterns,Solid Principles,我制作了下面的代码示例来学习如何使用泛型方法签名 为了给客户和员工提供一个Display()方法,我实际上开始用个人抽象类来替换我的IPerson接口 但后来我停了下来,想起了一个播客,在播客中,鲍勃叔叔告诉斯科特·汉斯曼关于“单一责任原则”,在这个原则中,你应该有很多小类,每个小类都做一件特定的事情,即客户类不应该有一个打印()和保存()和CalculateSalary()方法,但您应该拥有CustomerPrinter类和CustomerSaver类以及CustomerSalaryCalcu

我制作了下面的代码示例来学习如何使用泛型方法签名

为了给客户和员工提供一个Display()方法,我实际上开始用个人抽象类来替换我的IPerson接口

但后来我停了下来,想起了一个播客,在播客中,鲍勃叔叔告诉斯科特·汉斯曼关于“单一责任原则”
,在这个原则中,你应该有很多小类,每个小类都做一件特定的事情,即客户类不应该有一个打印()和保存()CalculateSalary()方法,但您应该拥有CustomerPrinter类CustomerSaver类以及CustomerSalaryCalculator类

这似乎是一种奇怪的编程方式。然而,摆脱我的界面也感觉不对(因为有那么多IoC容器和DI示例固有地使用它们),所以我决定尝试一下单一责任原则

因此下面的代码与我以前编写的代码不同(我会用Display()方法创建一个抽象类并去掉接口),但基于我所听到的关于解耦和S.O.L.I.D的内容。原则,这种新的编码方式(接口和PersonDisplayer类)我认为这是正确的方式

我想听听其他人在这个问题上是否也有同样的想法,或者是否经历过这样的积极或消极影响(例如,每个班都做一件特定的事情,数量庞大,等等)

使用系统;
命名空间TestGeneric33
{
班级计划
{
静态void Main(字符串[]参数)
{
容器=新容器();
CustomerCustomer1=container.instanceType(“Jim”、“Smith”);
employee1=container.instanceType(“Joe”、“Thompson”);
Console.WriteLine(PersonDisplayer.SimpleDisplay(customer1));
Console.WriteLine(PersonDisplayer.SimpleDisplay(employee1));
Console.ReadLine();
}
}
公营货柜
{
public T instanceType(stringfirstname,stringlastname),其中T:IPerson,new()
{
T obj=新的T();
obj.FirstName=FirstName;
obj.LastName=LastName;
返回obj;
}
}
公共接口IPerson
{
字符串名{get;set;}
字符串LastName{get;set;}
}
公共类个人显示器
{
私人IPerson(个人),;
公共人员显示人员(i个人)
{
_人=人;
}
公共字符串SimpleDisplay()
{
返回String.Format(“{1},{0}”,_person.FirstName,_person.LastName);
}
公共静态字符串SimpleDisplay(IPerson个人)
{
PersonDisplayer PersonDisplayer=新的PersonDisplayer(个人);
返回personDisplayer.SimpleDisplay();
}
}
公共类客户:IPerson
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串公司{get;set;}
}
公共类员工:IPerson
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
public int EmployeeNumber{get;set;}
}
}

嗯,我以前从未听说过这种“单一责任原则”,但在我看来,使用这些CustomerPrinter类和CustomerSaver类所做的只是将类转换回结构,并使所有内容都面向对象

例如,这意味着不同的客户类型在CustomerPrinter类中需要不同的案例,如果它们需要不同的打印方式。但据我所知,OO组织的一个要点,以及使用继承树和其他所有东西的一个要点,就是不再需要这个CustomerPrinter知道如何打印所有东西:客户知道如何打印自己


我不相信在任何情况下严格遵循这些范例。例如,在您的案例中,我不确定接口和抽象类之间的区别。但是我又是一个C++程序员而不是C程序员。

< P>我认为你走的路是正确的。不过,我并不完全确定容器类。我通常会坚持对这些对象使用“新”的简单解决方案,除非您对该接口有业务驱动的需求。(我不认为“整洁”在这个意义上是一个商业要求)

但是,将“成为”客户责任与“展示客户”分开是很好的。坚持这一点,这是对坚实原则的完美诠释

就我个人而言,我现在已经完全停止在这种代码中使用任何类型的静态方法,我依靠DI在正确的时间和地点获得所有正确的服务对象。一旦你开始进一步阐述坚实的原则,你会发现你正在制作更多的课程。尝试使用这些命名约定以保持一致。

我喜欢将其视为的一个实现。在我开始像你们一样拆分我的类之前,我试着想想每个类应该负责什么

您的类非常简单,可以很好地应用于一个抽象类,该抽象类具有您提到的
Print()
Save()
函数。我倾向于在你现在的设计上保留这种设计

但是,如果打印和保存是更复杂的任务,可能以不同的方式执行,那么就需要一个专用的
打印机
保存程序
类,因为这一职责现在更为复杂。创建新clas的“复杂性”阈值
using System;

namespace TestGeneric33
{
    class Program
    {
        static void Main(string[] args)
        {
            Container container = new Container();
            Customer customer1 = container.InstantiateType<Customer>("Jim", "Smith");
            Employee employee1 = container.InstantiateType<Employee>("Joe", "Thompson");
            Console.WriteLine(PersonDisplayer.SimpleDisplay(customer1));
            Console.WriteLine(PersonDisplayer.SimpleDisplay(employee1));
            Console.ReadLine();
        }
    }

    public class Container
    {
        public T InstantiateType<T>(string firstName, string lastName) where T : IPerson, new()
        {
            T obj = new T();
            obj.FirstName = firstName;
            obj.LastName = lastName;
            return obj;
        }
    }

    public interface IPerson
    {
        string FirstName { get; set; }
        string LastName { get; set; }
    }

    public class PersonDisplayer
    {
        private IPerson _person;

        public PersonDisplayer(IPerson person)
        {
            _person = person;
        }

        public string SimpleDisplay()
        {
            return String.Format("{1}, {0}", _person.FirstName, _person.LastName);
        }

        public static string SimpleDisplay(IPerson person)
        {
            PersonDisplayer personDisplayer = new PersonDisplayer(person);
            return personDisplayer.SimpleDisplay();
        }
    }

    public class Customer : IPerson
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Company { get; set; }
    }

    public class Employee : IPerson
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int EmployeeNumber { get; set; }
    }
}