简单工厂、工厂、抽象工厂设计模式
一、简单工厂
简单工厂结构图
class Product{
public:
virtual void Do();
};
class ProducA :public Product{
public:
void Do(){
ocut<<"class ProductA"<<endl;
}
};
class ProductB:public Product{
public:;
void DO(){
cout<<"class ProductB"<<endl;
}
}
class Factory{
private:
Product *product;
public:
Factory(int n){
switch(n){
case 1:product=new ProductA();
case 2:product=new ProductB();
case 3:product=new ProductC();
}
}
void send(){
prduct->Do();
}
~Factory(){
delete product;
}
};
//client
Factory *f=new Factory(2);
二、工厂模式
interface IFactory{
Operation CreateOperation();
}
class FactoryA:IFactory{
public Operation CreatOperation(){
return new OperationA();
}
}
class FactoryB:IFactory{
public Operation CreatOperation(){
return new OperationB();
}
}
class FactoryC:IFactory{
public Operation CreatOperation(){
return new OperationC();
}
}
//client
IFactory operFactory=new FactoryA();//a工厂
三、抽象工厂
抽象工厂 提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类。
抽象工厂角色:担任这个角色的是工厂方法模式的核心它是与应用系统商业逻辑无关。
具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统商业逻辑紧密相关的
抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或他们共同拥有的接口
具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体的产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
// Abstract Factory pattern -- Structural example
using System;
// "AbstractFactory"
abstract class AbstractFactory
{
// Methods
abstract public AbstractProductA CreateProductA();
abstract public AbstractProductB CreateProductB();
}
// "ConcreteFactory1"
class ConcreteFactory1 : AbstractFactory
{
// Methods
override public AbstractProductA CreateProductA()
{
return new ProductA1();
}
override public AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
// "ConcreteFactory2"
class ConcreteFactory2 : AbstractFactory
{
// Methods
override public AbstractProductA CreateProductA()
{
return new ProductA2();
}
override public AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
// "AbstractProductA"
abstract class AbstractProductA
{
}
// "AbstractProductB"
abstract class AbstractProductB
{
// Methods
abstract public void Interact( AbstractProductA a );
}
// "ProductA1"
class ProductA1 : AbstractProductA
{
}
// "ProductB1"
class ProductB1 : AbstractProductB
{
// Methods
override public void Interact( AbstractProductA a )
{
Console.WriteLine( this + " interacts with " + a );
}
}
// "ProductA2"
class ProductA2 : AbstractProductA
{
}
// "ProductB2"
class ProductB2 : AbstractProductB
{
// Methods
override public void Interact( AbstractProductA a )
{
Console.WriteLine( this + " interacts with " + a );
}
}
// "Client" - the interaction environment of the products
class Environment
{
// Fields
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB;
// Constructors
public Environment( AbstractFactory factory )
{
AbstractProductB = factory.CreateProductB();
AbstractProductA = factory.CreateProductA();
}
// Methods
public void Run()
{
AbstractProductB.Interact( AbstractProductA );
}
}
/// <summary>
/// ClientApp test environment
/// </summary>
class ClientApp
{
public static void Main(string[] args)
{
AbstractFactory factory1 = new ConcreteFactory1();
Environment e1 = new Environment( factory1 );
e1.Run();
AbstractFactory factory2 = new ConcreteFactory2();
Environment e2 = new Environment( factory2 );
e2.Run();
}
}
抽象工厂的优点:易于减缓产品系列,由于具体工厂类,例如:IFactory factory=new AccessFactory();在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,他只需要改变具体工厂即可使用不同产品配置。将具体的创建过程和客户端分离,客户端通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。
缺点:增加表hi改变添加很多类,接口。非常麻烦。
四、单例模式
目的:保证一个类只能创建一个对象,并且提供一个访问它的全局访问点
实现:
1)构造函数私有化(i.类外不能创建对象 ii.构造函数私有的类不可被继承)
静态数据成员必须初始化,而且只能在类外初始化
静态数据成员不通过对象访问,如果是公有的可以直接在类外使用
2)为了使这个对象单一,不被其他人创建,我们完全可以直接就把这个类的构造方法改成私有的(private),你应该知道,所有类都有构造方法,不编码则系统默认生成空的构造方法,默认的构造方法就会失效,于是只要你将类中的构造方法用private修饰,外部程序就不能用new来实例化他了。
单例模式可以分为懒汉式和饿汉式
懒汉式单例模式:在类加载时不初始化。
饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
第一种(懒汉,线程不安全)
class Singleton{
private static Singleton instance;
private Singlenton (){ }
public Singlenton GetInstance(){
if(instance==null){
instance=new Singlenton();
}
return instance;
}
}
多线程时的单例;
多个线程同时访问该类时也有可能创建多个对象,为了避免多线程造成的不是单例的情况,我们对创建对象实例部分加锁,lock锁是确保当一个线程位于代码的临界区时,另外一个线程不进入临界区。如果其他线程试图进入锁定的代码,则他将一直等待(即被阻止),直到该对象被释放。
第二种(懒汉,线程安全)
class Singleton{
private static Singleton instance;
private Singlenton (){ }
public Singlenton GetInstance(){
synchronized(syncRoot){
if(instance==null){
instance=new Singlenton();
}
}
return instance;
}
}
第三种(饿汉)
class Singleton{
private static Singleton intance=new Singleton();
private Singlrton(){}
public Singleton getInstance(){
return intance;
}
}
第四种(饿汉,变种)
class Singleton{
private static Singleton instance=null;
static {
instance=new Singleton();
}
private Singleton(){}
private Singleton getInstance(){
return instance;
}
}
第五种(静态内部类)
class Singleton{
private static class sss{
private static final Singleton instance=new Singleton();
}
private Singleton(){}
public static final Singleton getInstance(){
return sss.instance;
}
}
第六种(枚举)
public enum Singleton{
instance;
public void whateverMethod(){
}
}
双重锁定
每次加锁只是当该对象没有被实例化时间加锁,一旦被实例化,锁也就没有用了
第七种(双重校验)
class Singleton{
private static Singleton instance;
private Singlenton (){ }
public Singlenton GetInstance(){
if(insatance==null){
synchronized(syncRoot){
if(instance==null){
instance=new Singlenton();
}
}
}
return instance;
}
}