Buscar este blog

martes, 17 de abril de 2018

Introducción a la Programación Orientada a Objeto (POO)

Mi objetivo es enseñarle los conceptos de programación orientada a objeto, modelo de objeto, clases y responsabilidades.

Si comienzas en la programación orientada a objeto, primero deberías saber un poco de historia.
Los orígenes intelectuales de la programación orientada a objetos nacen con el desarrollo del lenguaje Simula (Dahl y Nygaard 1966), pero surgió como una tecnología de software significativa durante la década de 1980 con los lenguaje Smalltalk y C++.

Smalltalk-80 fue una manifestación pionera de la importancia y la utilidad de un área naciente de la informática. La programación orientada a objetos surgió cuando se desarrolló Smalltalk.

La década de 1990 vio el surgimiento del lenguaje de programación Java orientado a objetos. En 1992 la programación orientada a objetos realmente comienza el auge de la programación orientada a objetos.

Si desean profundizar sobre el tema del comienzo de la Programación Orientada a Objetos (POO) o Object-oriented programming (OOP) pueden leer “The emergence of object-oriented technology: the role of community” por Hugh Robinson y Helen Sharp.

Comencemos a conceptualizar.
Qué significa la programación orientada a objeto?
La programación orientada a objetos es un paradigma de programación. Los objetos manipulan los datos de entrada y salida e interactúan entre ellos. Un paradigma de programación es un modelo de diseño y desarrollo de programas que posee un conjunto de reglas.

El modelo orientado a objetos (OO) es una colección de objetos o clases que permite que un programa pueda examinar y manipular elemento de su entorno. Es modelar un problema existente con entidades independientes que interactúan entre sí.

Estas entidades son llamadas objetos con similitud de un objeto del mundo real. Pero es importante no confundir que todo objeto del entorno informático tiene que ser exactamente un objeto del mundo real. Pueden existir objetos en informática que no existan físicamente en el mundo real.Ejemplo: Una fecha se pude considerar un objeto y no es un objeto del mundo real físicamente.

Qué es un objeto y una clase?

En lenguajes de programación como Java y C# (por citarlos) una clase es la definición de las características concretas de un determinado tipo de objetos.

Los objetos son instancias de una clase. Por ende los objetos de una misma clase poseen las mismas responsabilidades siendo las clases abstracciones que generalizan dominios de objetos.

Qué es una responsabilidad?

Las responsabilidades de un objeto se dividen en dos grupos: atributos y métodos. Hay autores que lo llaman a los atributos: campos o fields, propiedade o variables; a los métodos: rutinas o funciones miembro. Los atributos son valores almacenados por los objetos de una clase mientras que los métodos son secuencias de pasos para determinar un comportamiento.

Imagine una tienda que se dedica a vender alimentos tales como manzanas y arroz. La tienda posee un vendedor. El vendedor debe ser capaz de informar al cliente acerca de precio, color, fecha de vencimiento de un producto.

¿Identifique cuáles son las clases y objetos?

En esta situación podemos decir que nuestro modelo orientado a objeto o nuestro entorno del problema son todos los objetos que intervienen en esta tienda.

Primero Identificar los objetos:
N cantidad de manzanas y arroz
Un vendedor
N cantidad de clientes.

Se preguntarán por qué pongo la variable N? Si analizan el problema nunca mencionan la cantidad de manzanas y arroz que hay por ende asumimos que pueden ser cualquier cantidad.

Hasta este paso ya tenemos los objetos ahora debemos agruparlos en clases.

Los objetos N manzanas pertenecen a la clase Manzana.
Los objetos N arroz pertenecen a la clase Arroz.
Pero a la vez las clases Manzana y Arroz son alimentos por ende pertenecen tambien a la clase Alimentos.
El objeto Vendedor pertence a la clase Vendedor
El objeto Cliente pertence a la clase Cliente.
Y la clase Vendedor y Cliente son personas que aunque el problema no lo diga se debe deducir y se crea la clase Persona.

¿Cuáles son sus responsabilidades?

La clase Alimentos, Manzana y Arroz tienen los atributos: precio, color y fecha de vencimiento.
La clase Persona tiene los atributos: RUT, nombre y apellido....
Vendedor y Cliente poseen las misma responabilidades de la clase Persona.
Vendedor también posee un método que es Informar encargado de darle información de los productos de la tienda a los clientes.
Cliente aunque no lo diga el problema para poder recibir información debe tener el método Consultar.

Espero que les hay gustado
Tengan un buen día
Yeiniel Alfonso

jueves, 5 de abril de 2018

EntityFramework + Patrón Repositorio

En tres artículos anteriores explique cómo utilizar ADO.NET y DataSet. En este artículo les voy a explicar cómo utilizar EntityFramework  y el patrón repositorio con dos gestores de bases de datos.

En este artículo no voy a explicar la sintaxis del lenguaje de consulta SQL ni MySQL, ni algunos pasos ya que se encuantra escrito en los tres artículos mencionados.

El código hablará por si solo:

Crearemos la clase conexión.


static class Connection
    {
       internal static string Connected()
       {
           var provider = ConfigurationManager.AppSettings.Get("DataProvider");
           return GetBase(provider);
       }

        internal static string Connected(EnumDataProvider dataProvider)
        {
            return GetBase(dataProvider.ToString());
        }

        private static string GetBase(string provider)
        {
            switch (provider.ToLower())
            {
                case "sql":
                    return "name=Sql";
                case "mysql":
                    return "name=MySql";
                default:
                    return "";
            }
        }
    }

Vamos a crear una clase que mapea un objeto y una tabla de una base de datos.


class MapperEngineering : EntityTypeConfiguration
    {
        public MapperEngineering()
        {
            ToTable("Engineering");

            HasKey(item => item.Id);
            Property(item => item.Id)
                .HasColumnName("Id")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                .IsRequired();

            Property(item => item.Name)
                .HasColumnName("Name")
                .HasMaxLength(255)
                .IsUnicode()
                .IsRequired();
        }
    }

Se crea el contexto de la base de datos

class DataBaseContext : DbContext
    {
        public DataBaseContext()
            : base(Connection.Connected()) { }

        public DataBaseContext(EnumDataProvider dataProvider) :
            base(Connection.Connected(dataProvider)) { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove();
            modelBuilder.Configurations.Add(new MapperEngineering());
            base.OnModelCreating(modelBuilder);
        }
    }

Ahora vamos a crear la interfaz y el patrón repositorio base

public interface IRepositoryGeneric where T : Entity
    {
        #region CRUD
        void Insert(T entidad);

        void Delete(T entidad);

        IEnumerable Find(Expression> expresion);

        T GetById(long id);

        IEnumerable FindAll();

        IEnumerable FindAll(Expression> orderbyExpression);

        void Saves(T entidad);
        #endregion

        #region Paged
        IEnumerable GetPage(bool desc, Expression> orderbyExpression, int currentPage,
            int pageSize, out int totalCount);

        IEnumerable GetPage(bool desc, Expression> orderbyExpression,
            Expression> expression, int currentPage, int pageSize, out int totalCount);
        #endregion

        #region Other

        decimal Sum(Expression> expression);

        bool Exist(Expression> expresion, out IEnumerable items);

        bool Exist(long id, out T item);
        #endregion
    }

public class Repository : IDisposable, IRepositoryGeneric where T : Entity
    {
        private readonly DbContext _contexto;
        private readonly DbSet _entities;
        private bool _disposed;

        public Repository(EnumDataProvider dataProvider)
        {
            _contexto = new DataBaseContext(dataProvider);
            _entities = _contexto.Set();
        }

        protected Repository()
        {
            _contexto = new DataBaseContext();
            _entities = _contexto.Set();
        }

        #region CRUD
        public void Insert(T entidad)
        {
            _entities.Add(entidad);
            _contexto.Entry(entidad).State = EntityState.Added;
        }

        public void Delete(T entidad)
        {
            _entities.Remove(entidad);
            _contexto.Entry(entidad).State = EntityState.Deleted;
        }

        public IEnumerable Find(Expression> expresion)
        {
            return _entities.Where(expresion);
        }

        public T GetById(long id)
        {
            return _entities.Find(id);
        }

        public IEnumerable FindAll()
        {
            return _entities;
        }

        public IEnumerable FindAll(Expression> orderbyExpression)
        {
            return _entities.OrderBy(orderbyExpression);
        }

        public void Saves(T entidad)
        {
            var entry = _contexto.Entry(entidad);
            entry.State = EntityState.Modified;
        }
        #endregion

        #region Paged
        public IEnumerable GetPage(bool desc, Expression> orderbyExpression, int currentPage,
            int pageSize, out int totalCount)
        {
            totalCount = _entities.Count();
            if (desc)
            {
                return
                    _entities.OrderByDescending(orderbyExpression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
            }

            return
                    _entities.OrderBy(orderbyExpression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
        }

        public IEnumerable GetPage(bool desc, Expression> orderbyExpression,
            Expression> expression, int currentPage, int pageSize, out int totalCount)
        {
            totalCount = _entities.Count(expression);

            if (desc)
            {
                return
                    _entities.Where(expression).OrderByDescending(expression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
            }

            return
                    _entities.Where(expression).OrderBy(expression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
        }

        #endregion

        #region Other

        public decimal Sum(Expression> expression)
        {
            return _entities.Sum(expression);
        }

        public bool Exist(Expression> expresion, out IEnumerable items)
        {
            items = Find(expresion);
            return items.Any();
        }
        public bool Exist(long id, out T item)
        {
            item = GetById(id);
            return item != null;
        }
        #endregion

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!_disposed)
                if (disposing)
                    _contexto.Dispose();
            _disposed = true;
        }
    }

 public class RepositoryEngineering: Repository
    {
        public RepositoryEngineering() { }

        public RepositoryEngineering(EnumDataProvider dataProvider) 
            : base(dataProvider) { }
    }

TEST

[TestMethod]
        public void SelectRepository()
        {
            var context = new RepositoryEngineering();
            var n = context.FindAll();

            Assert.AreEqual(n.Count(), 7);
        }

[TestMethod]
        public void InsertRepository()
        {
            var context = new RepositoryEngineering(EnumDataProvider.MySql);
            context.Insert(new Engineering { Name = "Engineering" });
        }
 
Saludos