软件体系结构设计原则

软件体系结构设计原则

一【实验目的】

  1. 理解面向对象设计原则的基本概念
  2. 掌握主要设计原则的概念、实现方法和实例
    二【实验内容】
    1.里氏替换原则
    举一个符合里氏替换原则的例子,用代码实现
    里氏替换原则:
    • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
    • 子类中可以增加自己特有的方法
    • 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松
    • 当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的的输出/返回值)要比父类的方法更严格或相等
    代码实例:
using System;
namespace lishitihuan
{
    class Program
    {
        static void Main(string[] args)
        {
            Animal animal1 = new Tiger();   //通过多态创建老虎对象
            Animal animal2 = new Cat();     //通过多态创建猫对象
            animal1.setRunSpeed(30);
            animal2.setRunSpeed(20);
            Console.WriteLine("如果奔跑300公里");
            Console.WriteLine("那么老虎将奔跑" + animal1.getRunSpeed(300));
            Console.WriteLine("那么猫将奔跑" + animal2.getRunSpeed(300));
        }
    }
    class Animal
    {
        private double runSpeed;
        private double flySpeed;
        public void setRunSpeed(double speed)
        {
            this.runSpeed = speed;
        }
        public double getRunSpeed(double distance)
        {
            return distance / runSpeed;
        }
    }
    class Tiger :Animal   //定义老虎类,直接继承动物类的方法
    {
    }
    class Cat : Animal    //定义猫类,直接继承动物类的方法
    {
    }  
}

2.依赖倒置原则
举一个符合依赖倒置原则 的例子,用代码实现
依赖倒置原则:
• 每个类尽量提供接口或抽象类,或者两者都具备。
• 变量的声明类型尽量是接口或者是抽象类。
• 任何类都不应该从具体类派生。
• 使用继承时尽量遵循里氏替换原则。
实例代码如下:

using System;
namespace yilaidaozhi
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();      //初始化顾客类
            Console.WriteLine("顾客购买以下商品");   
            customer.shopping(new ZhangsanShop());   //顾客执行shopping方法,参数是对应的商店对象
            customer.shopping(new LisiShop());
        }
    }
    interface Shop
    {
        public String sell();  //定义接口Shop以及抽象方法
    }
    class ZhangsanShop :Shop{
        public String sell()
        {
            return "张三商店销售的东西";  //实现接口以及抽象方法
        }
    }
    class LisiShop : Shop
    {
        public String sell()
        {
            return "李四商店销售的东西";  //实现接口以及抽象方法
        }
    }
    class Customer
    {
        public void shopping(Shop shop)
        {
            Console.WriteLine("顾客买到"+shop.sell());  //定义顾客类以及购买方法
        }
    }
}

3. 接口隔离原则
举一个符合接口隔离原则的例子,用代码实现
• 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。
• 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。
• 了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑。
• 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
例子:宠物狗和鸽子都有着捕食(hunt)行为,但是又都有着各自的特有的方法,比如宠物狗有奔跑(run)和行走(walk)行为,而鸽子有滑翔(glide)和飞翔(fly)行为,如果将所有行为设置成一个接口,然后宠物狗和鸽子去继承这一个接口,那么势必会造成接口的代码冗余。
实例:

using System;
namespace ISP
{
    /// <summary>
    /// 接口隔离原则
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Dog dog = new Dog();
            PetDog petDog = new PetDog();
            dog.hunt(petDog);
            dog.run(petDog);
            dog.walk(petDog);

            Bird bird = new Bird(); 
            Dove dove = new Dove();
            bird.fly(dove);
            bird.glide(dove);
            bird.hunt(dove);
        }
    }
    interface BehaviorOne
    {
        void hunt();  //捕食行为
    }
    interface BehaviorTwo
    {
        void walk();  //行走行为
        void run();   //奔跑行为
    }
    interface BehaviorThree
    {
        void glide();  //滑翔行为
        void fly();    //飞翔行为
    }
    class Dog 
    {
        public void hunt(BehaviorOne one)
        {
            one.hunt();
        }
        public void walk(BehaviorTwo two)
        {
            two.walk();
        }
        public void run(BehaviorTwo two)
        {
            two.run();
        }
    }
    class PetDog :BehaviorOne,BehaviorTwo
    {
        public void hunt()
        {
            Console.WriteLine("宠物狗:我喜欢吃狗粮");
        }
        public void walk()
        {
            Console.WriteLine("宠物狗:我喜欢行走");
        }
        public void run()
        {
            Console.WriteLine("宠物狗:我喜欢奔跑");
        }
    }
    class Bird
    {
        public void hunt(BehaviorOne one)
        {
            one.hunt();
        }public void fly(BehaviorThree three)
        {
            three.fly();
        }public void glide(BehaviorThree three)
        {
            three.glide();
        }
    }
    class Dove : BehaviorOne, BehaviorThree
    {
        public void fly()
        {
            Console.WriteLine("鸽子:我喜欢飞翔");
        }
        public void glide()
        {
            Console.WriteLine("鸽子:我喜欢滑翔");
        }
        void BehaviorOne.hunt()
        {
            Console.WriteLine("鸽子:我喜欢吃东西");
        }
    }
}

4.迪米特法则
举一个符合迪米特法则的例子,用代码实现
 从依赖者的角度来说,只依赖应该依赖的对象。
 从被依赖者的角度说,只暴露应该暴露的方法。
例子:明星由于全身心投入艺术,所以许多日常事务由经纪人负责处理,如与粉丝的见面会,与媒体公司的业务合作等。这里的经纪人是明星的朋友,而粉丝和媒体公司是陌生人,所以适合使用迪米特法则。
代码如下:

using System;
namespace LKP
{
    /// <summary>
    /// 迪米特法则(最少知道原则)
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Agent agent = new Agent();
            agent.setStar(new Star("渣渣林"));
            agent.setFans(new Fans("渣渣粉"));
            agent.setCompany(new Company("渣渣潮流股份有限公司"));
            agent.meetFans();
            agent.meetCompany();
        }
    }
    class Star
    {
        private String name;
        public Star(String name)
        {
            this.name = name;
        }
        public String getName()
        {
            return name;
        }
    }
    class Agent
    {
        private Star myStar;
        private Company myCompany;
        private Fans myFans;
        public void setStar(Star myStar)
        {
            this.myStar = myStar;
        }
        public void setFans(Fans myFans)
        {
            this.myFans = myFans;
        }
        public void setCompany(Company myCompany)
        {
            this.myCompany = myCompany;
        }
        public void meetFans()
        {
            Console.WriteLine(myStar.getName() + "与" + myFans.getName() + "见面了");
        }
        public void meetCompany()
        {
            Console.WriteLine(myStar.getName() + "和" + myCompany.getName() + "见面了");
        }
    }
    class Company
    {
        private String name;
        public Company(String name)
        {
            this.name = name;
        }
        public String getName()
        {
            return name;
        }
    }
    class Fans
    {
        private String name;
        public Fans(String name)
        {
            this.name = name;
        }
        public String getName()
        {
            return name;
        }
    }
}

5. 开闭原则
举一个符合开闭原则的例子,用代码实现
例子:猫和狗都会叫,但是叫的方式不同,所以可以让他们同时继承一个Pet类,里面设一个抽象方法say(),继承之后实现抽象方法,就可以实现不修改源代码,只修改代码就能增加一个宠物了。
代码:

using System;
namespace OCP
{
    class Program
    {
        static void Main(string[] args)
        {
            Pet dog = new Dog();
            dog.say();
            Pet cat = new Cat();
            cat.say();
        }
        abstract class Pet
        {
            public abstract void say();
        }
        class Dog:Pet
        {
            public override void say()
            {
                Console.WriteLine("狗叫:汪汪汪");
            }
        }
        class Cat : Pet
        {
            public override void say()
            {
                Console.WriteLine("猫叫:喵喵喵");
            }
        }
    }
}
 

遇到的问题:在学习各种设计模式方法的时候,对它们里面的方法调用以及该传什么参数等等还不是很熟悉,在开闭原则的使用的时候用到了多态,还有所有原则都用到了继承和实现接口,C#语言的这些语法忘了很多。
解决方法:在学习这些原则的同时对C#编程的继承和接口以及多态的这一部分又重新复习了一下,基本掌握了这些之后学这些原则就不是那么吃力了。
感想:代码以及各种原则如果想要彻底熟悉必须要多见见例子,多敲敲代码,不能仅仅是看,那样只会使纸上谈兵。对于软件设计模式,虽然现在一些小体量的程序用不到,但是以后软件体量大了,这些方法一定会着手使用。所以自己必须要熟练掌握。

上篇:软件设计模式例子代码  【例2.2】简单工厂方法模式-汽车保险  【例2.3】工厂方法模式-汽车保险  【例2.4】抽象工厂模式-房屋信息  【例2.5】生成器模式-房屋信息  【例2.6】单例模式-互联网连接  【例3.2】组合模式-五子棋代码  【例3.3】组合模式-空军指挥系统  【例3.4】组合模式-世界问候语  【例3.7】类适配器模式-客户信息验证  【例3.8】对象适配器模式-字符串排序  【例3.10】外观模式-安全系统  【例3.11】外观模式-椭圆功能  【例3.13】桥接模式-茶水机系统  【例3.14】桥接模式-几何立体体积  【例4.1】迭代器模式-矩阵搜索  【例4.2】迭代器模式-产品搜索  【例4.4】访问者模式-名牌鞋销售软件  【例4.5】访问者模式-计算机部件销售软件  【例4.6】命令模式-室内温度控制  【例4.7】命令模式-室内温度控制-2个GUI  【例4.8】命令模式-室内温度控制-3个GUI  【例4.10】中介者模式-旅游信息共享  【例4.11】中介者模式-海岛机场  【例4.13】策略模式-整数排序  【例4.14】策略模式-中国属相  【例4.16】状态模式-交通信号灯-设计1  【例4.16】状态模式-交通灯信号灯-设计2  【例4.16】状态模式-交通灯信号灯-设计3 下篇:软件体系结构例子代码  【例6.4】结构化设计-文件更新-C源代码  【例6.5】面向对象设计架构-文件更新  【例6.7】顺序批处理架构-文件更新  【例6.8】顺序批处理架构-图像处理  【例6.9】管道过滤器架构-主动过滤器  【例6.10】管道过滤器架构-被动过滤器  【例6.11】管道-过滤器架构-文件更新  【例6.12】管道-过滤器架构-图像处理程  【例6.14】事件体系结构-鼠标响应  【例6.17】事件体系结构-观察者模式-大草原1  【例6.18】事件体系结构-观察者模式-大草原2  【例6.19】事件体系结构-观察者模式-温度显示  【例6.21】层次架构-软件测试  【例6.22】层次架构-银行- Access数据库  【例6.23】MVC架构-手车拍卖-无观察者  【例6.24】MVC架构-手车拍卖-观察者-3个图形界面  【例6.25】MVC架构-手车拍卖-观察者-1个图形界面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值