miracle just wanna be better

创建型设计模式

2019-11-10
miracle

重要的设计原则

  1. 面向接口编程,不是面向实现.是优雅的,可扩展代码的第一步.
  2. 指责单一原则.每个类都应该只有一个单一的功能,并且该功能应该由这个类完全封装起来.
  3. 对修改关闭,对扩展开放.

简单工厂模式

public class FoodFactory {
	public static Food makeFood(String name){
		if(name.equals("noodle")){
			Food noodles=new LanZhouNoodle();
			return noodles;
		}else if(name.equals("chicken")){
			Food chicken=new HuangMenChinken();
			return chicken;
		}
	}
}

其中LanZhouNoodle和HuangMenChicken都继承自Food
一个工厂类里面有一个静态方法,根据不同的参数返回不同的派生自同一个父类(或实现自同一接口)的实例对象.
符合指责单一原则,只负责生产对象.

工厂模式

public interface FoodFactory {
	Food makeFood(String name);
}
public class ChineseFoodFactory implements FoodFactory{
	@Override
	public Food makeFood(String name){
		if(name.equals("A")){
			return new ChineseFoodA();
		}else if(name.equals("B")){}
		return new ChineseFoodB();
	}
}
public class AmericanFoodFactory implements FoodFactory{
	@Override
	public Food makeFood(String name){
		if(name.equals("A")){
			return new AmericanFoodA();
		}else if(name.equals("B")){}
		return new AmericanFoodB();
	}
}

其中ChineseFoodFactoryA,ChineseFoodFactoryB,AmericanFoodA,AmericanFoodB都派生自Food

使用时

public class App{
	public static void main(String[] args) {
		FoodFactory factory=new ChineseFoodFactory();
		factory.makeFood("A");
		FoodFactory factory=new AmericanFoodFactory();
		factory.makeFood("A");
	}
}

虽然都是调用makeFood(“A”) 但是不同工厂生产出来的对象不同.
先选取合适的工厂,然后通过该工厂来生产对象.

抽象工厂模式

当涉及到产品族的时候就需要抽象工厂模式
比如电脑是由很多零件组成,将cpu和主板进行抽象,然后cpu由cpuFactory生产,主板由MainBoardFactory生产,然后再将cpu和主板组合在一起.但是可能intel的cpu和AMD的主板不能兼容使用,所以就需要抽象工厂模式,直接定义电脑工厂,每个工厂负责生产cpu和主板所有的设备.

public interface ComputorFactory{
	public CPU makeCPU();
    public MainBoard makeMainBoard();
}

public class IntelFactory implements ComputorFactory{
	public CPU makeCPU(){
		return new IntelCPU();
	}
	public MainBoardFactory makeMainBoard(){
		return new IntelMainBoard();
	}
}

使用时

	ComputorFactory factory = new IntelFactory();
	factory.makeCPU();
	factory.makeMainboard();

单例模式

饿汉模式

public class Hsingleton {
	//将构造设为私有
	private Hsingleton(){};
	//创建私有静态实例,这个类第一次使用的时候就会进行创建
	private static Hsingleton instance =new Hsingleton();
	public static Hsingleton getInstance(){
		return instance;
	}
}

饱汉模式

public class Hsingleton {
	//将构造设为私有
	private Hsingleton(){};
	//创建私有静态实例,这个类第一次使用的时候就会进行创建,用volatile修饰
	private static volatile Hsingleton instance =null;
	public static Hsingleton getInstance(){
		if(instance==null){
			//加锁
			synchronized(Hsingleton.class){
				//必须判断,不然有并发错误
				if(instance==null){
					instance=new Hsingleton();
				}
			}
		}
		return instance;
	}
}

嵌套类

public class Singleton {
	private Singleton(){}
	//嵌套类可以使用外部类的静态属性和静态方法
	private static class Holder{
		private static Singleton instance=new Singleton();
	}
	public static Singleton getInstance(){
		return Holder.instance;
	}
}

建造者模式

public class Person {
	//姓名 -required(必写)
	private final String name;
	//性别-required(必写)
	private final String gender;
	//年龄
	private int age;
	//省份证号
	private String id;
	
	public static class newBuilder{
		//姓名 -required
		private String name;
		//性别-required
		private String gender;
		//年龄
		private int age;
		//省份证号
		private String id;
		
		public newBuilder setAge(int age){
			this.age = age;
			return this;
		}
		public newBuilder setId(String id){
			this.id = id;
			return this;
		}
		public newBuilder(String name,String gender){
			this.name = name;
			this.gender = gender;
		}
		public Person build(){
			return new Person(this);
		}
	}
	//外部类的私有构造函数
	private Person(newBuilder builder){
		this.name = builder.name;
		this.gender = builder.gender;
		this.age = age;
		this.id = id;
	}

}

创建对象时

Person p = new Person.newBuilder("miracle","male").setAge(18).build();
Person p = new Person.newBuilder("miracle","male").setAge(18).setId("1877551230").build();

思路

  • 我们用builder方式创建对象时,用到了静态的内部类,内部类可以访问外部类的所有属性和方法
  • 为外部类写一个私有的构造方法,就不能直接用外部类用new的方式来创建对象
  • 所以用外部类打点内部类的方式先new出内部类对象,通过设置内部类的构造方法限定必须要输入的属性值;然后用内部类调用build()方法,返回一个以子类作为参数的Person类类型,内部类就通过私有的外部类构造器创建了一个新的对象
  • 因为子类set方法的返回值都是子类的类类型,所以可以继续设置属性

优点

  • 成员变量可以是final类型,通过设置构造函数来要求必须输入
  • 对象状态连续,创建时就赋值,更加清晰

总结

  • 外部类构造函数私有,且参数为静态内部类,使用静态内部类的变量为构建类逐一赋值
  • 静态内部类拥有外部类相同的属性
  • 为每一个属性写一个setter方法,返回的是当前Builder对象
  • 最后提供一个方法build方法,new出来一个构建类的对象,参数是当前的Builder对象

上一篇 迭代器

Comments

Content