先做个简单的自我介绍,我在国内一家知名的公司从事对日外包工作,目前日语一级,一年编程经验。
一直想写一点东西,就针对初学者,探讨一下我对设计模式的学习过程中的感悟吧。这次要写的是简单工厂模式。
最开始学习设计模式的时候,对抽象类和接口这两个概念很是头疼。抽象类和接口类中,往往什么也不实现,只是定义一下方法。既然什么也不做,为什么还要用它们?在最开始自己写一些程序的时候,几乎是不用抽象类和接口。但随着学习的进一步深入,逐渐体会到了这两个东东的好处。下面就结合生活中的一些常见的事情,来和大家探讨一下简单工厂模式,在此过程中,来说说抽象类和接口的作用。
大家都很希望有自己的一套属于自己的房子,于是大家很努力的工作,终于挣到了能够买起一套房子的钱。当大家去看房子时,房地产开发商会拿出很多户型给大家看,让大家选择自己喜欢的设计户型。那么房地产商是如何设计房子呢?作为一个家,客厅,卧室,厨房,卫生间是必不可少的。不管是什么户型的房子,都必须满足这些条件,否则,开发出来的房子就不符合消费者的要求,就卖不出去。这里的“家”,指我们所居住的房子,具有所有户型房子的共同点。如果不满足这些条件,就不能称之为家。我们可以把这个家当作设计模式里面的抽象类来看待,房地产商告诉户型的设计人员,你们设计的房子,必须在满足这个框框(客厅,卧室,厨房,卫生间)的基础上来设计,在满足家的基础上,不同户型的房子,客厅该多大,厨房该多大,卧室该朝哪面,是你们该考虑的事情。但是,这个“家”可不能理解错了,不能按照自己的想法,在里面随便添东东。比如:如果在“家”的卧室里面规定了有两个窗户,那么按照所有的户型房子都必须符合“家”的范畴的规定,所有的户型房子的卧室就都得有两个窗户。但有些消费者就是不喜欢卧室有两个窗户,就喜欢一个窗户,怎么办?所以不能在“家”这个抽象的概念上,增加具体的东西,这样会限制要求满足它的具体事物的扩展性。
//家.
public abstract class Home {
//客厅.
public abstract void Parlor();
//卧室.
public abstract void Bedroom();
//厨房.
public abstract void Kitchen();
//卫生间.
public abstract void Toilet();
}
在满足“家”的基础上,不同户型的房子,根据不同的消费者,可以设计不同类型的客厅,卧室,厨房,卫生间等等。比如A型住宅,建造好后有一个简单的装修,B型和C型的住宅不需要装修。
//装修.
public interface Fitment {
//客厅装修.
public void ParlorFitment();
//卧室装修.
public void BedroomFitment();
//厨房装修.
public void KitchenFitment();
//卫生间装修.
public void ToiletFitment();
}
//A型住宅.
public class HouseA extends Home implements Fitment {
public void Parlor() {
System.out.println("This is parlor of House A.");
};
public void Bedroom() {
System.out.println("This is bedroom of House A.");
};
public void Kitchen() {
System.out.println("This is kitchen of House A.");
};
public void Toilet() {
System.out.println("This is toilet of House A.");
}; public void ParlorFitment() {
System.out.println("This is fitment of parlor.");
}
public void BedroomFitment() {
System.out.println("This is fitment of bedroom.");
}
public void KitchenFitment() {
System.out.println("This is fitment of kitchen.");
}
public void ToiletFitment() {
System.out.println("This is fitment of toilet.");
}
}上面的A型住宅也许能够说明这个继承和接口,继承,就是“is-a”的关系,而接口则是“has-a”的关系。正如上面的A型住宅,它是一个“家”,并且有装修。而下面的B型和C型住宅,它们都是“家”,但没有装修,一样不影响居住。//B型住宅.
public class HouseB extends Home {
public void Parlor() {
System.out.println("This is parlor of House B.");
};
public void Bedroom() {
System.out.println("This is bedroom of House B.");
};
public void Kitchen() {
System.out.println("This is kitchen of House B.");
};
public void Toilet() {
System.out.println("This is toilet of House B.");
};
}//C型住宅.
public class HouseC extends Home {
public void Parlor() {
System.out.println("This is parlor of House C.");
};
public void Bedroom() {
System.out.println("This is bedroom of House C.");
};
public void Kitchen() {
System.out.println("This is kitchen of House C.");
};
public void Toilet() {
System.out.println("This is toilet of House C.");
};
}但大家在选房子的时候,一般来说是不关心盖房子的过程的(用的是什么水泥,请的是哪个施工队等等),只关心房子的质量。当大家选择好自己喜欢的户型时,跟房地产商洽谈好有关事宜,最后签订买卖合同,合同写明:XXX购买XXX房地产开发商的House X型住宅一套。房地产商觉得这个户型选择的人很多,于是开始建造该户型的房子。//消费者A.
public class Buyer {
public static void main(String[] args) { //找到房地产商,并告诉他,我要A型的房子。
Landagent landagent = new Landagent();
HouseA houseA = (HouseA)landagent.BuildHouse("House A");
//房子盖好后,参观房内的卧室,客厅,厨房,卫生间。
houseA.Bedroom();
houseA.Kitchen();
houseA.Parlor();
houseA.Toilet();
//察看房子的装修。
houseA.BedroomFitment();
houseA.KitchenFitment();
houseA.ParlorFitment();
houseA.ToiletFitment(); }
}//消费者B.
public class BuyerB {
public static void main(String[] args) {
//找到房地产商,并告诉他,我要B型的房子。
Landagent landagent = new Landagent();
Home houseB = landagent.BuildHouse("House B"); //房子盖好后,参观房内的卧室,客厅,厨房,卫生间。
houseB.Bedroom();
houseB.Kitchen();
houseB.Parlor();
houseB.Toilet();
}
}//
public class BuyerC {
public static void main(String[] args) {
//找到房地产商,并告诉他,我要C型的房子。
Landagent landagent = new Landagent();
Home houseC = landagent.BuildHouse("House C"); //房子盖好后,参观房内的卧室,客厅,厨房,卫生间。
houseC.Bedroom();
houseC.Kitchen();
houseC.Parlor();
houseC.Toilet();
}
}//房地产开发商.
public class Landagent { //根据消费者的选择,建造不同的房子。
public Home BuildHouse(String houseKind) {
if (houseKind.equals("House A")) {
//建造A型房子。
return new HouseA();
} else if (houseKind.equals("House B")) {
//建造B型房子。
return new HouseB();
} else if (houseKind.equals("House C")) {
//建造C型房子。
return new HouseC();
} else {
return null;
}
}
}简单工厂模式的特点:
工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
但是,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。
一直想写一点东西,就针对初学者,探讨一下我对设计模式的学习过程中的感悟吧。这次要写的是简单工厂模式。
最开始学习设计模式的时候,对抽象类和接口这两个概念很是头疼。抽象类和接口类中,往往什么也不实现,只是定义一下方法。既然什么也不做,为什么还要用它们?在最开始自己写一些程序的时候,几乎是不用抽象类和接口。但随着学习的进一步深入,逐渐体会到了这两个东东的好处。下面就结合生活中的一些常见的事情,来和大家探讨一下简单工厂模式,在此过程中,来说说抽象类和接口的作用。
大家都很希望有自己的一套属于自己的房子,于是大家很努力的工作,终于挣到了能够买起一套房子的钱。当大家去看房子时,房地产开发商会拿出很多户型给大家看,让大家选择自己喜欢的设计户型。那么房地产商是如何设计房子呢?作为一个家,客厅,卧室,厨房,卫生间是必不可少的。不管是什么户型的房子,都必须满足这些条件,否则,开发出来的房子就不符合消费者的要求,就卖不出去。这里的“家”,指我们所居住的房子,具有所有户型房子的共同点。如果不满足这些条件,就不能称之为家。我们可以把这个家当作设计模式里面的抽象类来看待,房地产商告诉户型的设计人员,你们设计的房子,必须在满足这个框框(客厅,卧室,厨房,卫生间)的基础上来设计,在满足家的基础上,不同户型的房子,客厅该多大,厨房该多大,卧室该朝哪面,是你们该考虑的事情。但是,这个“家”可不能理解错了,不能按照自己的想法,在里面随便添东东。比如:如果在“家”的卧室里面规定了有两个窗户,那么按照所有的户型房子都必须符合“家”的范畴的规定,所有的户型房子的卧室就都得有两个窗户。但有些消费者就是不喜欢卧室有两个窗户,就喜欢一个窗户,怎么办?所以不能在“家”这个抽象的概念上,增加具体的东西,这样会限制要求满足它的具体事物的扩展性。
//家.
public abstract class Home {
//客厅.
public abstract void Parlor();
//卧室.
public abstract void Bedroom();
//厨房.
public abstract void Kitchen();
//卫生间.
public abstract void Toilet();
}
在满足“家”的基础上,不同户型的房子,根据不同的消费者,可以设计不同类型的客厅,卧室,厨房,卫生间等等。比如A型住宅,建造好后有一个简单的装修,B型和C型的住宅不需要装修。
//装修.
public interface Fitment {
//客厅装修.
public void ParlorFitment();
//卧室装修.
public void BedroomFitment();
//厨房装修.
public void KitchenFitment();
//卫生间装修.
public void ToiletFitment();
}
//A型住宅.
public class HouseA extends Home implements Fitment {
public void Parlor() {
System.out.println("This is parlor of House A.");
};
public void Bedroom() {
System.out.println("This is bedroom of House A.");
};
public void Kitchen() {
System.out.println("This is kitchen of House A.");
};
public void Toilet() {
System.out.println("This is toilet of House A.");
}; public void ParlorFitment() {
System.out.println("This is fitment of parlor.");
}
public void BedroomFitment() {
System.out.println("This is fitment of bedroom.");
}
public void KitchenFitment() {
System.out.println("This is fitment of kitchen.");
}
public void ToiletFitment() {
System.out.println("This is fitment of toilet.");
}
}上面的A型住宅也许能够说明这个继承和接口,继承,就是“is-a”的关系,而接口则是“has-a”的关系。正如上面的A型住宅,它是一个“家”,并且有装修。而下面的B型和C型住宅,它们都是“家”,但没有装修,一样不影响居住。//B型住宅.
public class HouseB extends Home {
public void Parlor() {
System.out.println("This is parlor of House B.");
};
public void Bedroom() {
System.out.println("This is bedroom of House B.");
};
public void Kitchen() {
System.out.println("This is kitchen of House B.");
};
public void Toilet() {
System.out.println("This is toilet of House B.");
};
}//C型住宅.
public class HouseC extends Home {
public void Parlor() {
System.out.println("This is parlor of House C.");
};
public void Bedroom() {
System.out.println("This is bedroom of House C.");
};
public void Kitchen() {
System.out.println("This is kitchen of House C.");
};
public void Toilet() {
System.out.println("This is toilet of House C.");
};
}但大家在选房子的时候,一般来说是不关心盖房子的过程的(用的是什么水泥,请的是哪个施工队等等),只关心房子的质量。当大家选择好自己喜欢的户型时,跟房地产商洽谈好有关事宜,最后签订买卖合同,合同写明:XXX购买XXX房地产开发商的House X型住宅一套。房地产商觉得这个户型选择的人很多,于是开始建造该户型的房子。//消费者A.
public class Buyer {
public static void main(String[] args) { //找到房地产商,并告诉他,我要A型的房子。
Landagent landagent = new Landagent();
HouseA houseA = (HouseA)landagent.BuildHouse("House A");
//房子盖好后,参观房内的卧室,客厅,厨房,卫生间。
houseA.Bedroom();
houseA.Kitchen();
houseA.Parlor();
houseA.Toilet();
//察看房子的装修。
houseA.BedroomFitment();
houseA.KitchenFitment();
houseA.ParlorFitment();
houseA.ToiletFitment(); }
}//消费者B.
public class BuyerB {
public static void main(String[] args) {
//找到房地产商,并告诉他,我要B型的房子。
Landagent landagent = new Landagent();
Home houseB = landagent.BuildHouse("House B"); //房子盖好后,参观房内的卧室,客厅,厨房,卫生间。
houseB.Bedroom();
houseB.Kitchen();
houseB.Parlor();
houseB.Toilet();
}
}//
public class BuyerC {
public static void main(String[] args) {
//找到房地产商,并告诉他,我要C型的房子。
Landagent landagent = new Landagent();
Home houseC = landagent.BuildHouse("House C"); //房子盖好后,参观房内的卧室,客厅,厨房,卫生间。
houseC.Bedroom();
houseC.Kitchen();
houseC.Parlor();
houseC.Toilet();
}
}//房地产开发商.
public class Landagent { //根据消费者的选择,建造不同的房子。
public Home BuildHouse(String houseKind) {
if (houseKind.equals("House A")) {
//建造A型房子。
return new HouseA();
} else if (houseKind.equals("House B")) {
//建造B型房子。
return new HouseB();
} else if (houseKind.equals("House C")) {
//建造C型房子。
return new HouseC();
} else {
return null;
}
}
}简单工厂模式的特点:
工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
但是,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。
匆匆看了下,既然你的Home类方法都是abstract的,干嘛不把Home改成接口呢,这样的话,可能会更好点吧
我改了下,你看看吧~
<code>
public interface Home {
public void Parlor(); //客厅.
public void Bedroom(); //卧室.
public void Kitchen(); //厨房.
public void Toilet(); //卫生间.
}
</code>
<code>
//房地产开发商.
public class Landagent {
public static boolean BuildHouse(Object o) {
if (o instanceof Home)) {
//根据o的方法进行实现
return true;
} else{
return false;
}
}
}
</code>
<code>
//消费者A.
public interface Buyer {
public boolean view(Home home);
}
public class BuyerImpl implements Buyer{
//0-argu default constructor
public boolean view(Home home,Object o){
if(o instanceof Home){
home=o;
//利用反射机制遍历方法
}else{
return false;
}
}
}
public class Test(){
public static void main(String[] args){
Buyer buyer=new BuyerImpl();
Home houseA=new HouseA();
buyer.view(houseA,new HouseA());
}
}
public abstract class Home {
//客厅.
public abstract void Parlor();
//卧室.
public abstract void Bedroom();
//厨房.
public abstract void Kitchen();
//卫生间.
public abstract void Toilet();
}
回chenniaoc:
其实经验很简单,就是持之以恒。
之所以能这么快就到一级水平,主要就是每天都坚持练习听力,每天都坚持记忆单词和语法。平日在工作的时候多加运用,尽可能的不用翻译。只要能做到持之以恒,就一定回有收获。
To luhaixun:
"在国内一家知名的公司从事对日外包工作”意思是由于外包的性质,很少能在实际工作中去运用设计模式。这些感悟都是在工作至于自己学习和思考的,如有不对的地方,虚心接受指正。“既然你的Home类方法都是abstract的,干嘛不把Home改成接口呢”
我的理解是接口是一种“has-a”的关系,而抽象类是“is-a”的关系,所有居住的房屋都应该是“家”这个抽象概念的一种。
如果理解的不正确,请指正,虚心聆听!
接口是一种“has-a”的关系,而抽象类是“is-a”的关系,我没有说你理解有什么问题,我的意思是如果把Home定义成interface的话,如果有新的房型,那么你的主程序就不需要修改了,只要添加一个实现Home接口的类就行了
如果理解的不正确,请指正,虚心聆听!
应该都是"is-a"吧,如果是聚合的话才是"has-a"
“额,问一下"在国内一家知名的公司从事对日外包工作”是想了解一下LZ的情况,没有别的意思,如有什么误会的地方,虚心接受指正。”---没有什么误会,呵呵。“接口是一种“has-a”的关系,而抽象类是“is-a”的关系,我没有说你理解有什么问题,我的意思是如果把Home定义成interface的话,如果有新的房型,那么你的主程序就不需要修改了,只要添加一个实现Home接口的类就行了 ”---仔细看了你的代码。觉得你说的很有道理,向你学习!今后也请多多指正!
我今年也要考二级.大概去年九月还是十月开始学的挺担心挂的..没LZ那么厉害哈...努力ING.
我们公司也基本做对日的...我新人.没做过东西还..感觉LZ蛮行.学习.
LZ好客气呀,一起学习的说~
dingxw92:
我在一本书上看到过这样的说法“继承,就是“is-a”的关系,而接口则是“has-a”的关系。”
我再仔细调查一下,之后再和dingxw92探讨。
To xujiaxiang:
其实大家只要能坚持到底,都能做到。