在了解了编程中面向对象的好处与及它的四个特点,由特点我们延伸出了它所遵循的几大原则。在这里,小编将会与大家更深入的挖掘设计模式中的具体的模式,让我们一起来探索吧~**
前言
今天要跟大家分享的是书中介绍的第一个设计模式,也是“工厂三姐妹之一”,因为它是第一个出生的,我就把它定义为老大了。 在这里小编只先分享老大简单工厂,老二老三在接下来的连载中将会出现,大家敬请期待。
接下来呢,就是分享简单工厂时间;当然在此之前小编也了解了关于“面向对象的三大特征”,即多态、继承、封装。
封装 | 每个对象都包含它能进行操作所需要的所有信息,即对象不必依赖其他独享来完成自己的操作;如在类中实现加一个按钮小狗旺财会叫并不会影响只玩的小猫旺财会叫的功能,因为通过按钮把他们各自的内部封装了起来。 |
---|---|
继承 | 在编程上,对象的继承代表了一种’is-a’的关系,如果两个对象A和B,可以描述为’B是A’,则表明B可以继承A。如猫和动物的关系。其中子类继承于父类是,有三个特点:1)子类拥有父类飞private的属性和功能;2)子类具有自己的属性和功能,即子类可以扩展父类没有的属性和功能 3)子类还可以以自己的方式实现父类的功能。这三个特点可用儿子向父亲学习京剧来作为例子。 |
多态 | 简单的来说,就是不同对象执行相同动作。举例:儿子代替父亲上台表演京剧 |
除了面向对象的三大特征之外,我认为集合、泛型、委托与事件也是特别重要的。
集合 | 就概念而言,是.NET Framework 提供了用于数据存储和检索的专用类,这些类统称集合。它与数组的比较中,数组的容量是固定的,而集合ArrayList可根据主要自己扩充,不受事先设置其大小的控制,可随意的添加、插入和移除某一范围,比数组更方便。但因为ArayList不管什么对象都接受,多以在实现时则会出现问题,这时要进行拆箱和装箱处理,其会耗费很大的资源和时间。为了解决这个问题引出泛型 |
---|---|
**泛型 | 它是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。使用其时,需要增加"using System.Collections.Generic;的命名空间。其用法关键就是在IListt和List后面加‘’ 这个T就是所需要指定的集合的数据或对象类型。泛型List避免了集合ArayList类型不安全问题和装箱拆箱问题,因为它在声明和实例化是都需要指定其内部项的数据或对象类型。泛型是集ArrayList集合和Array数组优点于一身的好东西,推荐使用此。 |
委托与事件 | 委托是对函数的封装,可以当作给方法的特征指定一个名词。而事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程。委托是一种引用方法的类型。事件就是在反生有意义的事情时,可以通过事件通知他们。委托对象可通过事件通知他们。委托对象用关键字delegate来声明,事件用event关键字来声明。举例:如当Cat的Shout方法触发时,Mouse就执行Run的方法。但猫不认识老鼠,怎么通知在Shout方法触发时,通知他它呢,这时就可用声明一个委托。事件发生时,就执行被委托的方法。** |
简单工厂模式
我的理解 | |
---|---|
1 | 具有逻辑判断的分支条件,尽量的降低了子类与客户端的耦合度。 |
2 | 不符合开放-封闭原则 |
3 | 实例化的对象的问题,用简单工厂来创建实例的过程。其方法是抽象出一个类,把要实现的功能都放在这个类中,之后再简单工厂里swicth判断语句里,直接实例化此类的对象,然后用里氏转换调用具体的类 |
下面有其他理解或补充的,欢迎在下方评论区中留下 。
代码如下:
//简单工厂
public class OperationFactory
{
public static Operation createOperate(string operate)
{
Operation oper = null;
switch (operate)
{
case "+":
oper = new OperationAdd(); //里氏转换
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}
//客户端
Operation oper;
oper = OperationFactory.createOperate("+");//调用简单工厂里面的运算类
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();//得出计算结果
说完老大简单工厂后,接下来让我们再一起来走进老二工厂方法的世界。
工厂方法模式
定义 | 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类 |
---|---|
与简单工厂相比 | 工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,整个工厂的功能只是扩展了的变化;克服了开放-封闭原则,并且又保持了封装对象创建过程的优点。但由于每增加一个类,就得增加一个工厂,所以会增加额外的开发量 |
我的理解 | 简单工厂是,每增加一个功能就得改动简单工厂分支逻辑判断,不符合开放-封闭原则;其是根据客户端的选择条件动态实例化相关的类,这里对客户端来说是,去除了具体产品的依赖。而工厂方法的客户端需要决定实例化哪一个工厂来实现运算类;其中它封装了对象的创建,使得更换对象时,不需要做大的改动就可实现。新增加功能的时候,只需要添加此功能相应的运算类和工厂类就可以了,然后在客户端中只需要做一个小小的实例化哪一个工厂的改动就可以了。通俗的说就是,先把执行相同功能的动作放在一个父类工厂作为接口,然后建立与之相关的类工厂,让其继承父类工厂。客户端想要实现什么功能,在实例化那里调用相关的类工厂就可以了。 |
举例如下,有关三位同学去敬老院学习雷锋做好事,去为老人们买米、扫地、洗衣的活动。
用简单工厂实现的代码如下
//简单工厂
class SimpleFactory
{
public static LeiFeng CreateLeiFeng(string type)
{
LeiFeng result = null;
switch (type )
{
case "学雷锋的大学生":
result = new Undergraduate();
break;
case "社区志愿者":
result = new Volunteer();
break;
}
return result;
}
}
//客户端代码
LeiFeng studentA = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
studentA.BuyRice();
LeiFeng studentB = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
studentB.Sweep();
LeiFeng studentC = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
studentC.Wash();
Console.ReadKey();
在这里用简单工厂的时凸显的特点就是在任何实例化的时候都要写出这个工厂的代码,这就造成了重复。
用工厂方法实现的代码如下
//雷锋工厂
interface IFactory
{
LeiFeng CreateLeiFeng();
}
//学雷锋的大学生工厂
class UndergraduateFactory : IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Undergraduate();
}
}
//社区志愿者工厂
class VolunteerFactory : IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Volunteer();
}
}
//客户端
IFactory factory = new VolunteerFactory(); //要想换成“社区志愿者”只需要修改此处就行;这也是它区别于简单工厂的特点之一,其中也保持了封装对象创建过程的优点
LeiFeng student = factory.CreateLeiFeng();
student.BuyRice();
student.Sweep();
student.Wash();
Console.Read();
说完了老大老二,让我们一起来揭开这神奇的面纱,关于老三的庐山真面目吧
未完待续···········