计算机科学与技术学院 实 验 报 告
课程名称: 软件设计模式 专 业: 计算机科学与技术 班 级: 2011 级 1 班 学 号: 2 姓 名: 刘
实验一 单例模式的应用
1 实验目的
1) 掌握单例模式(Singleton)的特点 2) 分析具体问题,使用单例模式进行设计。
2 实验内容和要求
很多应用项目都有配置文件,这些配置文件里面定义一些应用需要的参数数据。
通常客户端使用这个类是通过new一个AppConfig的实例来得到一个操作配置文件内容的对象。如果在系统运行中,有很多地方都需要使用配置文件的内容,系统中会同时存在多份配置文件的内容,这会严重浪费内存资源。
事实上,对于AppConfig类,在运行期间,只需要一个对象实例就够了。那么应该怎么实现呢?用C#控制台应用程序实现该单例模式。绘制该模式的UML图。
UML图:
AppConfig-ParameterA : string+GetParameterA()+SetParameterA()
源代码:
class Program {
static void Main(string[] args) {
AppConfig appConfigOne = AppConfig.GetParameterA(); AppConfig appConfigTwo = AppConfig.GetParameterA(); if (appConfigOne.Equals(appConfigTwo)) {
Console.WriteLine(\"appConfigOne 和 appConfigTwo 代表的是同一个实例!\");
} else {
Console.WriteLine(\"appConfigOne 和 appConfigTwo 代表的是不同的实例!\"); }
Console.ReadKey(); } } }
运行结果:
实验小结:
通过这次实验,我了解了单例模式的具体概念和使用方法,并且感受到了他的优点带来的方便,但是同时也知道了该设计模式的缺点:由于单例模式中没有抽象层,因此单例类的扩展有很大困难。
实验二 工厂模式的应用
1 实验目的
1) 掌握工厂模式(Factory)的特点 2) 分析具体问题,使用工厂模式进行设计。
2 实验内容和要求
有一个OEM制造商代理做HP笔记本电脑(Laptop),后来该制造商得到了更多的品牌笔记本电脑的订单Acer,Lenovo,Dell,该OEM商发现,如果一次同
时做很多个牌子的本本,有些不利于管理。利用工厂模式改善设计,用C#控制台应用程序实现该OEM制造商的工厂模式。绘制该模式的UML图。 UML图:
源代码:
class Laptop {
public virtual void GetLaptop() { } }
class HpLaptop:Laptop {
public override void GetLaptop() {
Console.WriteLine(\"生产了一台Hp电脑\"); } }
class AcerLaptop : Laptop {
public override void GetLaptop() {
Console.WriteLine(\"生产了一台Acer电脑\"); } }
class LenovoLaptop : Laptop {
public override void GetLaptop() {
Console.WriteLine(\"生产了一台Lenovo电脑\");
} }
class DellLaptop : Laptop {
public override void GetLaptop() {
Console.WriteLine(\"生产了一台Dell电脑\"); } }
interface IFactory {
Laptop CreateFactory(); }
class HpFactory:IFactory {
public Laptop CreateFactory() {
return new HpLaptop(); } }
class AcerFactory : IFactory {
public Laptop CreateFactory() {
return new AcerLaptop(); } }
class LenovoFactory : IFactory {
public Laptop CreateFactory() {
return new LenovoLaptop(); } }
class DellFactory : IFactory {
public Laptop CreateFactory() {
return new DellLaptop(); } }
class Program {
static void Main(string[] args)
{
IFactory laptopFactory = new LenovoFactory(); IFactory laptopFactory1 = new HpFactory(); IFactory laptopFactory2 = new AcerFactory(); IFactory laptopFactory3 = new DellFactory(); Laptop laptop = laptopFactory.CreateFactory(); Laptop laptop1 = laptopFactory1.CreateFactory(); Laptop laptop2 = laptopFactory2.CreateFactory(); Laptop laptop3 = laptopFactory3.CreateFactory(); laptop.GetLaptop(); laptop1.GetLaptop(); laptop2.GetLaptop(); laptop3.GetLaptop(); Console.ReadKey(); } } }
运行结果:
实验小结:
通过本次实验,我了解了工厂模式的适用范围和他的一些特点,工厂模式在一定程度上解决某些代码违反了面向对象设计的开放封闭原则。同时还了解了它的一些优点和弊端,比如:使用工厂方法模式的另一个优点是在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其它的具体工厂和具体产品,而只要添加一个新的具体工厂和具体产品即可。
实验三 抽象工厂模式的应用
1 实验目的
1) 掌握抽象工厂模式(Abstract Factory)的特点 2) 分析具体问题,使用抽象工厂模式进行设计。
2 实验内容和要求
麦当劳(McDonalds)和肯德基(KFC)快餐店都经营汉堡(Hamburg)和可乐(Cola),用C#控制台应用程序实现这两个快餐店经营产品的抽象工厂模式。绘制该模式的UML图。 UML图:
源代码:
interface IHamburg {
void HamburgName(); }
class McDonaldsHamburg : IHamburg {
public void HamburgName() {
Console.WriteLine(\"这是McDonalds Hamburg\"); } }
class KFCHamburg : IHamburg {
public void HamburgName() {
Console.WriteLine(\"这是KFC Hamburg\"); } }
interface ICola {
void ColaName(); }
class McDonaldsCola : ICola {
public void ColaName() {
Console.WriteLine(\"这是McDonalds Cola\"); } }
class KFCCola : ICola {
public void ColaName() {
Console.WriteLine(\"这是KFC Cola\"); } }
interface IFactory {
IHamburg CreateHamburg(); ICola CreateCola(); }
class McDonaldsFactory : IFactory {
public IHamburg CreateHamburg() {
return new McDonaldsHamburg(); }
public ICola CreateCola()
{
return new McDonaldsCola(); } }
class KFCFactory : IFactory {
public IHamburg CreateHamburg() {
return new KFCHamburg(); }
public ICola CreateCola() {
return new KFCCola(); } }
class Program {
static void Main(string[] args) {
IFactory factory = new KFCFactory(); IFactory factory1 = new McDonaldsFactory();
IHamburg hamburg1 = factory1.CreateHamburg(); ICola cola1 = factory1.CreateCola(); IHamburg hamburg = factory.CreateHamburg(); ICola cola = factory.CreateCola();
hamburg.HamburgName(); cola.ColaName(); hamburg1.HamburgName(); cola1.ColaName(); Console.ReadKey(); } } }
运行结果:
实验小结:
通过本次实验,加深了对抽象工厂模式的理解。抽象工厂提供一个创建一系列相关或相互依赖对象的接口,而不需指定他们具体的类。抽象工厂同样是存在缺点的,难以支持新种类的产品。 由于以前对C++不太了解,本次实验加深了对C++的了解,强化了编程能力。理解解了构造函数,虚函数,纯虚函数,成员函数实现,类之间的继承等含义。 但对于函数的调用问题常常出错,这在以后的学习中应多加注意和练习。
实验四 建造者模式的应用
1 实验目的
1) 掌握建造者模式(Builder)的特点
2) 分析具体问题,使用建造者模式进行设计。
2 实验内容和要求
建造者模式是一种创建型模式,它主要是应对项目中一些复杂对象的创建工作。所谓“复杂对象”,是指此对象中还含有其它的子对象。我们现在定义一个场景:汽车生产必须包含车轮(Wheel)、油箱(OilBox)和车身(Body),应用建造者模式,用C#控制台应用程序实现该设计,构建BMW品牌和BenZ品牌汽车生产。绘制该模式的UML图。 UML图:
源代码:
public abstract class ICar {
public abstract void Wheel(); public abstract void OilBox(); public abstract void Body(); }
class Benz:ICar {
public override void Wheel() {
Console.Write(\"奔驰的轮子,\"); }
public override void OilBox() {
Console.Write(\"奔驰的油箱,\"); }
public override void Body() {
Console.WriteLine(\"奔驰的车体!\"); } }
class BMW:ICar {
public override void Wheel() {
Console.Write(\"宝马的轮子,\");
}
public override void OilBox() {
Console.Write(\"宝马的油箱,\"); }
public override void Body() {
Console.WriteLine(\"宝马的车体!\"); } }
class Driver {
public void include(ICar car) {
car.Wheel(); car.OilBox(); car.Body(); } }
class Program {
static void Main(string[] args) {
ICar car = new Benz(); ICar car1 = new BMW();
Driver zhangsan = new Driver(); zhangsan.include(car); Driver lisi = new Driver(); lisi.include(car1);
Console.ReadKey();
}
} }
运行结果:
实验小结:
建造者模式的设计目的是消除其他对象的复杂创建过程。使用建造者模式不仅是最佳的做法,而且在某个对象的构建和配制方法改变时可以尽量减少重复更改代码
实验五 适配器模式的应用
1 实验目的
1) 掌握适配器模式(Adapter)的特点 2) 分析具体问题,使用适配器模式进行设计。
2 实验内容和要求
一个软件团队开发绘图系统,设计了圆对象(Circle)、矩形对象(Rectangle),线对象(Line)都支持Draw()函数,即可以通过Draw()函数绘制图形。为了加快项目进度,将角度对象(Angle)绘制功能交给了合作团队实现。但合作团队将角度对象绘制函数定为了DrawAngle()。绘图系统提供给用户后,用户不满意,希望能统一的调用,不用记太多命令。应用适配器模式,用C#控制台应用程序完善该设计。绘制该模式的UML图。
UML图:
源代码:
abstract class IDrawing {
public abstract void Draw(); }
class Circle : IDrawing {
public override void Draw() {
Console.WriteLine(\"这是Circle里面的Draw方法\"); } }
class Rectangle : IDrawing {
public override void Draw() {
Console.WriteLine(\"这是Rectangle里面的Draw方法\"); } }
class Line : IDrawing {
public override void Draw() {
Console.WriteLine(\"这是Line里面的Draw方法\"); } }
class Angle {
public void DrawAngle() {
Console.WriteLine(\"这是Angle里面的DrawAngle方法\"); } }
class AdapterAngle : IDrawing {
private Angle ag = new Angle(); public override void Draw() {
ag.DrawAngle(); } }
class Program {
static void Main(string[] args) {
IDrawing cc = new Circle(); cc.Draw();
IDrawing rr = new Rectangle(); rr.Draw();
IDrawing ll = new Line(); ll.Draw();
IDrawing aa = new AdapterAngle(); aa.Draw();
Console.ReadKey(); } } }
运行结果:
实验小结:
适配器模式可以让任何两个没有关联的类一起运行,提高了类的复用,增加了类的透明度 ,灵活性好,但是过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这
种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。由于JAVA至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
实验六 桥接模式的应用
1 实验目的
1) 掌握桥接模式(Bridge)的特点
2) 分析具体问题,使用桥接模式进行设计。
2 实验内容和要求
一个咖啡店可以提供大杯(JorumCoffee)、中杯(MediumCoffee)、小杯(SmallCoffee)的咖啡(Coffee),为了满足不同用户的口味,在咖啡中可以添加牛奶(Milk),或者糖(Sugar),或者柠檬(Lemon),提供给用户不同口味的组合,如大杯咖啡加牛奶,中杯咖啡加糖,小杯咖啡加柠檬,小杯咖啡加糖等。应用桥接模式,用C#控制台应用程序实现该设计。绘制该模式的UML图。 UML图:
源代码:
abstract class Sauce {
public abstract void Mixing(); }
class Milk : Sauce {
public override void Mixing() {
Console.WriteLine(\"加牛奶\"); } }
class Sugar : Sauce {
public override void Mixing() {
Console.WriteLine(\"加糖\"); } }
class Lemon : Sauce {
public override void Mixing() {
Console.WriteLine(\"加柠檬\"); } }
abstract class Coffee {
protected Sauce sauce;
public void AddSauce(Sauce sauce) {
this.sauce = sauce; }
public abstract void Mixing(); }
class JorumCoffee : Coffee {
public override void Mixing() {
Console.Write(\"大杯咖啡\"); sauce.Mixing(); } }
class MediumCoffee : Coffee {
public override void Mixing() {
Console.Write(\"中杯咖啡\");
sauce.Mixing(); } }
class SmallCoffee : Coffee {
public override void Mixing() {
Console.Write(\"小杯咖啡\"); sauce.Mixing(); } }
class Program {
static void Main(string[] args) {
//中杯咖啡加牛奶
Coffee coffeeOne = new MediumCoffee(); coffeeOne.AddSauce(new Milk()); coffeeOne.Mixing();
//大杯咖啡加糖
Coffee coffeeTwo = new JorumCoffee(); coffeeTwo.AddSauce(new Sugar()); coffeeTwo.Mixing();
//小杯咖啡加糖
Coffee coffeeThree = new SmallCoffee(); coffeeThree.AddSauce(new Lemon()); coffeeThree.Mixing();
Console.ReadKey(); } } }
运行结果:
实验小结:
Bridge模式是一个非常有用的模式,也非常复杂,它很好的符合了开放-封闭原则和优先
使用对象,而不是继承这两个面向对象原则。该模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
实验七 装饰模式的应用
1 实验目的
1) 掌握装饰模式(Decorator)的特点 2) 分析具体问题,使用装饰模式进行设计。
2 实验内容和要求
“喜羊羊逃命”游戏:喜羊羊被灰太狼追,喜羊羊最多5条命,灰太狼每咬到喜羊羊一次,喜羊羊就要少一条命。在逃的过程中喜羊羊可以吃到三种苹果,吃“红苹果”可以给喜羊羊加上保护罩,吃“绿苹果”可以加快喜羊羊奔跑速度,吃“黄苹果”可以使喜羊羊趟着水跑。应用装饰模式,用C#控制台应用程序实现该设计。绘制该模式的UML图。 UML图:
源代码:
abstract class State {
public abstract void Show(); }
class Animal : State
{
private string name; public Animal(string name) {
this.name = name; }
public override void Show() {
Console.WriteLine(\"的{0}\", name); } }
abstract class Apple:State {
protected State component;
public void Decorator(State component) {
this.component = component; }
public override void Show() {
if (component != null) {
component.Show(); } } }
class ProtectiveCover : Apple {
public override void Show() {
//base.Show();
Console.Write(\"有保护罩\"); base.Show(); } }
class RunFast : Apple {
public override void Show() {
//base.Show();
Console.Write(\"跑得快、\"); base.Show(); } }
class FlowingWater : Apple {
public override void Show() {
//base.Show();
Console.Write(\"会趟水、\"); base.Show(); } }
class Program {
static void Main(string[] args) {
Animal pleasantsheep = new Animal(\"喜羊羊\"); ProtectiveCover pc = new ProtectiveCover(); RunFast rf = new RunFast();
FlowingWater fw = new FlowingWater(); pc.Decorator(pleasantsheep); rf.Decorator(pc); fw.Decorator(rf);
fw.Show();
Console.ReadKey(); } } }
运行结果:
实验小结:
Decorator模式采用对象组合而非继承的手法,实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。同时它很好地符合面向对象设计原则中“优先使用对象组合而非继承”和“开放-封闭”原则。
实验八 外观模式的应用
1 实验目的
1) 掌握外观模式(Facade)的特点
2) 分析具体问题,使用外观模式进行设计。
2 实验内容和要求
一个保安系统的,由录像机、电灯、红外线监控和警报器组成。保安系统的操作人员需要经常将这些仪器启动和关闭。保安类需要用到所有的录像机(Camera)、电灯(Light)、感应器(Sensor)和警报器(Alarm)对象,保安觉得使用不方便。应用外观模式,用C#控制台应用程序改进该设计。绘制该模式的UML图。 UML图:
源代码:
public class Camera {
public void TurnOn() {
Console.WriteLine(\"Turning on the camera.\");
}
public void TurnOff() {
Console.WriteLine(\"Turning off the camera.\"); }
public void Rotate(int degrees) {
Console.WriteLine(\"Rotating the camera by {0} degrees.\", degrees); } }
public class Light {
public void TurnOff() {
Console.WriteLine(\"Turning on the light.\"); }
public void TurnOn() {
Console.WriteLine(\"Turning off the light.\"); }
public void ChangeBulb() {
Console.WriteLine(\"changing the light-bulb.\"); } }
public class Sensor {
public void Activate() {
Console.WriteLine(\"Activating the sensor.\"); }
public void Deactivate() {
Console.WriteLine(\"Deactivating the sensor.\"); }
public void Trigger() {
Console.WriteLine(\"The sensor has triggered.\"); } }
public class Alarm {
public void Activate() {
Console.WriteLine(\"Activating the alarm.\"); }
public void Deactivate() {
Console.WriteLine(\"Deactivating the alarm.\"); }
public void Ring() {
Console.WriteLine(\"Ringing the alarm.\"); }
public void StopRing() {
Console.WriteLine(\"Stop the alarm.\"); } }
public class SecurityFacade {
private static Camera camera1, camera2; private static Light light1, light2, light3; private static Sensor sensor; private static Alarm alarm; static SecurityFacade() {
camera1 = new Camera(); camera2 = new Camera(); light1 = new Light(); light2 = new Light(); light3 = new Light(); sensor = new Sensor(); alarm = new Alarm(); }
public void Activate() {
camera1.TurnOn(); camera2.TurnOn(); light1.TurnOn(); light2.TurnOn(); light3.TurnOn(); sensor.Activate(); alarm.Activate(); }
public void Deactivate() {
camera1.TurnOff();
camera2.TurnOff(); light1.TurnOff(); light2.TurnOff(); light3.TurnOff(); sensor.Deactivate(); alarm.Deactivate(); } }
class Program {
static void Main(string[] args) {
SecurityFacade security;__ security = new SecurityFacade();_ security.Activate();_
Console.WriteLine(\"\\n--------------------\\n\");_ security.Deactivate(); Console.ReadKey(); } } }
运行结果:
实验小结:
Façade模式注重的是简化接口,它更多的时候是从架构的层次去看整个系统,而并非单个类的层次。该模式对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的。松耦合关系使得子系统的组件变化不会影响到它的客户。
实验九 观察者模式的应用
1 实验目的
1) 掌握外观模式(Observer)的特点 2) 分析具体问题,使用外观模式进行设计。
2 实验内容和要求
网上商店中如果商品(product)在名称(name)、价格(price)等方面有变化,系统能自动通知会员,将是网上商店区别传统商店的一大特色。如何设计实现? 说明你所选择的设计模式,画出类关系图并指明各个类的角色。应用外观模式,用C#控制台应用程序改进该设计。绘制该模式的UML图。 UML图:
源代码:
public class Product {
public string name; public string price;
public Product(string s_name,string s_price) {
name = s_name; price = s_price; }
public Product() {
name = null; price = null; } }
class ShopSystem {
private IList products = pro; } private string action; public void Attach(MemberObserver observer) { observers.Add(observer); } public void Detach(MemberObserver observer) { observers.Remove(observer); } public void Notify() { foreach (MemberObserver mo in observers) mo.Update(); } public string ProductAction { get { action = null; foreach (Product p in products) { if (p.name != null || p.price != null) { action += p.name + \"的价格变成了\" + p.price+\"\\n\"; } } return action; } set { action = value; } } } class MemberObserver { private string name; private ShopSystem sub; public MemberObserver(string name, ShopSystem sub) { this.name = name; this.sub = sub; } public void Update() { Console.WriteLine(\"{0} 请注意!{1} \", sub.ProductAction, name); } } class Program { static void Main(string[] args) { Product productOne = new Product(); Product productTwo = new Product(\"衬衫\",\"125元/件\"); Product productThree = new Product(\"短袖\", \"60元/件\"); IList ShopSystem shopsystem = new ShopSystem(products); MemberObserver member1 = new MemberObserver(\"会员1\", shopsystem); MemberObserver member2 = new MemberObserver(\"会员2\", shopsystem); shopsystem.Attach(member1); shopsystem.Attach(member2); shopsystem.Notify(); Console.ReadKey(); } } } 运行结果: 实验小结: 通过Observer模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放-封闭原则。当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在的对象中以使它们可以各自地改变和复用。当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。 实验十 策略模式的应用 1 实验目的 1) 掌握策略模式(Strategy)的特点 2) 分析具体问题,使用策略模式进行设计。 2 实验内容和要求 在图书销售时,根据不同类型的图书有不同的折扣,计算金额时必须区别对待,例如计算机类图书7折,英语类图书6折。应用策略模式,用C#控制台应用程序实现该设计。绘制该模式的UML图。 UML图: 源代码: public interface DiscountStrategy { void discountInformation(); } public class ComputerBookDiscount : DiscountStrategy { public void discountInformation() { Console.WriteLine(\"计算机类图书打7折!\"); } } public class EnglishBookDiscount : DiscountStrategy { public void discountInformation() { Console.WriteLine(\"英语类图书打6折!\"); } } class BookSale { private DiscountStrategy strategy; public BookSale(DiscountStrategy strategy) { this.strategy = strategy; } public void discountInformation() { this.strategy.discountInformation(); } } class Program { static void Main(string[] args) { BookSale bs; bs = new BookSale(new ComputerBookDiscount()); bs.discountInformation(); bs = new BookSale(new EnglishBookDiscount()); bs.discountInformation(); Console.Read(); } } } 运行结果: 实验小结: 通过这次实验我了解到了策略模式的优点:策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。当客户端必须知道所有的策略类,并自行决定使用哪个策略类的时候可以选用工厂模式进行处理。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 99spj.com 版权所有 湘ICP备2022005869号-5
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务