C#实现设计模式学习1——创建型模式

面向对象

面向对象的好处:可维护,可复用,可扩展
三大特性:封装,继承和多态。
封装:把业务和界面分离。
继承和多态:降低程序的耦合(保护原先的程序,只需要对一部分进行修改,而不需要对全部进行修改。)
1.开放-封闭原则:软件实体(类,模块,函数等等)可以扩展,但是不可以修改。
2.单一原则:就一个类而言,应该仅有一个引起它变化的原因(每个类实现单一的功能)。
3.依赖倒转原则:针对接口或抽象类编程,不要针对实现编程(细节应该依赖于抽象)
4.里氏代换原则:子类必须能够能够替换掉它们的父类型,这样使得父类类型在无需修改的情况下就可以扩展。

设计模式分为3大类
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式;
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式;
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、访问者模式,中介者模式、解释器模式。

单例模式,只能创建一个对象

确保一个类只有一个实例,并提供一个访问本类实例唯一的全局访问点。单例模式的使用是当我们的系统中某个对象只需要一个实例的情况。

        public class Singleton//单例模式
        {
            // 定义一个静态变量来保存类的实例
            private static Singleton uniqueInstance;
            //定义一个标识确保线程同步
            private static readonly object locker = new object();
            // 定义私有构造函数,使外界不能创建该类实例
            private Singleton()
            {    }
            
            public static Singleton GetInstance()
            {
                 // 当第一个线程运行到这里时,此时会对locker对象 "加锁",
                // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁
                 // lock语句运行完之后(即线程运行完之后)会对该对象"解锁"
                 // 双重锁定只需要一句判断就可以了
                if (uniqueInstance == null)
                {
                    lock(locker)
                    {
                         // 如果类的实例不存在则创建,否则直接返回
                           if (uniqueInstance == null)
                           {
                                uniqueInstance = new Singleton();
                           }
                    }                   
                }
                return uniqueInstance;
            }
        }

为什么会有2个uniqueInstance?
当instance为null,并且同时有2个线程调用GetInstance()方法时,它们都将通过instance==null的判断。然后由于lock机制,这两个线程则只有一个进入,另一个在外面等待,必须要其中的一个进入并出来后,另一个才能进入。而此时如果没有第二重的instance是否为null的判断,则第一个线程创建了实例,而第二个线程还是可以继续再创建新的实例,这就没有达到单例的目的。

———————————————————————————————————————————

简单工厂模式,一个对象的创建

一个简单的工厂模式分别用到了封装,继承和多态,使程序容易维护,容易扩展,容易复用,提高灵活性。
使用封装将业务逻辑和界面逻辑分开;使用继承和多态降低耦合
在简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。缺点是违背了“开放-封闭”原则。

public abstract class MobilePhone1
    {
        public abstract void print();
    }
    public class Iphone1:MobilePhone1
    {
        public override void print()
        {
            Console.WriteLine("我是苹果手机");
        }
    }
    public class XiaoMi1:MobilePhone1
    {
        public override void print()
        {
            Console.WriteLine("我是小米手机");
        }
    }
    public class MobilePhoneFactory1
    {
        public static MobilePhone1 CreateMobilePhone(string phonebrand)
        {
            MobilePhone1 mobilePhone = null;
            switch(phonebrand)
            {
                case"苹果":
                    mobilePhone = new Iphone1();break;
                case"小米":
                    mobilePhone = new XiaoMi1();break;
                default:
                    break;

            }
            return mobilePhone;
        }
    }
public class Operation
    {
        private double _numberA = 0;
        private double _numberB = 0;
        public double NumberA
        {
            get;
            set;
        }
        public double NumberB
        {
            get;
            set;
        }
        public virtual double GetResult()
        {
            double result = 0;
            return result;
        }
    }
    class OperationAdd:Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA + NumberB;
            return result;
        }
    }
    class OperationSub : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = NumberA - NumberB;
            return result;
        }
    }
    //简单工厂模式,到底实例化谁,将来会不会增加实例化的对象
    public class OperationFactory
    {
        public static Operation createOperate(string operate)
        {
            Operation oper = null;
            switch(operate)
            {
                case "+":
                    oper = new OperationAdd();
                    break;
                case "-":
                    oper = new OperationSub();
                    break;
            }
            return oper;
        }
    }
    static void Main(string[] args)
    {
        Operation oper;
        oper = OperationFactory.createOperate("+");
        oper.NumberA = 1;
        oper.NumberB = 2;
        double result = oper.GetResult();
        Console.WriteLine(result);
    }

在这里插入图片描述

工厂方法模式(Factory Method)

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延续到祺子类中。
参考:C#设计模式–工厂方法模式
工厂方法模式克服了简单工厂违背开放-封闭原则(软件实体应该可以扩展,但是不可以修改)的缺点,又保持了封装对象创建过程的优点。但缺点是每加一个产品,就需要加一个产品工厂的类,增加额外的开发。

 public abstract class MobilePhone
    {
        public abstract void print();
    }
    public class Iphone:MobilePhone
    {
        public override void print()
        {
            Console.WriteLine("我是苹果手机!");
        }
    }
    public class XiaoMi:MobilePhone
    {
        public override void print()
        {
            Console.WriteLine("我是小米手机");
        }
    }

    public abstract class MobilePhoneFactory
    {
        public abstract MobilePhone Create();
    }

    public class IphoneFactory: MobilePhoneFactory
    {
        public override MobilePhone Create()
        {
            return new Iphone();
        }
    }
    public class XiaoMiFactory : MobilePhoneFactory
    {
        public override MobilePhone Create()
        {
            return new XiaoMi();
        }
    }

工厂方法克服了简单工厂违背开发-封闭原则的缺点,又保持了封装对象创建过程的优点。
工厂方法模式是简单工厂的扩展,工厂方法把简单工厂的内部逻辑判断转移到了客户端进行,想要增加功能,以前是修改工厂类,现在是修改客户端。

依旧以计算器的例子为例,将在上面简单工厂的基础上进行修改

interface IFactory
    {
        Operation CreateOperation();
    }
class AddFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new OperationAdd();
        }
    }
class DivFactory
    {
        public Operation CreateOperation()
        {
            return new OperationDiv();
        }
    }

客户端代码

IFactory operFactory = new AddFactory();//工厂方法模式
Operation oper = operFactory.CreateOperation();
oper.NumberA = 4;
oper.NumberB = 2;
double result = oper.GetResult();
Console.WriteLine(result);
Console.Read();

在这里插入图片描述

————————————————————————————————————————

抽象工厂模式(Abstract Factory),一组对象的创建

工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在实际的应用中,一个工厂不止会创建单一的产品,而是一系列的产品,这就引入了抽象工厂的概念。解决涉及多个产品系列的问题。
参考博客C#设计模式–抽象工厂模式,看一下UML

//抽象工厂类:提供创建不同品牌的手机屏幕和手机主板
    public abstract class AbstractFactory
    {
        //工厂生产屏幕
        public abstract Screen CreateScreen();
        //工厂生产主板
        public abstract MotherBoard CreateMotherBoard();
    }
    //屏幕抽象类:提供每一品牌的屏幕的继承
    public abstract class Screen
    {
        public abstract void print();
    }
    /// 主板抽象类:提供每一品牌的主板的继承
    /// </summary>
    public abstract class MotherBoard
    {
        public abstract void print();
    }
    /// 苹果手机屏幕   
    public class AppleScreen : Screen
    {
        public override void print()
        {
            Console.WriteLine("苹果手机屏幕!");
        }
    }
    /// 苹果手机主板   
    public class AppleMotherBoard : MotherBoard
    {
        public override void print()
        {
            Console.WriteLine("苹果手机主板!");
        }
    }
    /// 小米手机屏幕   
    public class XiaoMiScreen : Screen
    {
        public override void print()
        {
            Console.WriteLine("小米手机屏幕!");
        }
    }
    /// 小米手机主板类   
    public class XiaoMiMotherBoard : MotherBoard
    {
        public override void print()
        {
            Console.WriteLine("小米手机主板!");
        }
    }
    /// 苹果手机工厂   
    public class AppleFactory : AbstractFactory
    {
       
        /// 生产苹果手机屏幕           
        public override Screen CreateScreen()
        {
            return new AppleScreen();
        }       
        /// 生产苹果手机主板            
        public override MotherBoard CreateMotherBoard()
        {
            return new AppleMotherBoard();
        }
    }

建造者模式(Builder)

将一个复杂对象的构建与它的表示分开,使得同样的构建过程可以创建不同的表示。如果我们用了建造者模式,那么用户就只需要指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。(过程是稳定的,但是具体的细节是不同的)

建造者模式中一个很重要的类,指挥者(Director),用它来控制建造过程,也用它来隔离用户和建造过程的关联

 abstract class PersonBuilder
    {
        //把过程稳定住
        protected Graphics g;
        protected Pen p;
        public  PersonBuilder(Graphics g,Pen p)
        {
            this.g = g;
            this.p = p;
        }
        public abstract void BuildHead();
        public abstract void BuildBody();
        public abstract void BuildArmLeft();
        public abstract void BuildArmRight();
        public abstract void BuildLegLeft();
        public abstract void BuildLegRight();
    }
class PersonThinBuilder:PersonBuilder
    {
    //具体的细节
        public PersonThinBuilder(Graphics g,Pen p) : base(g, p)//base用于在派生类中访问重写的基类成员,Base 是子类中引用父类
        {

        }
        public override void BuildHead()
        {
            g.DrawEllipse(p, 50, 20, 30, 30);
        }
        public override void BuildBody()
        {
            g.DrawRectangle(p, 60, 50, 10, 50);
        }
        public override void BuildArmLeft()
        {
            g.DrawLine(p, 60, 50, 40, 100);
        }
        public override void BuildArmRight()
        {
            g.DrawLine(p, 70, 50, 90, 100);
        }
        public override void BuildLegLeft()
        {
            g.DrawLine(p, 60, 100, 45, 150);
        }
        public override void BuildLegRight()
        {
            g.DrawLine(p, 70, 100, 85, 150);
        }
    }
 class PersonDirector
    {
        private PersonBuilder pb;
        public PersonDirector(PersonBuilder pb)//用户告诉指挥者需要什么样的小人
        {
            this.pb = pb;
        }
        public void CreatePerson()
        {
            pb.BuildHead();
            pb.BuildBody();
            pb.BuildArmLeft();
            pb.BuildArmRight();
            pb.BuildLegLeft();
            pb.BuildLegRight();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值