Использовать метод, который работал бы с различными объектами

У меня есть система, которая манипулирует многими типами списков трудящихся (около 30) на предприятии, где я работаю. Все есть данные общим (как личные данные). То, что мне понравилось бы eficientar, состоит в том, чтобы повторно использовать код метода для многих типов трудящихся. Какие-то из классов: Manager, Director и Employee каждый должен проверять Ваш час ввода и я это делаю с другим так называемым классом Company, тогда у меня есть три метода для класса:

public class Company
{
    public void CheckIn(Director Person)
    {

    }

    public void CheckIn(Employee Person)
    {

    }

    public void CheckIn(Manager Person)
    {

    }
}

Завися список, за которым между на предприятии последуют различные вещи в доступах всего здания. Я надеюсь предаться пониманию.

14
задан 31.01.2016, 17:07
7 ответов

Просвет, что, если, что ты можешь делать, является использованием Интерфейсов. Интерфейсы позволяют тебе устанавливать правила для классов (признаки и mГ©todos, у которого закона должен быть) AquГ - пример cГіdigo:

public interface ICommonDataBetweenWorkers
    {
        string Name { get; set; }
        string Identifier { get; set; }
    }

 public class Employee : ICommonDataBetweenWorkers
    {
        public string Name { get; set; }

        public string Identifier { get; set; }
    }

    public class Manager : ICommonDataBetweenWorkers
    {
        public string Name { get; set; }

        public string Identifier { get; set; }
    }

    public class Director : ICommonDataBetweenWorkers
    {
        public string Name { get; set; }

        public string Identifier { get; set; }
    }

    public class Company
    {
        public void CheckIn(ICommonDataBetweenWorkers Person)
        {
            Console.WriteLine(Person.Name);
            Console.WriteLine(Person.Identifier);

            if (Person is Manager)
            {
                //Do something
            }
            else if(Person is Director)
            {
                //Do something
            }

            else if(Person is Employee)
            {
                //Do something

            }
            /*
             * No importa si es manager, director o employee. Mientras implementan la interfaz
             * compartirán los mismos miembros.
             */
        }

, И когда призовешь ты mГ©todo проверения введенная, ты это делаешь asГ-:

 static void Main(string[] args)
        {
            Company C = new Company();

           //Cuando sea Employee
            C.CheckIn(new Employee());

            //Cuando sea Manager
            C.CheckIn(new Manager());

            //Cuando sea Director
            C.CheckIn(new Director());

            //Cuando sea otra cosa
            C.CheckIn(new OtherRoleThatYouHave());
        }
7
ответ дан 24.11.2019, 14:56
  • 1
    Вик, делает мне очень профессиональным твой стиль! –  Elvira 29.01.2016, 00:16

Основанный на, который ты комментируешь

Все есть данные общим (как личные данные). То, что мне понравилось бы eficientar, состоит в том, чтобы повторно использовать код метода для многих типов трудящихся

Кроме выбора использования интерфейсов, возможно достаточно использовать какое-то свойство, которое давало бы тебе список твоего класса Person, например Person.Rol, кроме которого может быть тип проверенный списком, например CheckingType, чтобы группировать различные списки со сходным поведением.

if (Person.Rol.CheckingType == Administrative)
{
//Turno administrativo
}
else if (Person.Rol.CheckingType == Supervisor)
{
//Turno gerentes/supervisores
}
else
{
//Los demás empleados
}
4
ответ дан 24.11.2019, 14:56
  • 1
    +1 Из-за того, что не выставляем ни точка, о которой мы не упомянули, ни Виктор ни я;) –  jasilva 28.01.2016, 01:06

Ты можешь использовать класс наследства или интерфейс Persona, где все общие члены всех классов, о которых ты упоминаешь, это содержали

Так, только у тебя был бы метод CheckIn:

public void CheckIn(Persona persona){

}

Например:

Со связующим звеном Общеизвестными

interface IPersona
{

    string Nombre { get; set; }
    string Apellido { get; set; }
    DateTime FechaIngreso {get; set;}
    //un Largo etc.
}

на свойствах в интерфейсах

И с классом

   public abstract class Persona { //puede ser abstracta o no
        string Nombre { get; set; }
        string Apellido { get; set; }
        DateTime FechaIngreso {get; set;}

        public void MetodoGenerico(){
        }
   }

Из любой формы ты нуждаешься в том, чтобы снабдить ссылками их в "детях", в твоем классе Director tendrГ-схвати, что иметь

public class Director : IPersona //La I es por convención al usar Interfaces

или

public class Director : Persona

Из любого двух форм, которые ты выбираешь, ты упростишь твой много разработку.

10
ответ дан 24.11.2019, 14:56
  • 1
    Эта мне кажется лучшим ответом, интерфейсы добавляют ясность и он делает больше " mantenible" c и # 243; я говорю. Я не могу давать +1, потому что llegu и # 233; в l и # 237; mite. –  Alan 28.01.2016, 20:26

Чтобы касаться концепции SOLID, не deberГ-схватывай использовать какого-либо if или swith, что применился lГіgica согласно человеку, которого ты должен санкционировать.

Поэтому я courre выдвигать что-то как это такие

public abstract class Person {

    public virtual void CheckIn()
    {
        //implementacion por defecto de la validacion
        //usas el "this"" para hacer referencia al objeto
     }

}

public class Director: Person
{

    public override void CheckIn()
    {
        //implementacion para el director
        //usas el this para hacer referencia al objeto
    }

}

public class Employee: Person
{

    public override void CheckIn()
    {
       //implementacion para el empleado
       //usas el this para hacer referencia al objeto
     }

}

public class Manager: Person
{
   //este hace uso de la implementacion base
}

public class Company
{
    public void CheckIn(Person person)
    {
       person.CheckIn();
    }

}

Как края с наследством ты можешь способствовать тому, чтобы класс осуществил Ваше конкретное утверждение. InvocarГ-схвати это этой формы

Company company = new Company();
company.CheckIn(new Director());

В этом случае используйте один virtual, чтобы определять базовое, такое осуществление только ты должен sobreescribir, когда он необходим, но, а ты это хочешь так тебя могло бы определять метод как abstract

3
ответ дан 24.11.2019, 14:56
  • 1
    Для этого случая в особенности я не соглашаюсь использования этой стратегии, в пользу простого мотива, CheckIn кодируется несколько раз, когда правильное состояло бы в том, чтобы только была одна, ты видишь в классе услуги, так как кажется тяжело, чтобы CheckIn имел различную логику списком. И в случае, что он выдвигает @Elvira, кажется больше, что Он Является лично, и остальных классов МАЛО. –  jasilva 28.01.2016, 01:26
  • 2
    @jasilva, помни, что я упомянул, что, если логика сходная для нескольких случаев с виртуальным, ты определяешь ее в базовом классе и не должен определять ее в каждом производном классе. То, что я не понял, потому что ты упоминаешь о классе услуги? я понимаю, что думают работать ориентируемый на объекты, так как хочется избегать определять методы с каждой перегрузкой, делая растяжимое приложение как начала SOLID –  Leandro Tuttini 28.01.2016, 01:30
  • 3
    Если я соглашаюсь полностью с этим, но эта логика кажется, что я не применил к методу CheckIn может быть метод Despedir. Где для смертельного пользователя это был простой insert в таблице и update в другой, для Директора присоединитесь с Вебом service CIA, где он посылает Вашу фотографию и данные для того, чтобы они считали это сторожившим. Окажитесь более благодетельствуемым из этой стратегии, так как логика отличается, и очень уместно считать одну общей и sobreescribir исключения:) –  jasilva 28.01.2016, 01:37

Ввиду того, что ты не определяешь код, который внутри методов CheckIn, я буду стараться отвечать за самую общую форму:

Во-первых первое, что ты должен intentra, состоит в том, чтобы создавать интерфейс трудящихся, который содержал бы поля и методы, которые должны бы быть общими во все. Например:

public interface IRol
{
    int Id { get; set; }
    int HoraMaximaDeLlegada { get; set; }
}

Потом каждый тип рабочего может осуществлять эти поля и методы

public class Director: IRol
{
    public int Id { get; set; }
    public int HoraMaximaDeLlegada { get; set; } 
}

public class Employee: IRol
{
    public int Id { get; set; }
    public int HoraMaximaDeLlegada { get; set; } 
}

public class Manager: IRol
{
    public int Id { get; set; }
    public int HoraMaximaDeLlegada { get; set; } 
}

Таким образом понимая например, что у нас есть следующий класс

public class CheckIn
{
    public int Id { get; set; }
    public int PersonId { get; set; }
    public DateTime FechaCheckIn { get; set; }
    public bool EsTarde { get; set; }
}

Твой метод мог бы сокращаться в:

public class Company
{
    public void CheckIn(IRol person)
    {
        // Acá puedes usar todos los campos disponibles en IRol para realizar la tarea que necesites
        // Ejemplo de implementación
        var now = DateTime.Now;
        var checkIn = new CheckIn
        {
            PersonId = person.Id,
            FechaCheckIn = now,
            EsTarde = now > DateTime.Today.AddHours(person.HoraMaximaDeLlegada)
        };
        //... Hacer algo con ese nuevo checkIn
    }
}

Но это не всегда возможное.

Что происходит, если ты не можешь изменять классы в пользу какого-то мотива так что ты не можешь заставлять их помогать того же интерфейса. И даже, что происходит, если у классов нет тех же полей?

Возможно решать это с главным файлом Адаптер

Этот главный файл использован, чтобы менять "интерфейс" (использованный термин характерным образом, не как interface C#) класса, в котором ты нуждаешься, чтобы приспосабливать ее к API в особенности

Давайте говорить например, что у нас есть следующие классы:

public class Director
{
    public int Id { get; set; }
    // Al ser el director no tiene una hora maxima de llegada
}

public class Employee
{
    public int Id { get; set; }
    public int HoraDeEntrada { get; set; } 
}

public class Manager
{
    public int Id { get; set; }
    public int PuedeLlegarHasta { get; set; }
}

В этом случае мы можем создавать adapter, который стандартизировал бы интерфейс

public abstract class BaseRolAdapter : IRol
{
    public int Id { get; set; }
    public abstract int HoraMaximaDeLlegada { get; set; }

    public BaseRolAdapter(int id)
    {
        Id = id;
    }
}

И потом мы можем создавать subitpo из-за каждого Списка

public class EmployeeAdapter : BaseRolAdapter
{
    public readonly Employee Employee;

    public override int HoraMaximaDeLlegada
    {
        get { return Employee.HoraDeEntrada; }
        set { Employee.HoraDeEntrada = value; }
    }

    public EmployeeAdapter(Employee person)
        : base(person.Id)
    {
        Employee = person;
    }
}

public class ManagerAdapter : BaseRolAdapter
{
    public readonly Manager Manager;

    public override int HoraMaximaDeLlegada
    {
        get { return Manager.PuedeLlegarHasta; }
        set { Manager.PuedeLlegarHasta = value; }
    }

    public ManagerAdapter(Manager person)
        : base(person.Id)
    {
        Manager = person;
    }
}

public class DirectorAdapter : BaseRolAdapter
{
    public readonly Director Director;

    public override int HoraMaximaDeLlegada
    {
        get { return 24; /* Con esto el Director nunca llegara tarde */ }
        set { }
    }

    public DirectorAdapter(Director person)
        : base(person.Id)
    {
        Director = person;
    }
}

Где у каждого осуществления может быть ее собственная логика

Потом класс Company это осталось бы так

public class Company
{
    public void CheckIn(BaseRolAdapter person) // o IRol en lugar de BaseRolAdapter  si implementaba la interfaz
    {
        // Acá puedes usar todos los campos disponibles en IRol para realizar la tarea que necesites
        // Ejemplo de implementación
        var now = DateTime.Now;
        var checkIn = new CheckIn
        {
            PersonId = person.Id,
            FechaCheckIn = now,
            EsTarde = now > DateTime.Today.AddHours(person.HoraMaximaDeLlegada)
        };
        //... Hacer algo con ese nuevo checkIn
    }
}

Таким образом ты можешь способствовать тому, чтобы метод CheckIn всегда зависел от единственного класса или интерфейса, и не иметь один каждым типом служащего.

В любом случае ты единственный звук какие-то идеи, твой случай может меняться considerablemtente, но идея - та же самая, стандартизировать интерфейс, чтобы мочь делать ее единственной для всех видов классов.

4
ответ дан 24.11.2019, 14:56

Я хочу добавить мой ответ, хотя я предлагаю (как остальные) использовать интерфейс в объекте, однако другой выбор был бы следующей:

    private void CheckIn(object person)
    {
        if (person is Director)
        {
            // lógica 1
            return;
        }

        if (person is Manager)
        {
            // lógica 2
            return;
        }

        if (person is Employee)
        {
            // lógica 3
            return;
        }

        throw new Exception("No es de un tipo aceptado por la función.")
    }

Привет и здесь у тебя есть ссылка в "is"

1
ответ дан 24.11.2019, 14:56
  • 1
    Но ты не был бы repectando концепции SOLID, особенно концепция открытого / закрытого –  Leandro Tuttini 28.01.2016, 20:17
  • 2
    Я соглашаюсь с тобой @LeandroTuttini с тем, что не уважается эта концепция (O), поэтому suger и # 237; использовать интерфейс для того, чтобы каждый из них они реализовали то же задание с l и # 243; gica собственная. Но quiz и # 225; будьте opci и # 243; n м и # 225; s в другие. –  Carlos Huchim 28.01.2016, 21:01
  • 3
    Хорошая эта простота! –  Elvira 29.01.2016, 00:15

Также возможно использовать определение класса с характерными параметрами

public EmpleadoCompany<T> where T: ICommonDataBetweenWorkers
{
   public metodo1(T empleado1)
   {
      .....
   }

....


} 
-1
ответ дан 24.11.2019, 14:56

Теги

Похожие вопросы