C# 设计模式·创建型模式
面试问到这个··答不出来就是没有架构能力···这里学习一下···面试的时候直接让我说出26种设计模式··当时就懵逼了··我记得好像之前看的时候是23种的 还有3个是啥的···
这里先列出几种创建型模式,工厂、抽象工厂、单例,建造者、原型,后续在更新
工厂模式:缺点是每增加一个类型就得增加一个工具类和对象工厂类(反射可以避免修改这个···)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection; namespace ExercisePrj.Dsignmode
{
public class ShapeFactory
{ public static IShape CtreateShape(string shape)
{
if (shape == "Line")
{
return new Line();
}
else if (shape == "Circle")
{
return new Circle();
}
return null; }
//反射的实现方式,规定一个统一的类命名方式,通过反射初始化
public static IShape CtreateWithReflection(string shape)
{
Assembly assembly = Assembly.GetExecutingAssembly();
var ishape = assembly.CreateInstance("ExercisePrj.Dsignmode."+shape);
return ishape as IShape;
}
}
public interface IShape
{
void Draw();
}
public class Line: IShape
{
public void Draw()//隐式封闭实现,子类可以隐藏不能重写,类调用会执行这个
{
Console.WriteLine("draw line");
}
void IShape.Draw()//显示实现,接口调用会执行这个
{
Console.WriteLine("IShape.DrawLine");
}
} public class Circle:IShape
{
public void Draw()
{
Console.WriteLine("draw Circle");
}
} }
抽象工厂模式,简单讲就是比上边更流弊的工厂模式···这里有用到上边的类型
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ExercisePrj.Dsignmode
{
//抽象工厂类
public abstract class AbstractFactory
{
public abstract IShape GetShape(string shape);
public abstract IColor GetColor(string color);
}
//工厂类子类
public class ShapeFactoryEx:AbstractFactory
{
public override IShape GetShape(string shape)
{
return ShapeFactory.CtreateShape(shape);//偷个懒
}
public override IColor GetColor(string color)
{ return null; }
}
public class ColorFactory : AbstractFactory
{
public override IShape GetShape(string shape)
{
return null;
}
public override IColor GetColor(string color)
{
if(color=="blue")
{
return new Blue();
}
else if (color=="red")
{
return new Red();
}
return null;
}
}
//工厂创造器
public class FactoryProducer
{
public static AbstractFactory getFactory( string SType)
{
if(SType=="shape")
{
return new ShapeFactoryEx();
}
else if(SType=="color")
{
return new ColorFactory();
}
return null;
}
}
public interface IColor
{
void Fill();
}
public class Blue:IColor
{
public void Fill()
{
Console.WriteLine("Blue");
}
}
public class Red : IColor
{
public void Fill()
{
Console.WriteLine("Red");
}
} }
单例模式:平时用的时候连锁都没加···上次面试的时候,人家问在多线程里边会出啥问题···当时就没反应过来·,说这有啥问题的·都是一个对象调方法就是··完事才想起来,如果初始化的函数在多线程里边就是线程不安全了··简直蒙蔽··这里列好几种写法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ExercisePrj.Dsignmode
{
public class Singleton
{
private Singleton() { }
//private static Singleton m_Singleton;
//private static readonly object lockvalue = new object();
//public static Singleton GetInstance()
//{
// //return m_Singleton ?? new Singleton();//不加锁 线程不安全
// if (m_Singleton == null)
// {
// lock (lockvalue)//枷锁//这里还可以加双锁,就是在里边判断是不是空
// {
// return new Singleton();
// } // }
// return m_Singleton;
//} public static readonly Singleton Instance = new Singleton();//据说这个是最流弊的写法··跟下边的写法是一个意思··
//public static readonly Singleton Instance=null
//static Singleton()
//{
// Instance = new Singleton();
//}
}
}
建造者模式,将一个复杂的构造与其表示分开,使用同样的构建创建不同的表示··感觉就是做了可变动的组合,然后用一个类去构造这个变动组合类,一边排列组型或者菜单之类的应用场景都适合
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ExercisePrj.Dsignmode
{
//构建类
public class MealBuilder
{
public Meal prepareVegMeal()
{
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
} public Meal prepareNonVegMeal()
{
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
//实体接口
public interface Item
{
string name { get;}
float price { get; }
IPacking packing();
}
//实体关联接口
public interface IPacking
{
string pack();
}
//不同实体
public class Wrapper:IPacking
{
public string pack()
{
return "Wrapper";
}
}
public class Bottle:IPacking
{
public string pack()
{
return "Bottle";
}
}
public abstract class Burger:Item
{
public IPacking packing()
{
return new Wrapper();
}
public abstract string name { get; }
public abstract float price { get; }
}
public abstract class ColdDrink:Item
{
public IPacking packing()
{
return new Bottle();
}
public abstract string name { get; }
public abstract float price { get; }
}
public class VegBurger:Burger
{
public override string name { get; }
public override float price { get; }
public VegBurger()
{
name = "Veg Burger";
price = 25.0f;
}
}
public class ChickenBurger: Burger
{
public override string name { get; }
public override float price { get; }
public ChickenBurger()
{
name = "Chicken Burger";
price = 50.0f;
}
} public class Coke : ColdDrink
{
public override string name { get; }
public override float price { get; }
public Coke()
{
name = "Coke";
price = 30.0f;
} }
public class Pepsi : ColdDrink
{
public override string name { get; }
public override float price { get; }
public Pepsi()
{
name = "Pepsi";
price = 35.0f;
} }
//不同的组合类
public class Meal
{
private List<Item> Items = new List<Item>();
public void addItem(Item item)
{
Items.Add(item);
}
public float getCost()
{
float cost = ;
foreach(var item in Items)
{
cost += item.price;
}
return cost;
}
public void ShowItems()
{
foreach(var item in Items)
{
Console.WriteLine("name={0},packing={1},price={2}", item.name, item.packing().pack(), item.price);
}
}
}
}
原型模式,就是克隆··是为了避免创建新对象,采用克隆的方式··,讲道理一般实现的克隆是直接new对象然后赋值,这也没法避免啊···,网上写的好多实现方式都是浅复制,这玩意浅复制能行么,如果对象里边的属性或者字段都是基元类型,这无所谓修改的时候就相当于直接指定新的引用对象·,如果不是·哪克隆出来的所有对象里边的引用类型都得单独new,不然可能都得指向一个对象了,·····python有deepcopy, C#好像没有这个····这里是在网上查的用序列化和反序列的方式实现深复制,这样不用new对象···得注意克隆方式
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks; namespace ExercisePrj.Dsignmode
{
//
public class ApplianceCach
{
private static Dictionary<string, Appliance> ApplianceMap = new Dictionary<string, Appliance>();
public static Appliance GetApplicance(string shapeId)
{
Appliance cachAppliance = ApplianceMap[shapeId];
return (Appliance)cachAppliance.Clone();
}
public static void loadCache()
{
Fridge fridge = new Fridge();
fridge.ID = "";
ApplianceMap.Add(fridge.ID, fridge); Television tv = new Television();
tv.ID = "";
ApplianceMap.Add(tv.ID, tv); }
}
[Serializable]
public abstract class Appliance:ICloneable
{
protected string type;
private string id;
public string Type { get { return type; } }
public string ID { get { return id; } set { id = value; } } public abstract void DoWork();
public object Clone()
{
object obj = null;
//将对象序列化成内存中的二进制流
BinaryFormatter inputFormatter = new BinaryFormatter();
MemoryStream inputStream;
using (inputStream = new MemoryStream())
{
inputFormatter.Serialize(inputStream, this);
}
//将二进制流反序列化为对象
using (MemoryStream outputStream = new MemoryStream(inputStream.ToArray()))
{
BinaryFormatter outputFormatter = new BinaryFormatter();
obj = outputFormatter.Deserialize(outputStream);
}
return obj; }
} public class Fridge :Appliance
{
public Fridge()
{
type = "Fridge";
}
public override void DoWork()
{
Console.WriteLine("do some fridge job");
} }
public class Television:Appliance
{
public Television()
{
type = "Television";
}
public override void DoWork()
{
Console.WriteLine("do some Television job");
}
}
}
C# 设计模式·创建型模式的更多相关文章
- java设计模式--创建型模式(一)
2016-04-24 10:10:34 创建型模式:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 注意:工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂 ...
- C#设计模式-创建型模式(转)
一.简单工厂模式 简单工厂模式Simple Factory,又称静态工厂方法模式.它是类的创建模式.是由一个工厂对象决定创建出哪一种产品类的实例,是不同的工厂方法模式的一个特殊实现. 优点: u 模式 ...
- 设计模式-创建型模式,python享元模式 、python单例模式(7)
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝 ...
- 设计模式----创建型模式之工厂模式(FactoryPattern)
工厂模式主要分为三种简单工厂模式.工厂方法模式.抽象工厂模式三种.顾名思义,工厂主要是生产产品,作为顾客或者商家,我们不考虑工厂内部是怎么一个流程,我们要的是最终产品.将该种思路放在我们面向对象开发实 ...
- 【C#设计模式——创建型模式】简单工场模式
进入码农行列也有一年半载了,仍然感觉自己混混沌沌,无所事事,无所作为,,,想想都下气,下气归下气,仍要奋起潜行,像愤怒的小鸟一边又一遍的冲向猪头也好,像蜗牛一样往前蹭也罢,总之要有蚂蚁啃骨头的精神!! ...
- 【C#设计模式——创建型模式】抽象工厂模式
抽象工厂模式比工厂模式具有更高层次的抽象性.当要返回一系列相关类中的某一个,而每个类都能根据需要返回不同的对象时,可以选择这种模式.直接进入示例. 示例描述:完成花园的规划,多种花园种类,每个里面多种 ...
- 【C#设计模式——创建型模式】工场方法模式
工场方法模式对简单工场模式进行了乔庙的扩展,不是用一个专门的类来决定实例化哪一个子类.相反,超类把这种决定延迟到每个子类.这种模式实际上没有决策点,就是没有直接选择一个子类实例化的决策. 看书上的例子 ...
- java设计模式--创建型模式--抽象工厂
什么是抽象工厂,再次学习. 抽象工厂 概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 1.一个系统要独立于它的产品的创建.组合和表示时. 2.一个系统要由多个产品系 ...
- 设计模式 -创建型模式 ,python工厂模式 抽象工厂模式(1)
工厂模式 import xml.etree.ElementTree as etree import json class JSONConnector: def __init__(self, filep ...
随机推荐
- jenkins+gitlab+robot framework 中遇到的坑
问题一:拉Git源代码时提示无权限 原来之前用的ssh密钥一直都是自己的用户生成的.其实在Jenkins系统使用的都是Jenkins这个系统帐号的. 解决方法: 切换到jenkins这个帐号下生成个新 ...
- ELK安装成windows服务
一.Elasticsearch安装成windows服务 我的es所在路径为:D:\ELK5.5.0\elasticsearch-5.5.0 Java 安装目录为:C:\Program Files\Ja ...
- (四)SSO之CAS框架单点登录,自定义验证登录方式
应需求的变化,在登录cas的时候,默认根据用户名和密码进行验证,如果加上用户名,密码和一个系统标识进行验证呢?该如何做呢? 我们知道cas默认的登录界面中,输入的用户名和密码,再配置一下deploye ...
- vue二级路由跳转后外部引入js失效问题解决方案
vue路由可以通过children嵌套,于是可以形成二级路由等等... 案例如下: routes: [ { path: '/', name: 'dy', component: dy, children ...
- Lucene7.4学习和简单使用
简述: 前面从新回顾学习了Solr,正好也借此机会顺便学习一下Lucene. 一.什么是Lucene? 全文检索的一个实现方式,也是非结构化数据查询的方法.应用场景:在数据量大,数据结构不固定的时候, ...
- 关于在JS中AJAX导致跨域问题的解决
在部署一个原声的前端项目的时候,请求该服务器后端接口时发现出现了CORS跨域的问题,但是服务端已经做了同源策略的兼容,常见问题,遂记录. 报错信息: XMLHttpRequest cannot loa ...
- FTP在docker容器中上传失败解决,改为被动模式
package com.mayocase.takeout.utils; import org.apache.commons.net.ftp.FTPClient; import org.apache.c ...
- JAVA编程思想第一章——对象导论
- scp 一次拷贝多个文件
用正则表达式去匹配即可, scp *.tar root@11.11.11.12:/root/ 拷贝当前目录下的所有tar类型的文件到服务器上
- android的计算器
今天我闲着无聊,便想仿照Iphone的计算器自己写一个出来玩玩,于是就开动脑经,来场头脑风暴了!我拿什么了写呢?wp?这是个不错的选择,但是我最近在研究安卓的开发(求各位MSP不要烧我,我买不起MAC ...