设计模式粗浅理解之------简单工厂模式
什么是简单工厂模式
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
角色和职责
工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
抽象产品(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色
是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
优缺点
优点
工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。
缺点
由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利。
使用场景
工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。(以上参考百度百科)
代码实例
以下实例我希望模拟一个用户登录的功能,在很多的系统中都存在多种用户,可以具有不同的权限,假设我们在某系统中存在以下用户超级用户Super(S),管理员Admin(A),普通用户Normal(N),这三种用户在登录时系统要根据不同的的用户级别各自进行相应的操作。根据以上场景,我们如果用简单工厂模式可以采用如下方式实现:
第一步 创建所有用户类别的公共父类
1 public class User { 2 private string _userType { get; set; } 3 4 public string UserType 5 { 6 get { return _userType; } 7 set { _userType = value; } 8 } 9 10 public virtual void ShowUser() 11 { 12 } 13 }
该类定义了一个用户类别的属性,以及现实用户类别的虚方法,其子类必须要实现该方法。
第二步 创建具体的用户类
超级用户类:
1 class SuperUser : User { 2 public SuperUser() 3 { 4 base.UserType = "超级用户"; 5 } 6 public override void ShowUser() 7 { 8 Console.WriteLine(base.UserType + "已经登录"); 9 } 10 }
管理员类:
1 class SuperUser : User { 2 public SuperUser() 3 { 4 base.UserType = "管理员"; 5 } 6 public override void ShowUser() 7 { 8 Console.WriteLine(base.UserType + "已经登录"); 9 } 10 }
普通用户类:
1 class SuperUser : User { 2 public SuperUser() 3 { 4 base.UserType = "普通用户"; 5 } 6 public override void ShowUser() 7 { 8 Console.WriteLine(base.UserType + "已经登录"); 9 } 10 }
第三步 创建一个工厂类,根据传入的参数不同创建不同的对象
1 public class UserFactory { 2 public static User createUser(string userType) 3 { 4 User user = null; 5 switch (userType) 6 { 7 case "S": 8 user = new SuperUser(); 9 break; 10 case "A": 11 user = new AdminUser(); 12 break; 13 case "N": 14 user = new NormalUser(); 15 break; 16 default: 17 break; 18 } 19 return user; 20 } 21 }
做完以上工作我们就可以在程序中使用我们的类,程序不关心我们如何创建具体的用户类,只是明确的将需要实例化的类的参数传入工厂类,由工厂类负责调用相应的构造函数创建具体类,示例如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 User user = null; 6 user = UserFactory.createUser("S"); 7 user.ShowUser(); 8 user = UserFactory.createUser("A"); 9 user.ShowUser(); 10 user = UserFactory.createUser("N"); 11 user.ShowUser(); 12 Console.ReadKey(); 13 } 14 }
UserFactory类完全屏蔽了每个用户类的具体过程,其输出结果如下: