模式学习之创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 - Nicotine_SZZ
模式学习之创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
简单工厂模式
- public interface water { //先定义“概念”产品 这里是water
- public void say();
- }
- public class SickWater implements water{//产品的具体实现
- @Override
- public void say() {
- System.out.println("i am sick water!");
- }
- }
- public class CleanWater implements water {
- @Override
- public void say() {
- System.out.println("i am clean water!");
- }
- }
- public class WaterFactory {//制造产品的工厂
- public water waterProduce (String waterName){//根据输入的产品参数制造相应产品 方法前面用 water 这个“概念” 产品。
- switch (waterName){
- case "clean":
- return new CleanWater();
- case "sick":
- return new SickWater();
- default:
- System.out.println("请输出正确数值");
- return null;
- }
- }
- }
- public class Test {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- WaterFactory wf = new WaterFactory ();
- water clean = wf.waterProduce("clean");
- water sick = wf.waterProduce("sick");
- clean.say();
- sick.say();
- }
- }
- /*
- 输出:
- i am clean water!
- i am sick water!
- */
多个工厂模式
- public class WaterFactory {//简单的修改 将上面的需要输出参数制造产品的特点变成,手动选择产品,防止输入错误参数。个人感觉挺不错的。
- public water produceSickWater (){
- return new SickWater ();
- }
- public water produceCleanWater (){
- return new CleanWater ();
- }
- }
- public class Test {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- WaterFactory wf = new WaterFactory ();
- water clean = wf.produceCleanWater();//使用方法的稍微区分,输出一样。
- water sick = wf.produceSickWater();
- clean.say();
- sick.say();
- }
- }
静态工厂模式
- public class WaterFactory {
- public static water produceSickWater (){//也仅仅只是在制造产品前面静态化了,这样使用不需要实例化。
- return new SickWater ();
- }
- public static water produceCleanWater (){
- return new CleanWater ();
- }
- }
- public class Test {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- water clean =WaterFactory.produceCleanWater();//直接用工厂静态方法,很方便。 所以大多是第三种模式。
- water sick = WaterFactory.produceSickWater();
- clean.say();
- sick.say();
- }
- }
接着是抽象工厂类
- public interface water { //先定义“概念”产品 这里是water
- public void say();
- }
- public class SickWater implements water{//产品的具体实现
- @Override
- public void say() {
- System.out.println("i am sick water!");
- }
- }
- public class CleanWater implements water {
- @Override
- public void say() {
- System.out.println("i am clean water!");
- }
- }
- public interface AbstractFatory {//很重要!抽象工厂模式,个人认为抽象的体现就在这里,这里定义一个工厂该干的活,至于是什么工厂,后面具体实现。
- //这样就实现了增加新的产品,就是增加新的工厂,而不是对之前那个工厂类进行添加,做到闭包原则,虽然看起来很麻烦的样子。
- public water produce ();
- }
- public class SickWaterFactory implements AbstractFatory{//工厂的具体实现,只能增加不能修改
- @Override
- public water produce() {
- // TODO Auto-generated method stub
- return new SickWater();
- }
- }
- public class CleanWaterFactory implements AbstractFatory{
- @Override
- public water produce() {
- // TODO Auto-generated method stub
- return new CleanWater();
- }
- }
- public class Test {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- CleanWaterFactory cleanFactory = new CleanWaterFactory();
- SickWaterFactory sickFactory = new SickWaterFactory();
- water clean =cleanFactory.produce();
- water sick = sickFactory.produce();//很明显不方便的一点就是我需要多少产品就得知道多少工厂。
- clean.say();
- sick.say();
- }
- }
工厂模式和简单工厂模式,个人写的例子不是很好,给产品更多的参数,不是一个简单的say,实际运作也是以产品的各种参数值来定
具体可以看看 http://blog.csdn.net/jason0539/article/details/44976775 和 http://www.cnblogs.com/itTeacher/archive/2012/11/30/2796122.html
工厂模式的关键在于 抽象产品 具体产品 工厂 的实现 抽象工厂模式是 抽象产品 具体产品 抽象工厂 具体工厂 的实现
单例模式:当一个占用内存较大的类被频繁创建NEW,将占用极大内存。或者像中心系统一样,只允许存在一个,都需要单例模式。
- public class Hungry {
- private Hungry(){//私有化构造函数 不让new。
- }
- private static Hungry instance = new Hungry();//静态化实例
- public Hungry getInstance(){
- return instance;//获得单例实例化
- }
- //这个是饿汉模式 优点是简单 ,线程安全,缺点是一开始就创建,浪费内存。
- }
- public class Perfact {//较为理想的单例模式
- private Perfact() {
- }
- private static Perfact instance;//先不着急构造,利用 getINstance 进行构造,反正开始创建浪费内存。
- public static Perfact getInstance() {
- if (instance == null) {//不使用同步代码块 不是空的就直接返回一个instance
- synchronized (Perfact.class) {//保证线程安全
- if (instance == null) {
- instance = new Perfact();
- }
- }
- }
- return instance;
- }
- }
建造者模式
1.概念
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 [构建与表示分离,同构建不同表示]
与抽象工厂的区别:在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的建造过程。
建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心。
举个简单的例子,如汽车,有很多部件,车轮,方向盘,发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一部汽车,这个装配过程也很复杂(需要很好的组装技术), builder模式就是为了将部件和组装分开。
2.UML图
- public class Person {//个人是先从product 开始入手,头手脚是部件。
- private String foot;
- private String head;
- private String hand;
- public String getFoot() {
- return foot;
- }
- public void setFoot(String foot) {
- this.foot = foot;
- }
- public String getHead() {
- return head;
- }
- public void setHead(String head) {
- this.head = head;
- }
- public String getHand() {
- return hand;
- }
- public void setHand(String hand) {
- this.hand = hand;
- }
- }
- public interface PersonBuilder {// Builder 定义抽象接口一个Builder该做什么
- void buildHead();
- void buildHand();
- void buildFoot();
- Person buildPerson();
- }
- public class ManBuilder implements PersonBuilder {//该做什么的具体实现
- private Person person;
- public ManBuilder(){
- this.person= new Person();
- }
- @Override
- public void buildHead() {
- // TODO Auto-generated method stub
- person.setHead("man head.");
- }
- @Override
- public void buildHand() {
- // TODO Auto-generated method stub
- person.setHand("man hand");
- }
- @Override
- public void buildFoot() {
- // TODO Auto-generated method stub
- person.setFoot("man foot");
- }
- @Override
- public Person buildPerson() {
- // TODO Auto-generated method stub
- return person;
- }
- }
- public class WomenBuilder implements PersonBuilder {//具体实现women
- private Person person;
- public WomenBuilder(){
- this.person= new Person();
- }
- @Override
- public void buildHead() {
- // TODO Auto-generated method stub
- person.setHead("man head.");
- }
- @Override
- public void buildHand() {
- // TODO Auto-generated method stub
- person.setHand("man hand");
- }
- @Override
- public void buildFoot() {
- // TODO Auto-generated method stub
- person.setFoot("man foot");
- }
- @Override
- public Person buildPerson() {
- // TODO Auto-generated method stub
- return person;
- }
- }
- public class PersonDirect {//建造者模式中的“建造者”
- public Person construct (PersonBuilder pb){
- pb.buildHead();
- pb.buildHand();
- pb.buildFoot();
- return pb.buildPerson();
- }
- }
- public class Test2 {//测试类
- public static void main(String[] args) throws CloneNotSupportedException {
- // TODO Auto-generated method stub
- PersonDirect pc = new PersonDirect();
- Person man = pc.construct(new ManBuilder());
- }
- }
建造者模式将很多功能集成到一个类里,这个类可以创造出比较复杂的东西。所以与工厂模式的区别就是:工厂模式关注的是创建单个产品,而建造者模式则关注创建符合对象的多个部分。因此,是选择工厂模式还是建造者模式,依实际情况而定。摘录自 http://blog.csdn.net/zhangerqing/article/details/8194653 http://www.cnblogs.com/devinzhang/archive/2012/01/06/2314670.html http://blog.csdn.net/jason0539/article/details/44992733
原型模式,即深拷贝,在这里介绍另一种深拷贝的方法 是继承自Serializable 接口
- public class Teacher implements Serializable{//作为student的内对象,必须implements Serializable 不然student在序列化的时候会抛出错误。
- /**
- *
- */
- private String name;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- public class Student implements Serializable{
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- private Teacher teacher;
- private String name;
- public Teacher getTeacher() {
- return teacher;
- }
- public void setTeacher(Teacher teacher) {
- this.teacher = teacher;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Object deepClone() throws Exception
- {
- // 序列化
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(bos);
- oos.writeObject(this);
- // 反序列化
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- ObjectInputStream ois = new ObjectInputStream(bis);
- return ois.readObject();
- }
- }
- public class Test2 {
- public static void main(String[] args) throws Exception {
- // TODO Auto-generated method stub
- Teacher t = new Teacher();
- Student s = new Student ();
- s.setTeacher(t);//要设置,不然teacher都为null 下面会判断成true
- Student s2 = (Student) s.deepClone();
- System.out.print(s==s2);
- System.out.print(s.getTeacher()==s2.getTeacher());
- }
- }//输出两个false 深拷贝成功