创建型模式 工厂模式

172 阅读4分钟

这几天终于憋着完成了考试,所以终于有机会敲敲代码看看书,这几天再读*《大话设计模式》*这么本书。所以来写写读书笔记:)虽然到现在写的还是读书笔记哈哈哈。 要说到设计模式就首先得知道设计模式得六大原则:

  1. 单一职责原则:每一个类仅仅负责一个职责,不要存在对于一个导致类变更的原因。
  2. 里氏替换原则:基类可以透明的使用它的子类的对象。
  3. 依赖倒置原则:细节以来抽象。核心是面向接口的编程。
  4. 接口隔离原则:实现类应该依赖最小接口,避免实现不需要的方法。
  5. 迪米特法原则:一个对象应该尽量少的与其他类耦合。
  6. 开闭原则:对修改关闭,对扩展开放。 具体可以参阅这边文章设计模式六大原则。 而我今天首先记录的是工厂模式:
  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

###简单工厂模式 举个驴子**(以下代码仅是为了节省空间而放一起并非可以一个类名出现两个public修饰的类名)**:

public class MassageManager {
	
	private StudentMassagist mStudentMassagist;
	private NurseMassagist mNurseMassagist;
	
	//服务客人,创建对象
	public MassageManager(){
		System.out.println("Manager接待客人");
		mStudentMassagist = new StudentMassagist();
		mNurseMassagist = new NurseMassagist();
	}
	
	public void callStudent(String name){
		mStudentMassagist.setName(name);
		mStudentMassagist.serve();
	}
	public void callNurse(String name){
		mNurseMassagist.setName(name);
		mNurseMassagist.serve();
	}
	
}
public class StudentMassagist{
	private String name;
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void serve(){
		System.out.println(getName() + "按摩师正在服务");
	}
}
public class NurseMassagist{
	
	private String name;
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void serve(){
		System.out.println(getName() + "按摩师正在服务");
	}
}

如上,假如在一个月黑风高的夜晚,猫仔狗仔同你都未训,想去大保健,但是这里的经理比较忙意识需要来招待你而且还要创建服务人员这明显是不合理的,不符合我们之前说阐述的单一职责原则,甚至对于连最基本的继承都没有使用,因为不管是任何一个服务者,都有一个服务的方法,她们仅仅是名字作为区别。 那么按照之前的六大原则应该怎样呢?首先得使用面向对象编程语言的三大特性,继承、封装、多态。对于有相同方法的进行抽取,然后在创建一个类负责招待客人而我们的经理MassageManager仅仅使用创建服务者的功能充当我们的工厂。首先看看我们的UML类图

简单工厂模式UML

代码如下:

public abstract class BaseMassagist {
	private String name;
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public abstract void serve();
}

public class MassageManager {
	
	public static StudentMassagist callStudentMassagist(){
		return new StudentMassagist();
		
	}
	public static NurseMassagist callNurseMassagist(){
		return new NurseMassagist();
	}
	
}
public class StudentMassagist extends BaseMassagist{
	
	@Override
	public void serve() {
		// TODO Auto-generated method stub
		System.out.println(getName() + "按摩师正在服务");
	}

}
public class NurseMassagist extends BaseMassagist{

	@Override
	public void serve() {
		// TODO Auto-generated method stub
		System.out.println(getName() + "正在服务");
	}
}```
**那么问题来了**
该按摩店是特色按摩店,有很多种cosplay的服务者,但是如果我增加一个就需要修改以下我的工厂类,这明显有违**开闭原则**,如何是好?
###工厂方法模式
上面的问题我们可以使用**工厂方法模式**来解决,假如我们每次招进一个新的**Massagist**的时候我们可以再请一个**MassagistManager**这就不违反**开闭原则**,因为manager都仅仅是负责创建服务者的。那么我们再来看看UML类图:

![工厂方法模式UML](http://upload-images.jianshu.io/upload_images/2605454-0f42a1e12a97beb4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
代码如下:
**Manager工厂类**

public interface BaseMassageManager {

BaseMassagist callMassagist();

} public class StudentMassageManager implements BaseMassageManager{

@Override
public BaseMassagist callMassagist() {
	// TODO Auto-generated method stub
	return new StudentMassagist();
}

} public class NurseMassageManager implements BaseMassageManager{

@Override
public BaseMassagist callMassagist() {
	// TODO Auto-generated method stub
	return new NurseMassagist();
}

} public class UniformManager implements BaseMassageManager{

@Override
public BaseMassagist callMassagist() {
	// TODO Auto-generated method stub
	return new UniformMassagist();
}

}``` 服务者类

public abstract class BaseMassagist {

	
	private String name;
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public abstract void serve();
}

public class StudentMassagist extends BaseMassagist{
	
	@Override
	public void serve() {
		// TODO Auto-generated method stub
		System.out.println(getName() + "按摩师正在服务");
	}

}
public class NurseMassagist extends BaseMassagist{

	@Override
	public void serve() {
		// TODO Auto-generated method stub
		System.out.println(getName() + "正在服务");
	}
}

public class UniformMassagist  extends BaseMassagist{

	@Override
	public void serve() {
		// TODO Auto-generated method stub
		System.out.println(getName() + "正在服务");
	}
	
}```
这时候就完美的解决了新的职业类型加入时违反开闭原则修改工厂类的问题,nice~
**那么问题又来了**
虽然使用**工厂方法模式**帮助我们避免了修改类的问题,但是我们这店肯定不仅有按摩师和管理按摩师的manager的啊,那咱们的管理层还有各种各样的manager呢?还有其他方面服务的人员呢?
###抽象工厂模式
上面这个问题涉及了两个产品系列(产品族)的问题,假如我们这里引入的是属于管理层的CleanManager和属于服务者的清洁Auntie。我们用工厂方法就会再新增接口及其实现类,不明智。所以我们选择使用**抽象工厂模式**,首先看看UML结构图:
![抽象模式UML](http://upload-images.jianshu.io/upload_images/2605454-65fe0a078913de2f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
代码如下: