軟件開發(fā)是一項(xiàng)復(fù)雜的系統(tǒng)工程,隨著時間的演進(jìn),復(fù)雜度會自然的增長。
如果想要避免系統(tǒng)內(nèi)熵的過快增長,就需要我們在研發(fā)過程中,刻意的做減法,來保持系統(tǒng)的簡單性和可靠性。
KISS原則就是一條可讓系統(tǒng)保持簡單的行動指導(dǎo)原則。
那什么是KISS原則呢?下面我們具體看看吧。
Part1什么是KISS原則
KISS原則指的是“保持簡單原則”(Keep It Simple, Stupid)。
“保持簡單”是指在設(shè)計(jì)、開發(fā)、實(shí)現(xiàn)和管理過程中,應(yīng)該采用簡單的方法和策略來解決問題,以便更容易理解、實(shí)現(xiàn)、維護(hù)和使用。
KISS原則的基本思想是:在設(shè)計(jì)或解決問題時,應(yīng)該盡可能地簡化,不要過度復(fù)雜化。 這是因?yàn)楹唵蔚慕鉀Q方案通常更可靠,更易于理解和維護(hù),并且更具可擴(kuò)展性。
這個原則最初用于設(shè)計(jì)和工程領(lǐng)域,但現(xiàn)在已經(jīng)成為了一個廣泛應(yīng)用于各種領(lǐng)域的管理和生活原則。
Part2KISS原則的最佳實(shí)踐
以下是KISS原則的最佳實(shí)踐:
避免過度設(shè)計(jì):不要試圖預(yù)測未來可能發(fā)生的情況,只關(guān)注當(dāng)前需求,盡量避免過度設(shè)計(jì)。
盡量簡化代碼:使用簡單的代碼結(jié)構(gòu)和算法,盡可能避免復(fù)雜的嵌套和邏輯。
保持一致性:在代碼中使用統(tǒng)一的命名規(guī)則、代碼格式和注釋,保持代碼風(fēng)格的一致性。
避免重復(fù)代碼:避免在代碼中重復(fù)相同的邏輯,盡量將相同的代碼封裝成方法或類。
提高代碼可讀性:使用有意義的變量名、方法名和注釋,使代碼更容易理解和閱讀。
不要過早地進(jìn)行優(yōu)化:在代碼編寫的早期,不要過早地考慮性能優(yōu)化,盡可能使代碼易于理解和維護(hù)。
保持代碼精簡:避免使用過多的庫和框架,只使用必要的工具和庫,減少代碼的復(fù)雜性和依賴關(guān)系。
總之,遵循KISS原則的這些最佳實(shí)踐建議,是要保持代碼盡可能的簡單、易于理解和容易維護(hù)。
Part3KISS原則的反模式
以下是KISS原則的常見幾個反模式:
過度工程化:過度設(shè)計(jì)和過度開發(fā)會導(dǎo)致代碼復(fù)雜性增加,影響代碼的可讀性和可維護(hù)性。
濫用設(shè)計(jì)模式:使用過多的設(shè)計(jì)模式會導(dǎo)致代碼復(fù)雜性增加,難以理解和維護(hù)。
復(fù)制黏貼代碼:復(fù)制黏貼代碼可能導(dǎo)致代碼重復(fù)和冗余,增加代碼復(fù)雜性,難以維護(hù)。
過早優(yōu)化:在代碼編寫早期過度關(guān)注性能優(yōu)化,可能會影響代碼的可讀性和可維護(hù)性,同時可能導(dǎo)致不必要的代碼復(fù)雜性。
不遵循命名規(guī)范:命名不規(guī)范、不統(tǒng)一的變量和方法名可能會導(dǎo)致代碼難以理解和維護(hù)。
不遵循單一職責(zé)原則:一個類或方法負(fù)責(zé)過多的功能,會導(dǎo)致代碼復(fù)雜性增加,難以理解和維護(hù)。
濫用注釋:過多的注釋可能會導(dǎo)致代碼復(fù)雜性增加,同時也可能難以維護(hù)。
總之,KISS原則的常見反模式都是導(dǎo)致代碼復(fù)雜性增加、難以理解和維護(hù)的原因,應(yīng)該盡可能避免。
Part4一個經(jīng)典反例
以下是一個過度工程化的代碼案例,其違反KISS原則,具體Java代碼如下:
public abstract class AbstractBaseDao<T> implements BaseDao<T> {
private EntityManager entityManager;
private Class<T> entityClass;
public AbstractBaseDao(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected EntityManager getEntityManager() {
if (entityManager == null) {
entityManager = Persistence.createEntityManagerFactory("persistence-unit").createEntityManager();
}
return entityManager;
}
@Override
public T findById(Long id) {
return getEntityManager().find(entityClass, id);
}
@Override
public List<T> findAll() {
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(entityClass);
Root<T> root = criteriaQuery.from(entityClass);
criteriaQuery.select(root);
return getEntityManager().createQuery(criteriaQuery).getResultList();
}
@Override
public void save(T entity) {
getEntityManager().getTransaction().begin();
getEntityManager().persist(entity);
getEntityManager().getTransaction().commit();
}
@Override
public void update(T entity) {
getEntityManager().getTransaction().begin();
getEntityManager().merge(entity);
getEntityManager().getTransaction().commit();
}
@Override
public void delete(T entity) {
getEntityManager().getTransaction().begin();
getEntityManager().remove(entity);
getEntityManager().getTransaction().commit();
}
@Override
public void deleteById(Long id) {
T entity = findById(id);
if (entity != null) {
delete(entity);
}
}
}
public interface BaseDao<T> {
T findById(Long id);
List<T> findAll();
void save(T entity);
void update(T entity);
void delete(T entity);
void deleteById(Long id);
}
public class UserDaoImpl extends AbstractBaseDao<User> implements UserDao {
public UserDaoImpl() {
super(User.class);
}
@Override
public List<User> findByName(String name) {
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class);
Root<User> root = criteriaQuery.from(User.class);
criteriaQuery.select(root);
criteriaQuery.where(criteriaBuilder.equal(root.get("name"), name));
return getEntityManager().createQuery(criteriaQuery).getResultList();
}
}
public interface UserDao extends BaseDao<User> {
List<User> findByName(String name);
}
在這個例子中,實(shí)現(xiàn)了一個通用的 BaseDao 接口和抽象類 AbstractBaseDao,其中 AbstractBaseDao 是一個抽象類,包含了基本的 CRUD 操作,而 UserDaoImpl 是一個具體實(shí)現(xiàn)類,實(shí)現(xiàn)了 UserDao 接口,通過繼承 AbstractBaseDao 來實(shí)現(xiàn)對 User 對象的數(shù)據(jù)操作。
雖然這種方式可以實(shí)現(xiàn)基本的數(shù)據(jù)操作,但是通過抽象類和接口的方式,增加了代碼的復(fù)雜性和抽象程度,代碼中的 EntityManager、CriteriaBuilder 等 API 的使用也增加了代碼的復(fù)雜性。這種過度工程化的代碼實(shí)現(xiàn)方式會導(dǎo)致代碼不易于理解和維護(hù),同時增加了開發(fā)時間和成本。
如何改進(jìn)以上代碼呢?
為了符合 KISS 原則,可以對以上代碼進(jìn)行簡化和改進(jìn),以下是改進(jìn)后的 Java 代碼:
public class UserDao {
private EntityManager entityManager;
public UserDao(EntityManager entityManager) {
this.entityManager = entityManager;
}
public User findById(Long id) {
return entityManager.find(User.class, id);
}
public List<User> findAll() {
String jpql = "select u from User u";
TypedQuery<User> query = entityManager.createQuery(jpql, User.class);
return query.getResultList();
}
public void save(User user) {
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
}
public void update(User user) {
entityManager.getTransaction().begin();
entityManager.merge(user);
entityManager.getTransaction().commit();
}
public void delete(User user) {
entityManager.getTransaction().begin();
entityManager.remove(user);
entityManager.getTransaction().commit();
}
public void deleteById(Long id) {
User user = findById(id);
if (user != null) {
delete(user);
}
}
public List<User> findByName(String name) {
String jpql = "select u from User u where u.name = :name";
TypedQuery<User> query = entityManager.createQuery(jpql, User.class);
query.setParameter("name", name);
return query.getResultList();
}
}
在這個例子中,我們?nèi)サ袅顺橄箢惡徒涌诘膶哟危瑢?UserDao 定義為一個具體的類,其中包含了所有 User 對象的數(shù)據(jù)操作,同時去掉了 CriteriaBuilder 等 API 的使用,簡化了代碼的復(fù)雜性。
同時,我們將 EntityManager 對象通過構(gòu)造函數(shù)傳入 UserDao 中,這樣可以更靈活地管理 EntityManager 對象的生命周期,避免在每個方法中都創(chuàng)建 EntityManager 對象。在每個數(shù)據(jù)操作方法中,我們也盡量避免了使用過多的 JPA API,采用了更簡潔的 JPQL 語句來完成數(shù)據(jù)操作。
這樣的代碼更易于理解和維護(hù),同時也減少了代碼的復(fù)雜性,更符合 KISS 原則。
Part5最后
以上,是關(guān)于KISS原則的意義,最佳實(shí)踐經(jīng)驗(yàn)和常見反模式的簡單的總結(jié),希望對你有所啟發(fā)或幫助。
KISS原則不僅僅是一條軟件設(shè)計(jì)的指導(dǎo)原則,其也同樣使用于我們的生活和工作中。保持簡單,不要有太多的技巧,可能是做事最高效和最有效的方法。
將事情做復(fù)雜是一個自然的過程,而將復(fù)雜的事情做簡單,則是一項(xiàng)關(guān)鍵的能力。
保持簡單,是一個熵減的過程。
該文章在 2023/7/12 8:56:09 編輯過