工厂模式作为创建型的设计模式,主要是控制调用者对实例的创建,而抽象则是将依赖实现改变为依赖接口。
依赖,发现很多人不明白这个词的含义,简单说,就是实例对象后引用的类型,一个简单对象:User user = new User();
这时依赖是对象自己,如果User继承BaseUser并实现了IOperate接口,这时可依赖的对象有三个,除了自身之外,还有接口和父类。
在抽象工厂还是其它设计模式中,按设计模式Solid原则,要依赖的最好是接口而不是具体的实现!
这里的抽象工厂也是,即我们定义一个方法是最好先定义一个接口,来实现这个接口的方法。调用时就可以依赖这个接口来实现。
这样实现了相同接口的类可以依赖共同的引用,实现了对象的多样性。
看代码:
public interface ICarOperate { void GetCar(); } public abstract class Car { public static readonly Dictionarycars = new Dictionary (); } public class BMW : Car, ICarOperate { private static readonly BMW instance = new BMW(); public void GetCar() { WriteLine("BMW"); } public static ICarOperate GetInstance() { ICarOperate result = null; string key = string.Empty; try { key = string.Format("{0}", instance.GetType()); if (!cars.ContainsKey(key)) { cars.Add(key, instance); } result = cars[key]; } catch (Exception ex) { WriteLine("{0}", ex.Message); } return result; } } public class Benz : Car, ICarOperate { private static readonly Benz instance = new Benz(); public void GetCar() { WriteLine("Benz"); } public static ICarOperate GetInstance() { ICarOperate result = null; string key = string.Empty; key = string.Format("{0}", instance.GetType()); if (!cars.ContainsKey(key)) { cars.Add(key, instance); } result = cars[key]; return result; } } public class Test { public static void Run() { ICarOperate car = BMW.GetInstance(); car.GetCar(); car = Benz.GetInstance(); car.GetCar(); } }
在Test类中的Run方法里调用,相同的依赖,传入不同的实例后getCar出来的内容是不相同的。而且使用GetInstance方法来调用父类中的字典,在以后同样类型的子对象生成时永远只会保存一份实例,这样就可以极大节约内存的开销。当然这样做在多线程情况下,由于线程同步的安全要求,会比较慢,因为一个线程使用时,会处于锁定状态,其它线程无法访问。安全性是没问题,性能受了一点影响,毕竟有取舍。