对象是什么?
概念层:对象是某种拥有责任的抽象
规格层:对象是一系列可以被其他对象使用的公共接口
语言层:对象封装了代码和数据
从设计原则到设计模式
1.针对接口编程,而不是针对实现编程
2.优先使用对象组合而不是类继承
3.封装变化点
4.使用重构得到模式,迭代。不要把设计模式当成技巧。
类继承相当于白箱继承,破坏了面向对象的封装性,耦合度高。对象组合则要求被组合的对象
具有良好定义的接口,耦合度低。
封装变化点:使层与层之间的松耦合。
几条更具体的设计原则:
1.单一职责原则
2.开放封闭原则(对扩展开放,对更改封闭),不要更改,尽量扩展入手
3.替换原则:子类必须能够替换它们的基类
4.依赖倒置:高层模块不应该依赖于底层模块,二者都应该依赖于抽象,抽象不应该依赖于实现细
节,实现细节应该依赖于抽象
5.接口隔离原则
深刻理解面向对象是学好设计模式的基础,掌握一定的面向对象设计原则才能把握面向对象设计模式的
精髓,从而才能实现灵活运用设计模式。
Design Patterns
模式分类:
创建型模式Creational:对象的创建
结构型模式Structural:处理类与对象间的组合
行为型模式Behavioral:类与对象交互的职责分配
创建型模式:Singleton
如何绕过常规的实例构造器,保证一个类仅有一个实例,并提供该实例的全局访问点
单线程模式的几个要点:
1.Singleton模式中实例构造器可以设置为protected以允许子类派生
2.Singleton模式一般不要支持ICloneable接口
3.Singleton模式一般不要支持序列化
4.只考虑对象创建的管理,一般没有必要销毁进行特殊的管理,让垃圾回收机制来回收况且,Singleton模式只有一个实例。
5.该Singleton模式不用于多线程环境
多线程实现1.
class Singleton
{
private static volatile Singleton instance = null;
private static object lockHelper = new Object();
private Singleton(){}
public static Singleton Instance
{
get
{
if(instance == null)
{
lock (lockHelper)
{
if(instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
说明:
1.volatile是用于防止编译器做特殊修改,这样就可以保证一个严格的编译顺序
多线程实现2.
class Singleton
{
public static readonly Singleton Instance = new Singleton();
private Singleton();
}
扩展应用:
1.将一个实例扩展到n个实例----------对象池
.NET中的一些应用:
1.Type对象,每一种类实际上,.NET认为只有一个Type
2.HttpContext
设计模式参考书:
<<设计模式:可复用面向对象软件的基础>>GOF
<<面向对象分析与设计>> Grady Booch
<<敏捷软件开发:原则、模式与实践>>Robert C.Martin
<<重构:改善既有代码的设计>> Martin Fowler
<<Refactoring to Patterns>> Joshua Kerievsky
抽象工厂模式(解决new带来的问题)
new:实现依赖,不能应对"具体实例化类型"的变化
解决思路:封装变化点
Road road = new Road();
class RoadFactory
{
public static Road CreateRoad()
{
return new Road();
}
}
Road road = RoadFactory.CreateRoad();
动机:
一系列相互依赖的对象
往往存在更多系列对象
避免紧耦合
关键是寻找变化点,缺点,不能应对新对象。
Builder:生成器
设计模式强调变化,正是因为变化所以需要使用设计模式。如果没有变化,那么其实
不需要设计模式也可以把软件做的很好。
GOF:将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
public abstract class House{}
public abstract class Door{}
public abstract class Wall{}
public abstract class Windows{}
public abstract class Floor{}
public abstract class HouseCeiling{}
public abstract class Builder
{
public abstract void BuildDoor();
public abstract void BuildWall();
public abstract void BuildWindows();
public abstract void BuildFloor();
public abstract void BuildHouseCeiling();
public abstract House GetHouse();
}
//这部分是最稳定的
public class GameManager
{
public static House CreateHouse(Builder builder)
{
builder.BuilderDoor();
builder.BuilderDoor();
builder.BuilderWall();
builder.BuilderWall();
builder.BuilderWindows();
builder.BuilderWindows();
builder.BuilderFloor();
builder.BuilderHouseCeiling(); //天花板
}
}
public class RomainDoor:Door{}
public class RomainWall:Wall{}
public class RomainWindows:Windows{}
public class RomainFloor:Floor{}
public class RomainHouseCeiling:HouseCeiling{}
public class RomainHouse:House
{
}
public class RomainHouseBuilder:Builder
{
public override void BuildDoor();
public override void BuildWall();
public override void BuildWindows();
public override void BuildFloor();
public override void BuildHouseCeiling();
public override House GetHouse()
{
}
}
//App
public class App
{
public static void Main()
{
House house =
GameManager.CreateHouse(new RomainHouseBuilder());
}
}
原型模式Prototype
例子:
ProtoType.cs
public class GameSystem
{
public static void Run()
{
NormalActor nomalActor1 = new NormalActor();
NormalActor nomalActor2 = new NormalActor();
NormalActor nomalActor3 = new NormalActor();
NormalActor nomalActor4 = new NormalActor();
NormalActor nomalActor5 = new NormalActor();
FlyActor nomalActor = new FlyActor();
FlyActor nomalActor = new FlylActor();
WaterActor waterActor = new WaterActor();
WaterActor waterActor = new WaterActor();
}
}
//高层依赖于具体的类了(抽象依赖于实现细节了),如果需要增加一个新的角色,就不好办了。
AbstractFacoty 或 Factory模式也可以做,现在我们用原型模式来解决这个问题.
原型设计模式Clone方法可以利用.NET中的Object类的MemberwiseClone()方法或序列化来实现
深拷贝。一般如果一个类内部会发生大的变动,但是类的接口很稳定,那么可以运用原型模式,来
解决这一类问题。
创建型模式的讨论:
singleton解决的是对象个数带来的问题,Factory,Abstract Factory,Builder,Prototype解决的
是new带来的问题.
Factory,Abstract Factory,Builder
Factory:一般只创建一个对象
Abstract Factory:创建多个对象
Builder:算法骨架是稳定的,步骤容易变.
其实原型就是一个特殊的工厂类,来克隆易变对象,遇到易变类,起初的设计通常从
Factory开始,当遇到更多的复杂变化时,再考虑重构为其他三种工厂的模式。