文章场景取自日常工作中,先大概描述一下,小公司一般工作流程是,需求方需要改什么需求,增加什么功能,直接找到程序员进行更改

用代码表示这种场景就是

    class demand //需求方
{
//传统方式,需求方直接找程序员改功能
coder code;
public demand(coder code)
{
this.code = code;
}
public void GetCount()
{
code.GetCount();
}
public void GetDataInterface()
{
code.GetDataInterface();
}
}

class coder//程序员
{
public string Name { get; set; }
public void GetCount()
{
Console.WriteLine(
"帮忙统计一个数据的数量");
}
public void GetDataInterface()
{
Console.WriteLine(
"帮忙提供一个数据接口");
}
}

class Client
{
//直接调用
coder code= new coder ();
demand d
= new demand(code);
d.GetCount();
d.GetDataInterface();
}

  

如果我们的程序员不想需求方找到我们,经常打断我们的思路,那就可以考虑用代理模式了,在需求方和程序员之间设置产品,需求方找产品

产品找程序员,然后程序员修改或增加需求功能

先上图:

 需求方先找产品,产品找程序员,产品就相当于代理的角色了

大公司或者说公司有比较规范流程的公司一般都是采用代理模式完成项目的

   public   abstract class Abstactcoder
{
public abstract void GetCount();

public abstract void GetDataInterface();
}

class CoderA : Abstactcoder
{
public override void GetCount()
{
Console.WriteLine(
"代理方式取得数量");
}
public override void GetDataInterface()
{
Console.WriteLine(
"代理方式取得数据接口");
}
}

class Proxy : Abstactcoder
{
/*需求方不能直接找程序员或者UI,如果想找,人家也不理你,必须走产品部门,Proxy在这里的作用就相当于产品部门,
*需求方想改什么东东,必须先找产品部门,产品部门沟通好以后,再找程序员进行具体的工作
*这样避免了需求方直接找到程序员,程序员的工作需要集中精力,思路不能被打断,打断思路需要重启思路,这很糟糕,所以我们需要代理(产品部门)
*/
private Abstactcoder abstactcoder;
public Proxy()
{
abstactcoder
= new CoderA();
}
public override void GetCount()
{
abstactcoder.GetCount();
}
public override void GetDataInterface()
{
abstactcoder.GetDataInterface();
}
}

class Client
{
//代理方式调用程序员
Proxy proxya = new Proxy();
proxya.GetCount();
proxya.GetDataInterface();

Console.Read();
}

代理模式应用场景:
1.安全代理,在代理类里面加一些权限的判断和控制
2.远程代理,.net引用webservice,会生成一些代理文件
3.虚拟代理,提供一个占位符,但是没有直接显示图片,qq图片采用

最后总结一下,代理模式就是找一个人干活,但是并不直接找干活的人,找一个中间人,找干活的人并不关心中间人(代理)去怎么做,只是关心最后活干完就行了!

中间人负责接活,但是并不完成具体的工作任务,他会把找他干活人的任务分配给其他人去完成!

这样看来,代理是个美差,代理自己什么都没干!

posted @ 2011-08-18 14:39 艾伦 阅读(127) 评论(0) 编辑

外观模式(Facade Pattern)可以将一系列复杂的类包装成一个简单的封闭接口。也称门面模式.

Facade模式的意图是:为了子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用

先上图

可以看的出来,我们客户端调用子系统方法,并不是直接调用,而是中间有个高层次的统一接口Entity

client调用只是跟Entity这个类打交道,别的don't care

 class Client
{
//门面/外观模式 facade[fə'sɑ:d] 之C#
/* 应用场景
* 为子系统中的接口提供一个一致的调用方法,一般在项目的前期不用,后期解耦时候考虑用
* 开发阶段,会产生很多小的类,为了减少类之间的耦合,可以用facade模式定义一个统一的接口
* 在对老系统进行维护和升级的时候,可能要调用以前的方法,同时不对这些方法进行修改,可以考虑定义一个更高层次的接口,调用遗留的老方法, 新系统不直接调用原来的方法,而是通过访问这个更高层次的接口调用以前的方法
*/
static void Main(string[] args)
{
Entity entity
= new Entity();
entity.Activity();
entity.Rest();
Console.Read();
}
}
//吃喝
class Eat
{
public void Action()
{
Console.WriteLine(
"Eat ");
}
}
//玩乐
class Play
{
public void Action()
{
Console.WriteLine(
"Play");
}
}
//休息,睡觉
class Sleep
{
public void Rest()
{
Console.WriteLine(
"Sleep");
}
}
class Entity
{
Eat eat;
Play play;
Sleep sleep;
public Entity()//构造函数
{
eat
= new Eat();
play
= new Play();
sleep
= new Sleep();
}
public void Activity()//吃喝玩乐
{
eat.Action();
play.Action();
}
public void Rest()//休息
{
sleep.Rest();
}
}

 Abstract Factory模式可以与Facade模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。Abatract Factory模式也可以代替Facade模式隐藏那些与平台相关的类

 Abstract Factory模式可以与Facade模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。Abatract Factory模式也可以代替Facade模式隐藏那些与平台相关的类

Mediator模式与Facade模式的相似之处是,它抽象了一些已有的类的功能

posted @ 2011-08-15 12:48 艾伦 阅读(1189) 评论(2) 编辑

上一篇说的是简单工厂,工厂模式,抽象工厂

抽象工厂解决了我们切换的问题,但是如果要新增子类的时候,我们需要修改的地方就很多了

要新增一个类IProject,ProjectA,ProjectB,更改抽象工厂以及工厂的实现子类

没有一种方法是适用于所有情况的,也没有一种方法是万能的,不同的场景,我们要考虑不同的方法进行优化

在这里,我说的是用简单工厂模式优化抽象工厂,以应对新增的情况,先来简单工厂的图

好的,上代码

namespace AbstractFactoryOptimize
{
/*抽象工厂在切换产品的时候很方便,但是在新增功能的时候,就会要改动很多东西了
要新增一个类IProject,ProjectA,ProjectB,更改抽象工厂以及工厂的实现子类
这时候,我们单单用抽象工厂是不便于扩展的,考虑用简单工厂应对这种场景
*/
public abstract class Product
{
public abstract void work();
}
public class ProductA : Product
{
public override void work()
{
Console.Write(
"ProductA");
}
}
public class ProductB : Product
{
public override void work()
{
Console.Write(
"ProductB");
}
}
public abstract class Car
{
public abstract void Build();
}
public class CarA : Car
{
public override void Build()
{
Console.Write(
"Build CarA");
}
}
public class CarB : Car
{
public override void Build()
{
Console.Write(
"Build CarB");
}
}
//简单工厂代替抽象工厂
public class SimplyFactory
{
private static readonly string db = "A";
//工厂生产多个对象
public static Product newproduct()
{
Product product
= null;
switch (db)
{
case "A":
product
= new ProductA();
break;
case "B":
product
= new ProductB();
break;
default:
break;
}
return product;
}

public static Car newCar()
{
Car car
= null;
switch (db)
{
case "A":
car
= new CarA();
break;
case "B":
car
= new CarB();
break;
default:
break;
}
return car;
}
}

//简单工厂改造抽象工厂之客户端
public class AbstractFactoryClient
{
public static void GetFactoryMethod()
{
Product product
= SimplyFactory.newproduct();
product.work();

Car car
= SimplyFactory.newCar();
car.Build();

Console.Read();
}
}
}

改成这样之后,我们要进行切换,需要修改的是

  private static readonly string db = "A";

其他地方无需更改!

但是,我们还是需要修改代码,进行编译,然后才能生效,考虑用反射优化这种情况,上反射优化代码

namespace AbstractFactoryOptimize
{
/*抽象工厂在切换产品的时候很方便,但是在新增功能的时候,就会要改动很多东西了
要新增一个类IProject,ProjectA,ProjectB,更改抽象工厂以及工厂的实现子类
这时候,我们单单用抽象工厂是不便于扩展的,考虑用简单工厂应对这种场景
*/
public abstract class Product
{
public abstract void work();
}
public class ProductA : Product
{
public override void work()
{
Console.Write(
"ProductA");
}
}
public class ProductB : Product
{
public override void work()
{
Console.Write(
"ProductB");
}
}
public abstract class Car
{
public abstract void Build();
}
public class CarA : Car
{
public override void Build()
{
Console.Write(
"Build CarA");
}
}
public class CarB : Car
{
public override void Build()
{
Console.Write(
"Build CarB");
}
}

//用反射的写法优化抽象工厂,xml文件对应子类名称,有改动的时候修改xml文件就可以了,不需要修改程序并编译
public class Reflect
{
private static readonly string assambly = "AbstractFactoryOptimize";//程序集名称
private static readonly string db = ConfigurationManager.AppSettings["a"];

public static Product newproduct()
{
string name = assambly + "." + "Product" + db;//命名空间.类名
return (Product) Assembly.Load(assambly).CreateInstance(name);
}

public static Car newcar()
{
string name = assambly + "." + "Car" + db;
return (Car) Assembly.Load(assambly).CreateInstance(name);
}
}
public class reflextClient
{
Product product
= Reflect.newproduct();
product.work();

Car car
= Reflect.newcar();
car.Build();

Console.Read();
}
}

xml文件中配置节点

 <appSettings>
<add key ="a" value="B"/>

</appSettings>

这样的话,如果有什么变化,我们修改xml文章中的配置就可以了

这也会带来一个问题,就是反射的程序集如果要卸载,我们只能通过停止当前进程达到目的,用Appdomain(应用程序域)可以解决

posted @ 2011-08-11 13:00 艾伦 阅读(100) 评论(0) 编辑

前面介绍了策略和单例模式,这篇文章说一下简单工厂,工厂,抽象工厂的概念和应该场景

首先,从简单工厂开始:

见上图,可以看出来,最核心的部分就是工厂类了,所有的变化都封装在这个工厂类里面,Client不用关心类的实例化

但是,可谓成也工厂类,败也工厂类

如果,实例化的对应有所变化,就需要修改核心工厂类,违背了开放-封闭原则(对修改封闭,对扩展开放)

C#版本代码实现

SimplyFactory
   public abstract class  Simplyfactory
{
public abstract string CreateFactory();

}
public class SimplyA : Simplyfactory
{
public override string CreateFactory()
{
return "FactoryA";
}
}

public class SimplyB : Simplyfactory
{
public override string CreateFactory()
{
return "FactoryB";
}
}

class Factory
{
public static Simplyfactory Create(string Type)//核心工厂类负责所有对象的创建,属于创建型模式
{
Simplyfactory s
= null;
switch (Type)
{
case "A":
s
= new SimplyA();
break;
case "B":
s
= new SimplyB();
break;
default:
break;
}
return s;
}
}

class Client
{
static void GetSimplyFactory()
{
Simplyfactory simplyfactory
= Factory.Create("A");
Console.Write(simplyfactory.CreateFactory());
Console.Read();
}
}

输出结果:FactoryA

简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类

简单工厂模式解决的问题是如何去实例化一个合适的对象。

简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。

好的,下面介绍下工厂模式

先来图

 

 

定义一个创建对象的抽象类,有子类来决定具体实例化哪个类,使一个类的创建延迟到子类中

创建的对象Product不会变,但是对象的具体实现经常变换,如果发生变化,增加新的FacotoryMethods子类就可以了

满足对开放--封闭原则

 C#版本代码:

FactoryMethod
 public abstract class Product
{
public abstract void work();
}
public class ProductA : Product
{
public override void work()
{
Console.Write(
"ProductA");
}
}
public class ProductB : Product
{
public override void work()
{
Console.Write(
"ProductB");
}
}

public abstract class FactoryMethods
{
public abstract Product newproduct();
}
//对不同产品的实例化,由不同的工厂来具体实现,每一个工厂生产具体的商品
public class FactoryMethodA : FactoryMethods//具体工厂
{
public override Product newproduct()
{
return new ProductA();//实现具体的实例化
}
}
public class FactoryMethodB : FactoryMethods//具体工厂
{
public override Product newproduct()
{
return new ProductB();//实现具体的实例化
}
}

public class FactoryMethodClient
{
public static void GetFactoryMethod()
{
//产品种类是变化的,如果发生变化,新增一个工厂就可以了,在调用的地方掉用新的方法
//体现出对修改封闭,对扩展开放,新增新的功能对原来的没有影响
FactoryMethods factorysubA = new FactoryMethodA();
FactoryMethods factorysubB
= new FactoryMethodB();

Product pruductA
= factorysubA.newproduct();
Product pruductB
= factorysubB.newproduct();

pruductA.work();
pruductB.work();
}
}

可以看出来,工厂模式的工厂,实例化的对象只有一个,如果实例化的对象是多个,就成了抽象工厂模式,其实工厂模式和抽象工厂也就这点区别

先来看看抽象工厂的UML图

看到了吧,唯一的区别就是工厂创建了多个对象,当然,还是在工厂子类中创建的,这一点和工厂模式是一致的

C#版本代码

   

AbstractFactory
/*其实工厂和抽象工厂没有多大区别,只不过是抽象工厂生产的商品是多个而已
通俗的说,就是抽象工厂模式的具体工厂里面会有多个实例具体对象的方法
更直观的就是,抽象工厂模式每个工厂一次造多个玩意,而工厂模式的每个工厂只造一个玩意
*/
public abstract class Product
{
public abstract void work();
}
public class ProductA : Product
{
public override void work()
{
Console.Write(
"ProductA");
}
}
public class ProductB : Product
{
public override void work()
{
Console.Write(
"ProductB");
}
}
public abstract class Car
{
public abstract void Build();
}
public class CarA : Car
{
public override void Build()
{
Console.Write(
"Build CarA");
}
}
public class CarB : Car
{
public override void Build()
{
Console.Write(
"Build CarB");
}
}
public abstract class AbstractFactory
{
//工厂生产多个对象
public abstract Product newproduct();
public abstract Car newCar();
}
public class AbstractFactoryA : AbstractFactory
{
public override Product newproduct()
{
return new ProductA();//子类里面实现具体的实例化
}
public override Car newCar()
{
return new CarA();
}
}
public class AbstractFactoryB : AbstractFactory
{
public override Product newproduct()
{
return new ProductB();//子类里面实现具体的实例化
}
public override Car newCar()
{
return new CarB();
}
}

public class AbstractFactoryClient
{
public static void GetFactoryMethod()
{
AbstractFactory factorysubA
= new AbstractFactoryA();
AbstractFactory factorysubB
= new AbstractFactoryA();

Product pruductA
= factorysubA.newproduct();
Product pruductB
= factorysubB.newproduct();
Car factorycarA
= factorysubA.newCar();

factorycarA.Build();

pruductA.work();
pruductB.work();
}
}

应用场景:封装变化点。创建一系列相互依赖的对象。

好了,到这里就把简单工厂,工厂,抽象工厂都介绍完了,抽象工厂的问题是如果有创建对象变化的时候,还是要变化代码,重新生成,后面会介绍用反射解决这个问题

posted @ 2011-07-29 10:13 艾伦 阅读(836) 评论(1) 编辑

单例模式是为了确保一个类中只有一个实例被创建,并提供对该实例的全局访问指针

废话不说,上代码

    

Singleton
public sealed class Signton
{
public static Signton singn = null;
private static readonly object padlock = new object();
private Signton()
{

}
public static Signton Instance
{
get
{
if (singn == null)
{
/* lock关键字可以用来确保代码块完成运行,而不会被其他线程中断
这是通过在代码块运行期间为给定对象获取互斥锁来实现的, 这种方式的实现对于线程来说是安全的
这种情况下,对象实例由最先进入的那个线程创建,后来的线程在进入时(instence == null)为假
不会再去创建对象实例了。但是这种实现方式增加了额外的开销,损失了性能
*/
lock (padlock)
{
if (singn == null)
{
singn
= new Signton();
}
return singn;
}
}

else

{

return null;

}
}
}
}

 单例模式UML图:

单例模式的优点:

    1,实例控制:单例模式防止其它对象对自己的实例化,确保所有的对象都访问一个实例。

    2,伸缩性:因为由类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。


单例模式的缺点:

    1,系统开销。虽然这个系统开销看起来很小,但是每次引用这个类实例的时候都要进行实例是否存在的检查。这个问题可以通过静态实例来解决。

    2,开发混淆。当使用一个单例模式的对象的时候(特别是定义在类库中的),开发人员必须要记住不能使用new关键字来实例化对象。因为开发者看不到在类库中的源代码,所以当他们发现不能实例化一个类的时候会很惊讶。

    3,对象生命周期。单例模式没有提出对象的销毁。在提供内存管理的开发语言(比如,基于.NetFramework的语言)中,只有单例模式对象自己才能将对象实例销毁,因为只有它拥有对实例的引用。在各种开发语言中,比如C++,其它类可以销毁对象实例,但是这么做将导致单例类内部的指针指向不明。

posted @ 2011-07-27 14:18 艾伦 阅读(173) 评论(0) 编辑
摘要: 策略模式是目前我工作中比较常用的模式下面贴出搜集各种语言的版本,记得我当初刚开始的时候,只会C#,别的语言看不明白,不知道现在还有没有人有我当年的烦恼!所以在这里我提供c#,C++,java,php四种版本,本来想写python版本,可惜自己不太懂,怕弄错让大家笑话首先来个策略模式的大致讲解,定义一系列的算法,把他们一个个封装起来,并且使他们可相互替换,本模式使得算法可独立于使用它的客户而变化客户端知道要调用具体哪个算法,由客户端决定使用的算法,算法可以独立于客户端自由的变动如下图:C#版本策略模式:using System; using System.Collections.Generic;阅读全文
posted @ 2011-07-25 17:58 艾伦 阅读(117) 评论(0) 编辑
摘要: insert into Ecp_Chat_Message(CHATID,CONTENT,IMGURL,SENDUSERID,SENDTIME,RECEIVEUSERID,STATE,ISREAD)values(1,'asdfdf','aaaa','kehu4',to_date('2011-12-03 12:55:45.333333','yyyy-mm-dd hh24:mi:ss.ff'),'serviceid',1,0)报错如下:日期格式图片在转换整个输入字符串之前结束插入到秒的可以这样写,inse阅读全文
posted @ 2011-07-05 16:49 艾伦 阅读(177) 评论(0) 编辑
摘要: sql写法,F5运行select top 10 * from Ecp_Chat_AllotService oracle写法,F8运行select * from Ecp_Chat_AllotService where rownum<=10mysql写法 ,F9运行SELECT * FROM USER LIMIT 0,10后面补充自增设置,sql 设置属性oracle 系列mysql 未知阅读全文
posted @ 2011-07-05 13:38 艾伦 阅读(94) 评论(0) 编辑
摘要: 查找ecp_wbs_workorder_info中work_order_id在 ecp_wbs_workorder_deal_info表中的数据in 写法select * from ecp_wbs_workorder_info info where work_order_id in(select work_order_id from ecp_wbs_workorder_deal_info)exists写法select * from ecp_wbs_workorder_info where exists(select * from ecp_wbs_workorder_deal_info d w.阅读全文
posted @ 2011-07-04 12:38 艾伦 阅读(72) 评论(0) 编辑
摘要: 要求输出:1,2,3,5,8,13,21,34,55,89前面我已经写了,递归输出方法,见文章http://www.cnblogs.com/A-I/archive/2010/08/12/1798117.html#1892936在这里,给出数组代替的写法,输出结果相同int[] ilent = new int[11];for(int i=0;i<ilent.Length;i++){if(i==0||i==1){ilent[i]=1;}else{ilent[i]=ilent[i-1]+ilent[i-2];}Console.Write(ilent[i]+",");}Con阅读全文
posted @ 2011-07-03 09:05 艾伦 阅读(102) 评论(0) 编辑