zoukankan      html  css  js  c++  java
  • 面向对象基本原则

    设计模式是为了让程序具有更好的

    代码重用性、可读性、可拓展性、可靠性、使程序呈现高内聚,低耦合的特性。

    如果软件系统过于简单,则不必要去为了OO而去OO。

    1、 单一责任原则:一个类只负责一项职责

    1)降低了类的复杂度,一个类只负责一项职责。

    2)提高类的可读性,可维护性。

    3)降低变更引起的风险。

    4)通常情况下我们应该遵守单一职责原则;只有类中的方法特别少的时候,可以在方法级别保持单一职责原则。

        public class RoadVehicle
        {
            public void Run(string vehicle)
            {
                Console.WriteLine(vehicle + "在公路上运行!");
            }
        }
        public class RiverVehicle
        {
            public void Run(string vehicle)
            {
                Console.WriteLine(vehicle + "在河中运行!");
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                RoadVehicle rv = new RoadVehicle();
                rv.Run("汽车");
                RiverVehicle riv = new RiverVehicle();
                riv.Run("");
                Console.Read();            
            }
        }
    在类这一层级上遵守单一
        public class Vehicle
        {
            public void RunAtRoad(string vehicle)
            {
                Console.WriteLine(vehicle + "在公路上运行!");
            }
            public void RunInRiver(string vehicle)
            {
                Console.WriteLine(vehicle + "在河中运行!");
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Vehicle vhcl = new Vehicle();
                vhcl.RunAtRoad("汽车");
                vhcl.RunInRiver("");
                Console.Read();            
            }
        }
    在类中的方法上遵守单一

     当类中的方法较少的时候,可以考虑在方法上遵守单一职责。(在方法上遵循单一,并不是一个标准的处理方式)。

    使用Proxy模式,实现单一职责原则:

    没有遵循单一职责原则的例子:
            /// <summary>
            /// 假定,该方法对数据库进行insert操作。
            /// </summary>
            public void Add()
            {
                //权限判断的职责和数据库操作的职责被无礼的实现在一个类中,权限的规则变化和数据库操作的规则变化,都有可能引起DBManager修改当前代码。
                if (GetPermission(id) == "CanAdd")
                {
                    Console.WriteLine("管理员可以增加数据");
                }
            }
    
    使用代理模式对代码进行调整后,有效地实现了职责分离。
        interface IDBAction
        {
            void Add();
            bool Delete();
            void View();
        }
    
        //DBManager 只负责数据的处理。
        public class DBManager : IDBAction
        {       
            public void Add()
            {
                //执行数据增加
            }
    
            public bool Delete()
            {
    
                return false;
            }
    
            public void View()
            {
    
            }
        }
    
        public class DBManagerProxy : IDBAction
        {
            private IDBAction dbManager;
            public DBManagerProxy(IDBAction dbAction)
            {
                dbManager = dbAction;
            }
    
            /// <summary>
            /// 处理权限判断的逻辑
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public string GetPermission(string id)
            {
                //处理权限判断。
                return "CanAdd";
            }
    
            public void Add(string id)
            {
                if (GetPermission(id) == "CanAdd")
                {
                    dbManager.Add();//调用了DBManager中的Add方法。
                }
            }
            //通过代理,将数据操作和权限判断两个职责进行分离,而实际的数据操作由DBManager来执行,此时客户端的调用变的非常简单。        
    
            public bool Delete()
            {
                //部分省略....
                return false;
            }
    
            public void View()
            {
                //部分省略....
            }
        }
    单一职责原则的案例

    2、开闭原则

      随着客户需求的变化,只是增加类,而不是修改现有的类。对拓展开放,对修改关闭。

      常用的设计模式:template method,strategy。

    不遵循开放封闭原则    
        public class BusyBankStaff
        {
            private BankProcess bankProc = new BankProcess();
            public void HandleProcess(Client client)
            {
                switch (client.ClientType)
                {
                    case  "存款用户":
                        bankProc.Deposit();
                        break;
                    case "转账用户":
                        bankProc.Transfer();
                        break;
                    case "取款用户":
                        bankProc.DrawMoney();
                        break;
                }
            }
        }
    
    使用开放封闭原则,对代码进行重构
        interface IBankProcess
        {
            void Process();
        }
    
        class DepositProcess : IBankProcess
        {
            public void Process()
            {
                //办理存款业务。
            }
        }
    
        class TransferProcess : IBankProcess
        {
            public void Process()
            {
                //办理转账业务。
            }
        }
    
        class DrawMoneyProcess : IBankProcess
        {
            public void Process()
            {
                //办理转账业务。
            }
        }
    
        class EasyBankStaff
        {
            private IBankProcess bankProc = null;
            public void HandleProcess(Client client) { 
                //办理业务。
                bankProc = client.CreateProcess();
                bankProc.Process();
            }
        }
    
            static void Main(string[] args)
            {
                EasyBankStaff bankStaff = new EasyBankStaff();
                bankStaff.HandleProcess(new Client("转账用户"));
            }
    
        class Client
        {
            private string ClientType;
            public Client(string clientType)
            {
                ClientType = clientType;
            }
            public IBankProcess CreateProcess()
            {
                //后期可以通过依赖倒置原则,将下面的语句块给消除。
                switch (ClientType)
                {
                    case "存款用户":
                        return new DepositProcess();
                        break;
                    case "转账用户":
                        return new DepositProcess();
                        break;
                    case "取款用户":
                        return new DepositProcess();
                        break;
                }
                return null;
            }
        }
    开放封闭原则的案例

    3、依赖倒置原则

    4、接口隔离原则:客户端不应该依赖它不需要的接口 

    5、里氏替换原则

    6、迪米特法则(最少知道原则,中介者模式)

      一个类对自己依赖的类知道的越少越好,对于被依赖的类来说,不管有多复杂,都尽量将逻辑封装在类的内部,对外除了提供的public方法,不对外泄露任何信息。

      一个类中,尽量不要突然出现一个局部变量(这个局部变量是另外一个类)。

      只能降低类与类之间的耦合,并不能完全消除类与类之间的耦合。

    7、合成复用原则

      尽量使用合成/聚合的方式,而不是使用继承。

    如果只是为了使用类中的方法,那么并不是一定需要去继承,可以使用组合的方式(将类的实例传进去)进行方法的调用。

    创建型设计模式

      单例模式(Singleton Pattern):把对象的创建权限关闭,提供一个公开的静态方法,起到对象重用的作用。(当对象不会被频繁创建的时候,不建议使用单列,因为这样容易占内存)。

      简单工厂:(不属于GOF的23种设计模式)。

      工厂方法(Factory Method Pattern):每个工厂只负责一个对象的创建。

      抽象工厂:每个工厂负责一个产品簇的创建。当多个对象是有机不可分的时候,可以使用抽象工厂来创建多个对象。

      原型模式:把对象创建权限关闭,提供一个公开的静态方法,提供全新的对象,不走构造函数。(使用频率低)。

      建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。(使用频率低)。

    结构型设计模式:关注类与类之间的关系。在面向对象中类与类之间进行交互,才能产生功能;纵向关系:继承/实现;横向关系:依赖、关联、组合、聚合。(关系依次变强)。

      适配器模式(Adapter Pattern):在原类型不变的情况下,拓展新的接口。类适配器、对象适配器。

      桥接模式(Bridge Pattern):把实现和逻辑分开,面向对象聚合复用的思想。

      组合模式(Composite Pattern):不管是个体还是组件,都包含公共的操作接口,通过同样的方式来处理一个组合中的所有对象。组件的典型操作包括:增加、删除、查找、分组和获取子元素等。典型运用:树形结构的数据组织。

      外观模式(Facade Pattern):将表现层和逻辑层分离,封装底层的复杂处理,为用户提供简单的接口。外观模式很多时候是一种系统架构的设计,为复杂系统的解耦,提供了最好的解决方案。

      装饰模式(Decorator Pattern):为原有系统,动态的增加或删除状态和行为,在继承被装饰类的同时包含被装饰类的实例成员。.net 中的stream。

      享元模式:

      代理模式(Proxy Pattern):将复杂的逻辑封装起来,通过代理对象控制实际对象的创建与访问,由代理对象屏蔽原有逻辑的复杂性,同时控制其可访问性。(包一层!)

             代理模式与适配器模式从代码上来看是比较接近的,代理模式是为了对原有的类进行二次封装(可以添加原本没有的功能),适配器是为了兼容。

    行为型设计模式:关注行为与对象的分离

      责任链模式(Chain of Responsibility Pattern):一个请求需要多个环节处理,环节还有可能拓展,变化,调整顺序等问题。  

      模板方法模式(Template Method Pattern):在父类中定义模板,然后由子类实现。具体的实现一般由父类定义好算法的骨架,然后将算法的某些步骤委托给子类。典型应用:asp.net 的Page类。

      迭代器模式(Iterator Pattern):foreach集合。

      中介者模式:

      解释器模式:

      命令模式(Command Pattern):将请求封装为对象,从而将命令的执行者和责任分开。通常在队列中等待命令。典型的应用:菜单系统。

      观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系。当一个对象的状态发生变化的时候,所有依赖于它的对象都得到通知并被自动更新。观察者和被观察者的分开,为模块划分提供了清晰的界限。 .net中的委托和事件。

      备忘录模式:

         状态模式:

      策略模式(Strategy Pattern):将易于变化的部分封装为接口,通常Strategy封装一些运算法则,使者能互换。

      访问者模式:

  • 相关阅读:
    hdu4722Good Numbers(dp)
    poj3373Changing Digits(dp)
    URAL1244. Gentlemen(背包)
    URAL1658. Sum of Digits(DP)
    URAL1635. Mnemonics and Palindromes(DP)
    URAL(DP集)
    URAL1036. Lucky Tickets
    关于int类型的赋值语句正确的有
    float、double的有效位数
    浮点型常量又称实型常量,用于表示有小数部分的十进制数,他有两种表示形式,分别为:
  • 原文地址:https://www.cnblogs.com/vichin/p/11401720.html
Copyright © 2011-2022 走看看