Ответы пользователя по тегу ООП
  • Как красиво реализовать возможность подписания блока данных?

    lam0x86
    @lam0x86
    Как я понял задачу: у вас есть две сущности, реализация которых неизвестна:
    • подписываемый объект
    • сервис генерации подписи

    Объект ничего не знает, каким сервисом он будет подписан, а сервис не знает, какая структура у подписываемого объекта.
    В этом случае логично ввести некую промежуточную сущность, в которую объект может себя сериализовать, а сервис будет знать, как её подписать. В простейшем случае это может быть массив, например, byte[]. Можно придумать более изощренный способ с потоковой генерацией подписи, чтобы не создавать промежуточный объект.

    Может, я неправильно понял задачу, но вот, что у меня вышло.

    Интерфейсы:
    public interface ISignable
    {
        ISignature Signature { get; set; }
        byte[] Serialize();
    }
    
    public interface ISignature
    {
    }
    
    public interface ISignatureService
    {
        bool Validate(ISignable signable);
        void Sign(ISignable signable);
    }


    Простейшая имплементация (в качестве подписи используется просто хеш-код):
    class MyObject : ISignable
    {
        public ISignature Signature { get; set; }
        public long Param1 { get; set; }
        public string Param2 { get; set; }
        public string InnerData { get; set; }
    
        public byte[] Serialize()
        {
            return Encoding.UTF8.GetBytes(Param1 + Param2 + InnerData);
        }
    }
    
    public class HashCodeSignatureService : ISignatureService
    {
        public void Sign(ISignable signable)
        {
            var signature = CalculateSignature(signable);
            signable.Signature = signature;
        }
    
        public bool Validate(ISignable signable)
        {
            var s1 = CalculateSignature(signable);
            var s2 = signable.Signature as SimpleHashCodeSignature;
            return s1?.HashCode == s2?.HashCode;
        }
    
        private static SimpleHashCodeSignature CalculateSignature(ISignable signable)
        {
            var body = signable.Serialize();
            var signature = new SimpleHashCodeSignature(body.Aggregate(0, (a, b) => a + b.GetHashCode()));
            return signature;
        }
    }
    
    public class SimpleHashCodeSignature : ISignature
    {
        public int HashCode { get; }
    
        public SimpleHashCodeSignature(int hashCode)
        {
            HashCode = hashCode;
        }
    }


    А так это можно использовать:
    class Program
    {
        static void Main(string[] args)
        {
            var obj = new MyObject {Param1 = 1, Param2 = "asd", InnerData = "some data"};
            var signatureService = new HashCodeSignatureService();
            signatureService.Sign(obj);
            // Passing the object across untrusted boundary
            signatureService.Validate(obj);
        }
    }
    Ответ написан
    Комментировать
  • Как придумывать осмысленные имена для классов?

    lam0x86
    @lam0x86
    1) Изучать популярные проекты на гитхабе, независимо от языка программирования.
    2) Использовать словарь (мне Лингво очень помогает).

    Моё мнение - чем необычнее имя сущности (в разумных пределах), тем проще запоминать структуру проекта. Когда приходится разбираться в чужих проектах, где половина классов называется ControllerBase, ControllerImpl, AbstractControllerFactory и т.п., хочется вешаться.
    Ответ написан
    Комментировать