C# 这是单一责任原则的一个例子吗?
我制作了下面的代码示例来学习如何使用泛型方法签名 为了给客户和员工提供一个Display()方法,我实际上开始用个人抽象类来替换我的IPerson接口 但后来我停了下来,想起了一个播客,在播客中,鲍勃叔叔告诉斯科特·汉斯曼关于“单一责任原则”,在这个原则中,你应该有很多小类,每个小类都做一件特定的事情,即客户类不应该有一个打印()和保存()和CalculateSalary()方法,但您应该拥有CustomerPrinter类和CustomerSaver类以及CustomerSalaryCalculator类 这似乎是一种奇怪的编程方式。然而,摆脱我的界面也感觉不对(因为有那么多IoC容器和DI示例固有地使用它们),所以我决定尝试一下单一责任原则 因此下面的代码与我以前编写的代码不同(我会用Display()方法创建一个抽象类并去掉接口),但基于我所听到的关于解耦和S.O.L.I.D的内容。原则,这种新的编码方式(接口和PersonDisplayer类)我认为这是正确的方式 我想听听其他人在这个问题上是否也有同样的想法,或者是否经历过这样的积极或消极影响(例如,每个班都做一件特定的事情,数量庞大,等等)C# 这是单一责任原则的一个例子吗?,c#,design-patterns,solid-principles,C#,Design Patterns,Solid Principles,我制作了下面的代码示例来学习如何使用泛型方法签名 为了给客户和员工提供一个Display()方法,我实际上开始用个人抽象类来替换我的IPerson接口 但后来我停了下来,想起了一个播客,在播客中,鲍勃叔叔告诉斯科特·汉斯曼关于“单一责任原则”,在这个原则中,你应该有很多小类,每个小类都做一件特定的事情,即客户类不应该有一个打印()和保存()和CalculateSalary()方法,但您应该拥有CustomerPrinter类和CustomerSaver类以及CustomerSalaryCalcu
使用系统;
命名空间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; }
}
}