有一個班4個學生,5門課程 1求第1門課程的平均分; 2找出有兩門以上課程不及格的學生,輸出他們的學號和全部課程成績及平均成績; 3找出平均成績在90分以上或全部課程成績在85分以上的學生。4分別編3個函式實現以上3個要求。
目錄
基本介紹
- 工廠模式:屬於建立模式的一種,仔細劃分的話,工廠模式大致分為三種,簡單工廠模式、工廠方法模式以及抽象工廠模式。
- 主要作用:建立物件時避免客戶端直接暴露建立邏輯(解耦),而是通過一個公共的介面去建立物件。
- 優點:①. 擴充套件性好,想增加產品,只要擴充套件相應工廠類即可。(也是缺點)②. 遮蔽產品的具體實現細節
簡單工廠模式
基於上圖說的場景,我們瞭解所有的英雄和英雄面板都可以被購買,那麼我們先定義一個介面讓所有英雄和英雄面板遵循這個規則
public interface Hero { /** * 成功購買英雄 */ void buyHeroSuccess(); /** * 成功購買配套面板 */ void buySkinSuccess(); }
那麼接下來我們開始定義不同的英雄,這裡我們分別選 妲己、程咬金、后羿 作為示例
/**
* 妲己
*/
public class DaJi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-妲己!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了面板-熱情桑巴");
}
}
/** * 程咬金 */ public class ChengYaoJin implements Hero { @Override public void buyHeroSuccess() { System.out.println("勇士,恭喜你獲得了英雄-程咬金!"); } @Override public void buySkinSuccess() { System.out.println("恭喜你獲得了面板-愛與正義"); } }
/**
* 后羿
*/
public class HouYi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-后羿!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了面板-黃金射手座");
}
}
上面我們一下子就定義了三個英雄,下面就可以開始簡單工廠的核心了-工廠
既然是工廠模式,那麼生產產品的時候(即建立類),由工廠統一管理,我們通過標籤去決定生產什麼樣的產品
/**
* 王者榮耀工廠(商城)
*/
public class HerosFactory {
/**
* 根據不同的標籤生產不同的英雄
*/
public Hero getDifferentHero(String heroType) {
if("HouYi".equals(heroType)){
return new HouYi();
}else if("DaJi".equals(heroType)){
return new DaJi();
}else if("ChengYaoJin".equals(heroType)){
return new ChengYaoJin();
}
return null;
}
}
寫完了簡單工廠的工廠類,我們可以寫個測試方法測試一下
/**
* 測試方法
*/
public class TestFactory {
public static void main(String[] args) {
HerosFactory herosFactory = new HerosFactory();
Hero hero1 = herosFactory.getDifferentHero("DaJi");
hero1.buyHeroSuccess();
hero1.buySkinSuccess();
System.out.println("-----------------");
Hero hero2 = herosFactory.getDifferentHero("HouYi");
hero2.buyHeroSuccess();
hero2.buySkinSuccess();
}
}
工廠方法模式
我個人認為工廠方法模式是簡單工廠模式的升級,我們先想想簡單工廠模式最大的缺點是啥?
如果我想新增一個物件,那麼我就需要擴充套件工廠類,即我需要去改工廠類的生產方法程式碼去增加一個標籤
這麼幹,實際違背了 開閉原則-對外擴充套件開放,對內修改關閉
比較好的方案是什麼呢?
再定義一個抽象的工廠型別的基類,讓子類去實現該基類(也就是工廠與例項物件遙相呼應),可能這麼說,還是有人不明白,上程式碼
首先英雄介面部分還是和簡單工廠一致
public interface Hero {
/**
* 成功購買英雄
*/
void buyHeroSuccess();
/**
* 成功購買配套面板
*/
void buySkinSuccess();
}
接著我們是已購買三個英雄,妲己、程咬金、后羿
/**
* 妲己
*/
public class DaJi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-妲己!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了面板-熱情桑巴");
}
}
/**
* 程咬金
*/
public class ChengYaoJin implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-程咬金!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了面板-愛與正義");
}
}
/**
* 后羿
*/
public class HouYi implements Hero {
@Override
public void buyHeroSuccess() {
System.out.println("勇士,恭喜你獲得了英雄-后羿!");
}
@Override
public void buySkinSuccess() {
System.out.println("恭喜你獲得了面板-黃金射手座");
}
}
上述程式碼都是和簡單工廠部分一致,針對我們說的問題,我們說 定義一個抽象的工廠型別的基類
/**
* 工廠方法模式:(王者榮耀商城)
*/
public abstract class HeroFactory {
protected abstract Hero productHero();
}
我們已經看到了,基類的抽象方法可以建立英雄,那麼需要建立的子類工廠通過繼承該基類就可以完成建立所需英雄的功能了
/**
* 定義一個射手英雄工廠
*/
public class ArrowFactory extends HeroFactory{
@Override
protected Hero productHero() {
return new HouYi();
}
}
/**
* 法師工廠
*/
public class MageFactory extends HeroFactory{
@Override
protected Hero productHero() {
return new DaJi();
}
}
/**
* 坦克工廠
*/
public class TanksFactory extends HeroFactory{
@Override
protected Hero productHero() {
return new ChengYaoJin();
}
}
定義完三個工廠,我們再次進行測試
/**
* 測試工廠方法模式
*/
public class TestFatcoryMethod {
public static void main(String[] args) {
Hero hero1 = new ArrowFactory().productHero();
hero1.buyHeroSuccess();
hero1.buySkinSuccess();
System.out.println("------------");
Hero hero2 = new MageFactory().productHero();
hero2.buyHeroSuccess();
hero2.buySkinSuccess();
}
}
抽象工廠模式
抽象工廠模式是所有形態的工廠模式中最為抽象和最具一般性的一種形態模式。(不然怎麼叫抽象工廠)
其次抽象工廠是指當有多個抽象角色,使用一種工廠模式。抽象工廠可以向提供一個介面,使客戶端在不指定產品的具體情況下,建立多個產品族中的物件。一個抽象工廠類,可以派生多個具體工廠類,每個具體的工廠類可以建立多個產品的例項。
工廠方法模式 是對 一個產品型別進行構建,而抽象工廠則針對的 是 多個產品型別的構建。
下面我們用程式碼去演繹抽象工廠模式:
之前說過王者榮耀商城中,可以買英雄和面板。按照面向物件的思想我們可以將英雄 和 面板 單獨抽取,成為最頂層的介面。那麼會有下面的程式碼:
//英雄的頂層介面
public interface Hero {
void haveHero();
}
定義完第一個抽象角色,也就是英雄的頂層介面,接下來我們定義具體的實現
/**
* 妲己
*/
public class DaJiHero implements Hero {
@Override
public void haveHero() {
System.out.println("勇士,恭喜你已獲得-妲己");
}
}
/**
* 程咬金
*/
public class ChengYaoJinHero implements Hero {
@Override
public void haveHero() {
System.out.println("勇士,恭喜你已獲得-程咬金");
}
}
/**
* 后羿
*/
public class HouYiHero implements Hero {
@Override
public void haveHero() {
System.out.println("勇士,恭喜你獲得了英雄-后羿");
}
}
我們知道英雄還有面板,所以我們定義第二個抽象角色,即面板的頂層介面
/**
* 面板
*/
public interface Skin {
void haveSkin();
}
接著定義面板介面的實現類
/**
* 妲己面板
*/
public class DaJiSkin implements Skin{
@Override
public void haveSkin() {
System.out.println("恭喜你獲得了面板-熱情桑巴");
}
}
/**
* 程咬金面板
*/
public class ChengYaoJinSkin implements Skin {
@Override
public void haveSkin() {
System.out.println("恭喜你獲得了面板-愛與正義");
}
}
/**
* 后羿面板
*/
public class HouYiSkin implements Skin{
@Override
public void haveSkin() {
System.out.println("恭喜你獲得了面板-黃金射手座");
}
}
根據上面的概念,我們定義完了2個抽象角色,那麼還需定義一個抽象工廠。可能你會問為什麼要定義一個抽象工廠,因為上面的概念也說到了定義抽象工廠的目的就是為了派生具體的工廠類(也就是讓子類去實現)。這個抽象工廠類加上abstract 關鍵字後,又該如何去寫內部的邏輯,我想這一塊才是最需要思考和解決的問題。
/**
* 商品工廠(頂層多型介面 )
*/
public interface MarketFactory {
}
/**
* 英雄抽象工廠
*/
public abstract class HeroAbStractFactory implements MarketFactory {
public abstract Hero getHero(String heroType);
}
/**
* 面板抽象工廠
*/
public abstract class SkinAbStractFactory implements MarketFactory {
public abstract Skin getSkin(String skinType);
}
定義完抽象工廠,我們實現兩個工廠
/**
* 英雄工廠
*/
public class HeroFactory extends HeroAbStractFactory {
@Override
public Hero getHero(String heroType) {
if("HouYi".equals(heroType)){
return new HouYiHero();
}else if("DaJi".equals(heroType)){
return new DaJiHero();
}else if("ChengYaoJin".equals(heroType)){
return new ChengYaoJinHero();
}
return null;
}
}
/**
* 面板工廠
*/
public class SkinFactory extends SkinAbStractFactory {
@Override
public Skin getSkin(String skinType) {
if("HouYi".equals(skinType)){
return new HouYiSkin();
}else if("DaJi".equals(skinType)){
return new DaJiSkin();
}else if("ChengYaoJin".equals(skinType)){
return new ChengYaoJinSkin();
}
return null;
}
}
那麼,我們已經定義完具體的例項工廠,一個是英雄工廠,一個是面板工廠,現在可以定義一個統一管理類管理這兩個工廠
/**
* 工廠(商城)
*/
public class FactoryProduct {
public static MarketFactory getFactoryByType(String factoryType){
if("HeroFactory".equals(factoryType)){
return new HeroFactory();
}else if("SkinFactory".equals(factoryType)){
return new SkinFactory();
}
return null;
}
}
最後我們開始測試
/**
* 工廠測試
*/
public class TestFactory {
public static void main(String[] args) {
HeroFactory heroFactory = (HeroFactory) FactoryProduct.getFactoryByType("HeroFactory");
Hero hero = heroFactory.getHero("ChengYaoJin");
hero.haveHero();
SkinFactory skinFactory = (SkinFactory) FactoryProduct.getFactoryByType("SkinFactory");
Skin skin = skinFactory.getSkin("ChengYaoJin");
skin.haveSkin();
}
}