这是单一责任原则的一个例子吗? [英] It this an example of the Single Responsibility Principle?

查看:111
本文介绍了这是单一责任原则的一个例子吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



为了获得一个 Display()方法,我做了以下代码示例来了解如何使用泛型方法签名。对于客户和员工,我实际上开始用 Person抽象类替换我的 IPerson界面



但是,我停下来,记得一个播客,鲍伯叔叔告诉Scott Hanselman关于单一责任原则的应用程序,你应该有很多小班每个都做一个特定的事情,即客户班不应该有一个 Print() Save() CalculateSalary()方法但您应该有一个 CustomerPrinter类 CustomerSaver类 CustomerSalaryCalculator类



这似乎是一种奇怪的编程方式。但是,除了我的界面外,也感到错误(因为这么多IoC容器和DI示例本身就使用它们),所以我决定尝试单一责任原则。



所以以下代码与以前编程的不同(我将使用Display()方法制作一个抽象类,并摆脱了界面),但基于关于我已经听说过去耦和SOLID原则,这种新的编码方式(界面和PersonDisplayer类)我认为这是正确的方法



我会喜欢听到其他人在这个问题上认为相同的方式,或者经历了这个的正面或负面影响(例如一个笨拙的数字的课程,每个都做一件特别的事情等)。

  using System; 

命名空间TestGeneric33
{
类程序
{
static void Main(string [] args)
{
容器容器= new Container();
客户customer1 = container.InstantiateType< Customer>(Jim,Smith);
雇员employee1 = container.InstantiateType< Employee>(Joe,汤普森);
Console.WriteLine(PersonDisplayer.SimpleDisplay(customer1));
Console.WriteLine(PersonDisplayer.SimpleDisplay(employee1));
Console.ReadLine();
}
}

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

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

public class PersonDisplayer
{
private IPerson _person;

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

public string SimpleDisplay()
{
返回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;组; }
public string LastName {get;组; }
public string Company {get;组;
}

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


解决方案

我喜欢将单一责任原则视为分离职责。在我开始分类我的课程之前,我尝试想想每个课程应该负责什么。



你的课程很简单,并且很好地适用于一个抽象按照您所提到的方式执行 Print() Save()函数。我会倾向于将设计保持在当前的状态。



但是,如果打印和保存更复杂的任务可能会以不同的方式执行,那么专用的打印机 Saver 类是有必要的,因为现在这个责任更复杂了。制作新课程的复杂性门槛非常主观,将取决于具体情况,但最终,代码只是我们低级人类理解的抽象,所以使它变得最直观。 / p>

容器类有点误导。它实际上并不包含任何东西。它实际上实现了工厂方法模式,并将受益于被命名为工厂。

$另外,您的 PersonDisplayer 从来没有实例化,可以通过静态方法提供其所有功能,所以为什么不使它成为一个静态类呢? 实用程序类(如打印机或储存器)是静态的并不罕见。除非您需要具有不同属性的打印机的单独实例,否则请保持静态。


I made the following code example to learn how to use a generics method signature.

In order to get a Display() method for both Customer and Employee, I actually began replacing my IPerson interface with an Person abstract class.

But then I stopped, remembering a podcast in which Uncle Bob was telling Scott Hanselman about the Single Responsibility Principle in which you should have lots of little classes each doing one specific thing, i.e. that a Customer class should not have a Print() and Save() and CalculateSalary() method but that you should have a CustomerPrinter class and a CustomerSaver class and a CustomerSalaryCalculator class.

That seems an odd way to program. However, getting rid of my interface also felt wrong (since so many IoC containers and DI examples use them inherently) so I decided to give the Single Responsibility Principle a try.

So the following code is different than I have programmed in the past (I would have made an abstract class with a Display() method and got rid of the interface) but based on what I have heard about decoupling and the S.O.L.I.D. principles, this new way of coding (the interface and the PersonDisplayer class) I think this is the right way to go.

I would like to hear if others think the same way on this issue or have experienced positive or negative effects of this (e.g. an unwieldy number of classes each doing one particular thing, etc.).

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; }
    }
}

解决方案

I like to think of the Single Responsibility Principle as an implementation of separation of duties. Before I start splitting my classes as you have, I try to think of what each class should be responsible for.

Your classes are quite simple and lend themselves well to an abstract class with an implemented Print() and Save() functions as you mentioned. I would tend to keep that design over your current one.

However, if printing and saving were more complicated tasks which might be performed in different ways then a dedicated Printer or Saver class would be warranted, since that responsibility is now more complex. The 'complexity' threshold for making a new class is very subjective and will depend on the exact situation, but in the end, the code is just an abstraction for us lowly humans to understand, so make it such that it's the most intuitive.

You Container class is a little misleading. It doesn't actually 'contain' anything. It actually implements the Factory Method Pattern and would benefit from being named a factory.

Also, your PersonDisplayer is never instantiated and can provide all of its functionality through static methods, so why not make it a static class? It's not uncommon for utility classes such as Printers or savers to be static. Unless you have a need to have separate instances of a printer with different properties, keep it static.

这篇关于这是单一责任原则的一个例子吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆