分享几个简单的设计模式
一,单例模式
简介:单例模式,为提升效率或者符合逻辑,即保证一个类只能有一个实例,且提供一个全局唯一的访问点。
实现:单例模式的实现 可以分为单线程和多线程下:
单线程下的实现(伪代码):
public class single()
{
//定义一个静态变量 保存类的实例
private static single sle;
//构造函数 私有
private single()
{
}
//提供一个 实例的全局访问点
public static single GetSle()
{
if(sle==null)
{
sle=new single();
}
return sle;
}
}
多线程下(需要保证线程安全)的实现(伪代码):
public class single()
{
//定义一个静态变量 保存类的实例
//采用volatile关键字,保证这个变量不会被优化
private static volatile single sle;
定义一个锁
private lock1 =new lock();//伪代码
//构造函数 私有
private single()
{
}
//提供一个 实例的全局访问点
public static single GetSle()
{
if(sle==null)
{
//采用双重加锁机制,该方式 不需 每次线程访问这里时 都进行加锁,(已经创建好了之后)
lock(lock1)
{
if(slt=null)
{
sle=new single();
}
}
}
return sle;
}
}
优点:保证了所有访问 都是同一个实例。
二,工厂方法模式
简介:在简单工厂模式中,随着需求的不断增加,工厂内的方法需要不断进行修改,逻辑也会越来越复杂,而工厂方法模式 遵循 “开放封闭”原则,将类的实例化,延迟到子类,让子类确认实例化哪一个类。在面对 “剧烈变化的对象” 的创建工作,实现了一套比较稳定的接口。
组成角色:
①抽象工厂角色:定义工厂类的基本方法,任何具体工厂 需要继承它。
②具体工厂角色:实现抽象工厂方法(多态),创建具体的产品。
③抽象产品角色:定义产品类的基本方法,任何具体产品需要继承它。
④具体产品角色:实现抽象产品方法,与具体工厂类一一对应。
实现:
//抽象产品,水果
public abstract class Fruit
{
public abstract void eat();
}
//具体产品,苹果
public class apple :Fruit
{
public override void eat()
{
"吃苹果"
}
}
//具体产品,香蕉
public class banana :Fruit
{
public override void eat()
{
"吃香蕉"
}
}
//抽象工厂,工厂
public abstract class Factory
{
public abstract Fruit ProduceFru();
}
//具体工厂,生产苹果
public class appleFactray: Factory
{
public override Fruit ProduceFru()
{
return new apple();
}
}
//具体工厂,生成香蕉
public class bananaFactray: Factory
{
public override Fruit ProduceFru()
{
return new banana();
}
}
//使用
main()
{
Factory appFac=new appleFactray();
Factory banFac=new bananaFactray();
Fruit a= appFac. ProduceFru();
a.eat();
Fruit b=banFac . ProduceFru();
b.eat();
}
优点:新增产品时,只需要新增一个具体产品类和具体的工厂,无需修改原来的工厂,符合“对修改关闭,对扩展开放”原则。工厂方法模式解决的是 单个对象的需求变化
三,抽象工厂模式
简介:解决一系列 相互关联的对象的创建问题,且面对这一系列对象 需求的变化,如何设计 以应对这种变化,使得代码不会变的越来越臃肿,符合“开放封闭”原则。
组成部分:
①抽象工厂类,定义了一组相互依赖对象的创建, 有几种产品,就有几个创建接口。
②具体工厂类,实现抽象工厂类里面的抽象接口。
③抽象产品类,有几种产品,就有几个抽象基类,为每一个产品定义抽象接口。
④具体产品类,实现抽象产品类的接口。
实现:
Main()
{
//游戏类型的电脑
Factory gamFac = new gamingFactory();
gamFac.Producemonnitor().produce();
gamFac.Producehost().produce();
gamFac.Producemouse().produce();
gamFac.Producekeyboard().produce();
}
//抽象工厂类,包括创建一个电脑的接口
public abstract class Factory
{
public abstract monitor Producemonnitor();
public abstract host Producehost();
public abstract mouse Producemouse();
public abstract keyboard Producekeyboard();
}
//具体工厂类,实现不同类型的抽象工厂。
public class gamingFactory:Factory
{
public override monitor Producemonnitor()
{
return new gamingmonitor();
}
public override host Producehost()
{
return new gaminghost();
}
public override mouse Producemouse()
{
return new gamingmouse();
}
public override keyboard Producekeyboard()
{
return new gamingkeyboard();
}
}
public class officialFactory:Factory
{
public override monitor Producemonnitor()
{
return new officialmonitor();
}
public override host Producehost()
{
return new officialhost();
}
public override mouse Producemouse()
{
return new officialmouse();
}
public override keyboard Producekeyboard()
{
return new officialkeyboard();
}
}
//抽象产品类
public abstract class monitor
{
public abstract void produce();
}
public abstract class host
{
public abstract void produce();
}
public abstract class mouse
{
public abstract void produce();
}
public abstract class keyboard
{
public abstract void produce();
}
//具体产品类
//游戏类型的 gaming
public class gamingmonitor:monitor
{
public override void produce()
{
//"游戏类型的显示器"
}
}
public class gaminghost:host
{
public override void produce()
{
//"游戏类型的主机"
}
}
public class gamingmouse : mouse
{
public override void produce()
{
//"游戏类型的鼠标"
}
}
public class gamingkeyboard:keyboard
{
public override void produce()
{
//"游戏类型的键盘"
}
}
//办公类型的 official
public class officialmonitor:monitor
{
public override void produce()
{
//"办公类型的显示器"
}
}
public class officialhost:host
{
public override void produce()
{
//"办公类型的主机"
}
}
public class officialmouse : mouse
{
public override void produce()
{
//"办公类型的鼠标"
}
}
public class officialkeyboard:keyboard
{
public override void produce()
{
//"办公类型的键盘"
}
}
优点:抽象工厂解决的是 一系列对象 需求的变化,将对象的创建工作延迟到子类,客户端使用的是抽象基类,减少了客户端和具体产品间的依赖,降低了耦合度,有利于后期的维护和扩展。缺点是产品对象的需求变更。
四,建造者模式
简介:面对 产品对象内 某一部分需求的强烈变化(比如对象的组成内容,组成顺序),如何设计类和接口 使对象能够稳定创建。
组成部分:
①抽象建造者,为产品对象 每个组件 的 创建 指定抽象接口。规定这个复杂对象 要实现哪些部分的创建。
②具体建造者,实现抽象建造者的方法,提供一个可以检索此复杂对象的接口,构造一个具体建造者对象,在指导者的调用下创建复杂对象实例。
③指挥者,调用具体建造者,进行产品的创建。指挥者不涉及具体的产品信息,将自身隔离出来。保证产品各个组件的创建或者按顺序创建。
④产品角色,复杂对象,包括将组件组装成产品的接口,包含组件的内容定义。
实现:
//以不同品牌的电脑 为例(假设香蕉电脑和荔枝电脑是两种不同品牌的电脑),电脑有CPU,GPU,硬盘组成
//客户端操作
Main()
{
Director dirtor = new Director();
Builder ba = new BananaBuilder();
Builder lit = new LitchiBuilder();
dirtor.Construct(ba);
Computer baCom = ba.GetComputer();
baCom.Run();
}
//指挥者
public class Director
{
public void Construct(Builder builder)
{
//具体建造者 按顺序组装产品
builder.makeGPU();
builder.makeCPU();
builder.makeHarddisk();
}
}
//产品角色
//sealed修饰类,表示此类不能被继承,修饰函数,表示此函数不能被重写(此情况 必须搭配
//override)
public sealed class Computer
{
//组件类
private List<string> Components = new List<string>();
//组装接口
public void add(string component)
{
Components.Add(component);
}
public void Run()
{
foreach (string component in Components)
{
//打印,或者其他的操作
}
}
}
//抽象建造者
public abstract class Builder
{
//组装产品的接口
public abstract void makeGPU();
public abstract void makeCPU();
public abstract void makeHarddisk();
//检索产品的接口
public abstract Computer GetComputer();
}
//具体建造者,香蕉电脑
public sealed class BananaBuilder : Builder
{
Computer BananaComputer = new Computer();
public override void makeGPU()
{
BananaComputer.add("香蕉电脑的GPU");
}
public override void makeCPU()
{
BananaComputer.add("香蕉电脑的CPU");
}
public override void makeHarddisk()
{
BananaComputer.add("香蕉电脑的硬盘");
}
public override Computer GetComputer()
{
return BananaComputer;
}
}
//具体建造者,荔枝电脑
public sealed class LitchiBuilder : Builder
{
Computer LitchiComputer = new Computer();
public override void makeGPU()
{
LitchiComputer.add("荔枝电脑的GPU");
}
public override void makeCPU()
{
LitchiComputer.add("荔枝电脑的CPU");
}
public override void makeHarddisk()
{
LitchiComputer.add("荔枝电脑的硬盘");
}
public override Computer GetComputer()
{
return LitchiComputer;
}
}
优点:建造者模式解决的是 对象部分的需求变化,隐藏了产品的组装过程,有新产品需求时,只需要再实现一个具体的建造者。
五,原型模式
简介:当对象的创建 ,需要的数据较为复杂时,并且需要多个这样的实例时,如果采用工厂模式,随着产品种类的增多,系统会越来越复杂,由于实例类型相同(状态参数不同),可以采用克隆的方式创建。通过具体原型创建原型的种类,再通过克隆生成新的实例。
组成部分:
①抽象原型,声明类特性的抽象接口,和一个克隆的接口
②具体原型,实现抽象类的接口。
实现:
//咋们以奥特曼举例,迪迦奥特曼,和赛文奥特曼
//飞行 flying
//发射激光 emit_laser
//客户端操作
Main()
{
Prototype dijia = new DiJiaPro();
Prototype dijia2 = dijia.CloneObj();
Prototype dijia3 = dijia.CloneObj();
Prototype saiwen = new SaiWenPro();
Prototype saiwen2 = saiwen.CloneObj();
saiwen2.flying();
}
//抽象原型
public abstract class Prototype
{
//飞行
public abstract void flying();
//发射光波
public abstract void emitlaser();
public abstract Prototype CloneObj();
}
//具体原型,迪迦奥特曼
public sealed class DiJiaPro:Prototype
{
public override void flying()
{
//迪迦飞行
}
public override void emitlaser()
{
//迪迦发射光波
}
public override Prototype CloneObj()
{
return (DiJiaPro)this.MemberwiseClone();
}
}
//具体原型2,赛文奥特曼
public sealed class SaiWenPro:Prototype
{
public override void flying()
{
//赛文飞行
}
public override void emitlaser()
{
//赛文发射光波
}
public override Prototype CloneObj()
{
return (SaiWenPro)this.MemberwiseClone();
}
}
优点:隐藏了创建新实例的复杂性,简化了复杂对象的创建。
参考链接:https://www.cnblogs.com/mq0036/p/8288099.html
现在整理了几个创建 型的设计模式,后续有时间再更新几个 其他类别 的简单设计模式。