设计模式-构建型
构建型,嗯,就是为了更好的实例化。
SOLID设计原则
开闭原则:一个软件实体如类、模块和函数应该对修改封闭,对扩展开放。
单一职责原则:一个类只做一件事,一个类应该只有一个引起它修改的原因。(不懂)
里氏替换原则:子类应该可以完全替换父类。也就是说在使用继承时,只扩展新功能,而不要破坏父类原有的功能。
依赖倒置原则:细节应该依赖于抽象,抽象不应依赖于细节。把抽象层放在程序设计的高层,并保持稳定,程序的细节变化由低层的实现层来完成。
迪米特法则:又名「最少知道原则」,一个类不应知道自己操作的类的细节,换言之,只和朋友谈话,不和朋友的朋友谈话。
接口隔离原则:客户端不应依赖它不需要的接口。如果一个接口在实现时,部分方法由于冗余被客户端空实现,则应该将接口拆分,让实现类只需依赖自己需要的接口方法。
工厂模式
优点
简单工厂模式可以提高代码的复用,下面代码需要苹果种子以及Sunlight,在工厂中new可以提高代码复用,而调用方也无需知道怎么new一个苹果满足最少知道原则。
工厂方法模式可以避免一个工厂过于臃肿,将一个工厂拆分为多个工厂。优点如下
抽象工厂模式,满足依赖倒置原则,高出约束底层。
缺点
横向拓展方便了,但是纵向就麻烦了,如果接口增加方法,所有工厂都要修改
简单工厂模式
方法工厂模式
抽象工厂模式
单例模式
优点
避免对象重复创建,避免搞错对象(搞错操作实例)
一般情况
饿汉式
变量在声明时便初始化。
缺点:这东西从头到尾未必用得上,内存浪费
懒汉式(懒加载)
先声明一个空变量,需要用时才初始化。
缺点:线程不安全
上锁
public class Singleton
{
private Sington() { }
private static Singleton _Singleton = null;
private static object Singleton_Lock = new object(); //锁同步
public static Singleton CreateInstance()
{
lock (Singleton_Lock)
{
Console.WriteLine("路过");
if (_Singleton == null)
{
Console.WriteLine("被创建");
_Singleton = new Singleton();
}
}
return _Singleton;
}
}
缺点:我们上锁是为了多线程在对象还没创建的时候多次访问,这段时间可以说相当短,上面代码中,无论什么时期都会执行一次获得锁的操作,这就很浪费信息。所有需要一个判断,如果已经实例化了,就不需要获得锁了。
双IF
public class Singleton
{
private static Singleton _Singleton = null;
private static object Singleton_Lock = new object();
public static Singleton CreateInstance()
{
if (_Singleton == null) //双if +lock {
lock (Singleton_Lock)
{
Console.WriteLine("路过。");
if (_Singleton == null)
{
Console.WriteLine("被创建。");
_Singleton = new Singleton();
}
}
}
return _Singleton;
}
}
静态变量
public sealed class Singleton
{
private Singleton() { }
private static readonly Singleton singleInstance = new Singleton();
public static Singleton GetInstance
{
get
{
return singleInstance;
}
}
}
缺点:和懒汉式一样,不用就浪费空间
解决方案C#特有的惰性初始化:
public sealed class Singleton
{
private Singleton()
{}
private static readonly Lazy<Singleton> Instancelock =
new Lazy<Singleton>(() => new Singleton());
public static Singleton GetInstance
{
get
{
return Instancelock.Value;
}
}
}
建造者模式(迷糊)
链式编程原来是基于这货的呀。
优点:相当于写好了全部条件的构造函数,否则你要写n!+1个构造函数(n为参数数量),而且每个都有默认值。
JAVA的更好,静态内部类中属性非静态。
using System;
using System.Collections.Generic;
using System.Text;
namespace DesignMode
{
public class Computer
{
public static Builder Builder=new Builder();
public string Cpu { get; set; }
public bool CoreGraphics { get; set; }
public int MemoryBank { get; set; }
public Computer()
{
}
}
interface IBuilder
{
Builder AddCpu(String cpu);
Builder AddCoreGraphics();
Builder AddMemoryBank(int memoryBank);
Computer GetComputer();
}
public class Builder: IBuilder
{
Computer computer;
public string Cpu { get; set; }
public bool CoreGraphics { get; set; }
public int MemoryBank { get; set; }
public Builder()
{
computer = new Computer();
}
public Builder AddCoreGraphics()
{
computer.CoreGraphics = true;
return this;
}
public Builder AddCpu(String cpu)
{
computer.Cpu = cpu;
return this;
}
public Builder AddMemoryBank(int memoryBank)
{
computer.MemoryBank = memoryBank;
return this;
}
public Computer GetComputer()
{
return computer;
}
}
}
JAVA版
原型模式
说白了就是克隆
JAVA克隆实现Cloneable接口即可,但这是浅克隆,深克隆需修改Cloneable的实现。
C#类似。
反射克隆
//深拷贝
public static object DeepCopy(object obj)
{
Object targetDeepCopyobj;
Type targetType = obj.GetType();
//值类型
if (targetType.IsValueType)
{
targetDeepCopyobj = obj;
}
//引用类型
else
{
targetDeepCopyobj = System.Activator.CreateInstance(targetType);
MemberInfo[] memberCollection = obj.GetType().GetMembers();
foreach (MemberInfo member in memberCollection)
{
//拷贝字段
if (member.MemberType == MemberTypes.Field)
{
FieldInfo field = (FieldInfo)member;
object fieldValue = field.GetValue(obj);
if (fieldValue is ICloneable)
{
field.SetValue(targetDeepCopyobj, (fieldValue as ICloneable).Clone());
}
else if (field != null)
{
field.SetValue(targetDeepCopyobj, DeepCopy(fieldValue));
}
else
{
field.SetValue(targetDeepCopyobj,null);
}
} //拷贝属性
else if (member.MemberType == MemberTypes.Property)
{
PropertyInfo myProperty = (PropertyInfo)member;
MethodInfo info = myProperty.GetSetMethod(false);
if (info != null)
{
object propertyValue = myProperty.GetValue(obj, null);
if (propertyValue is IList)
{
var list = (IList)Activator.CreateInstance(propertyValue.GetType()); ;
Object value;
foreach (var item in propertyValue as IList)
{
value = DeepCopy(item);
list.Add(value);
}
myProperty.SetValue(targetDeepCopyobj, list, null);
}
else
{
if (propertyValue is ICloneable)
{
myProperty.SetValue(targetDeepCopyobj, (propertyValue as ICloneable).Clone(), null);
}
else if (propertyValue != null)
{
myProperty.SetValue(targetDeepCopyobj, DeepCopy(propertyValue), null);
}
else
{
myProperty.SetValue(targetDeepCopyobj,null);
}
}
}
}
}
}
return targetDeepCopyobj;
}
//浅拷贝
public static object Copy(object o)
{
Type t = o.GetType();
PropertyInfo[] properties = t.GetProperties();
Object p = t.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, o, null);
foreach (PropertyInfo pi in properties)
{
if (pi.CanWrite)
{
object value = pi.GetValue(o, null);
pi.SetValue(p, value, null);
}
}
return p;
}