الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

هل تفكيري Oop صحيح

بدأه Final Heaven في 10 مارس 2009 · 5 رد · 1,086 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

عندما نقوم بتصميم Objects ل database tables

كمثال جدول الموظفين و جدول المنطقة

public abstract class Common{
	 protected int id;
	 public int getId(){
		  return id;
	 }
	 public void setId(int id){
		  this.id = id;
	 }
	 public boolean insertToDb();
	 public boolean updateToDb();
	 public boolean deleteFromDb();
}

public class Employee extends Common{
	  private String name;
	  private int age;

	  public Employee(int id){
			 this.id = id;
	  }

	  public String getName(){
			 return name;
	  }
	  public void setName(String name){
			 this.name = name;
	  }
	  public int getAge(){
			 return age;
	  }
	  public void setAge(int age){
			 this.age=age;
	   }
	  //********************************************************************************
***********************************
	  public static List<Employee> getList(){
			// you code to get a list of employees here
	  }
	   //********************************************************************************
************************************
	  public boolean insertToDb(){}
	 public boolean updateToDb(){}
	 public boolean deleteFromDb(){}
}

public class Region extends Common{
	  private String name;
	  public Region(int id){
			 this.id = id;
	   }
	   public String getName(){
			  return name;
	  }

	 public void setName(String name){
			 this.name = name;
	  }
	   //********************************************************************************
***********************************
	  public static List<Region> getList(){
			  // you code is here
	  }
	   //********************************************************************************
***********************************
	  public boolean insertToDb(){}
	 public boolean updateToDb(){}
	 public boolean deleteFromDb(){}
}

و هنا هل تفكيري صحيح بالنسبة لوضع getList

في الشيئين Employee و Region

أوَ ليْسَتْ Common Behavior

و لكنها لا تعتمد على Object Employee لأنها ليست مثل insertToDb و غيرها تحتاج Object لتفعيلها لإعتمادها على variables

و أما getList فإنها تستقل عن Object Employee

و عندما تكون static لا أقدر على وضعها في Object Common

لتصبح Common Behavior

و لكن هل أحتاج لدى كل نداء لها لإنشاء object جديد كي اتمكن من وضعها ك Common Behavior

//Which is Right and Better?
//1- Static Use:
Employee.getList();

//2- Behavior use:
Employee e= new Employee();
e.getList()

و لذا و كما ترون كي أصمم getList ك Common Behavior لأنني أمنع لدى إستخدامي ل static

علي أن أنشئ object جديد لدي كل إستخدام فهل الحل الوحيد كي تكون Common Behavior

أن أقوم بإنشاء object جديد في كل مرة؟

و كن فتى في ذرى العلياء همّته

يسمو بغاياته حتى على زحل

موقع خاص بي

My Website

قمت بتصميم لعبة بسيطة بإستخدام اللغة الجميلة الجافا

Plane Fighter Game

برنامج جميل بلغة الجافا يساعد على تنظيم المشاكل

The TS Organizer

#2

على ما يبدو انتا محتار في عدد الـ objects الذي ستصنعه لكل موظف يحمل ID معين

بالبداية كتصميم اولي للفكرة جيد .. لكن لماذا استخدمت كلاس مجرد ولم تستخدم interfac مثلا

بالنسبة لـ getList .. اتوقع عند استدعاها ستقوم بعرض كافة الموظفين مع معلومات الحقول .. اما انا مخطا

طيب اذا فعلا كانت هكذا اذا انتا لا تحتاج لمؤشرات على كل سجل موظف .. بل تحتاج لطريقة تستدعي كل هذا بالتالي تتخلص من صناعة الكائنات

واذا كنت تقصد بال getList ان تاتي لك بسجل موظف واحد يحدد من خلال شرط معين .. فلا اتوقع بان هناك طريقة تغنيك عن الكائن ليساعدك على الاستدعاء

لا ادري اذا تساعد العملية التي تقوم بها بالشكل المطلوب .. لكن مثلا لو تقوم بالاطلاع على ما يسمى الفهرسة ..قد توفر عليك اشياء كثيرة بالـ data base

وهي اصلا مستخدمة في جميع قواعد البيانات في وقت البرمحة ..في تساعد في استدعاء الجدول بسهول او السجل

بالتوفيق

الله معك ..

#3

وعليكم السلام ورحمه الله وبركاته ،،

ما رأيك بفصل جزئيه التعامل مع القاعده عن جزئيه الكائنات ؟ ﻷن لكل منهم وظيفه معينه ، وعند تصميمك للكلاسات يفضل جعل كل منها لديه وظيفه محدده ،، بمعني يكون لديك Employee تمثل العميل فقط -بياناته ودوال Setter&Getter- وأيضا Region وتمثل معلومات المنطقه فقط ، ثم بعد ذلك يكون لديك الجزء المسؤول عن الحفظ وليكن اسمه DataBase

ويمكن أن يكون بالشكل :

class DataBase {
public void insertEmployee(Employee e);
public void insertRegion(Region r);

public List<Employee> getEmployee();
public List<Region> getRegion();
}

وفي الداله الرئيسيه /

Employee e = new Employee();
// 
DataBase db = new DataBase();
//
db.insertEmployee(e);
//
List<Employee> l = db.getEmployee();

هكذا ستكون العمليه أكثر منطقيه ، حيث أنك تدخل البيانات للقاعده ، وعند الحاجه لها تقوم بأخذها منها أيضا ، ويمكن حينها أن تجعل الداله static :

List<Employee> list = DataBase.getEmployee();

أو لا تجعلها ، فهذا أم عائد لتصميمك ، فمثلا لو كانت داله البناء في DataBase تقوم بالأتصال مع القاعده ، فبالتالى يجب أن تقوم بعمل كائن من الكلاس أولا حتى يتم الاتصال ،،

بالتوفيق :) .

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#4

مغزى السؤال هو كيف السعي إلى أفضل تصميم OOP

و إليكم أسلوب تفكيري من خلال هذا التصميم:

public class DBManager {
	private static Connection connection;

	public static <T extends DBCommon>List<T> getList(Class<T> c, String sql) {
		List<T> list = null;

		try {
			ResultSet resultSet = connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE,
									  ResultSet.CONCUR_READ_ONLY).executeQuery();

			resultSet.last();
			list = new ArrayList<T>(resultSet.getRow());
			resultSet.beforeFirst();

			while (resultSet.next()) {
				T object = c.newInstance();

				object.fill(resultSet);
				list.add(object);
				object = null;
			}

			resultSet = null;
		}
		catch (InstantiationException ex) {
			Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		catch (IllegalAccessException ex) {
			Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
		}
		catch (SQLException ex) {
			Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
		}

		return list;
	}
}

public abstract class DBCommon {
	protected Connection		connection;
	protected Long			  id;
	protected PreparedStatement preparedDelete;
	protected PreparedStatement preparedInsert;
	protected PreparedStatement preparedSelect;
	protected PreparedStatement preparedUpdate;

	//~--- constructors -------------------------------------------------------

	public DBCommon() {
		connection = DBManager.getConnection();
		createStatements();
	}

	//~--- methods ------------------------------------------------------------

	public abstract void fill(ResultSet result);

	public void fullFill(ResultSet result) {
		fill(result);
		setRelated();
	}

	public boolean insertToDB() {
		return executeInsert();
	}

	public boolean deleteFromDB() {
		return deleteFromDB(id);
	}

	public boolean updateToDB() {
		return executeUpdate();
	}

	protected boolean executeUpdate() {
		try {
			setPreparedUpdate();
			preparedUpdate.executeUpdate();
			preparedUpdate.clearParameters();

			return true;
		}
		catch (SQLException ex) {
			Logger.getLogger(DBCommon.class.getName()).log(Level.SEVERE, null, ex);
		}

		return false;
	}

	protected boolean executeInsert() {
		id = -1l;

		try {
			setPreparedInsert();
			preparedInsert.executeUpdate();

			ResultSet generatedID = preparedInsert.getGeneratedKeys();

			if (generatedID.next()) {
				id		  = generatedID.getLong(1);
				generatedID = null;
				preparedInsert.clearParameters();
			}
		}
		catch (SQLException ex) {
			Logger.getLogger(DBCommon.class.getName()).log(Level.SEVERE, null, ex);
			id = -1l;
		}

		return id != -1;
	}

	public boolean selectFromDB(long id) {
		try {
			preparedSelect.setLong(1, id);

			ResultSet result = preparedSelect.executeQuery();

			if (result.next()) {
				fill(result);
			}

			result = null;
			preparedSelect.clearParameters();

			return true;
		}
		catch (SQLException ex) {
			Logger.getLogger(DBCommon.class.getName()).log(Level.SEVERE, null, ex);
		}

		return false;
	}

	public void fullSelectFromDB(long id) {
		selectFromDB(id);
		setRelated();
	}

	protected abstract void createStatements();

	protected void createPreparedStatements(String insert, String update, String delete, String select) {
		try {
			preparedInsert = connection.prepareStatement(insert, PreparedStatement.RETURN_GENERATED_KEYS);
			preparedUpdate = connection.prepareStatement(update);
			preparedDelete = connection.prepareStatement(delete);
			preparedSelect = connection.prepareStatement(select);
		}
		catch (SQLException ex) {
			Logger.getLogger(DBCommon.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

	protected boolean deleteFromDB(long id) {
		try {
			preparedDelete.setLong(1, id);
			preparedDelete.executeUpdate();
			preparedDelete.clearParameters();

			return true;
		}
		catch (SQLException ex) {
			Logger.getLogger(DBCommon.class.getName()).log(Level.SEVERE, null, ex);
		}

		return false;
	}

	//~--- get methods --------------------------------------------------------

	public Long getId() {
		return id;
	}

	//~--- set methods --------------------------------------------------------

	public void setId(Long id) {
		this.id = id;
	}

	protected abstract void setPreparedUpdate() throws SQLException;

	protected abstract void setPreparedInsert() throws SQLException;

	protected abstract void setRelated();
}

public class Region extends DBCommon implements Serializable {
	private static final long serialVersionUID = 1L;

	//~--- fields -------------------------------------------------------------

	private String			 name;
	private List<FatehStudent> fatehStudentList;

	//~--- constructors -------------------------------------------------------

	public Region() {}

	public Region(Long id) {
		this.id = id;
	}

	public Region(Long id, String name) {
		this.id   = id;
		this.name = name;
	}

	//~--- methods ------------------------------------------------------------

	@Override
	public int hashCode() {
		int hash = 0;

		hash += ((id != null)
				 ? id.hashCode()
				 : 0);

		return hash;
	}

	@Override
	public boolean equals(Object object) {

		// TODO: Warning - this method won't work in the case the id fields are not set
		if (!(object instanceof Region)) {
			return false;
		}

		Region other = (Region) object;

		if (((this.id == null) && (other.id != null)) || ((this.id != null) &&!this.id.equals(other.id))) {
			return false;
		}

		return true;
	}

	@Override
	public String toString() {
		return name;
	}

	@Override
	public void fill(ResultSet result) {
		try {
			id   = result.getLong(1);
			name = result.getString(2);
		}
		catch (SQLException ex) {
			Logger.getLogger(Region.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

	@Override
	protected void createStatements() {
		String insertSql = "INSERT INTO REGION(NAME) VALUES(?)";
		String updateSql = "UPDATE REGION SET NAME = ? WHERE ID = ?";
		String deleteSql = "DELETE FROM REGION WHERE ID = ?";
		String selectSql = "SELECT * FROM REGION WHERE ID = ?";

		createPreparedStatements(insertSql, updateSql, deleteSql, selectSql);
	}

	//~--- get methods --------------------------------------------------------

	public String getName() {
		return name;
	}

	public List<FatehStudent> getFatehStudentList() {
		return fatehStudentList;
	}

	public static List<Region> getRegions() {
		return DBManager.getList(Region.class, "SELECT * FROM REGION");
	}

	//~--- set methods --------------------------------------------------------

	public void setName(String name) {
		this.name = name;
	}

	public void setFatehStudentList(List<FatehStudent> fatehStudentCollection) {
		this.fatehStudentList = fatehStudentCollection;
	}

	@Override
	protected void setPreparedUpdate() throws SQLException {
		preparedUpdate.setString(1, name);
		preparedUpdate.setLong(2, id);
	}

	@Override
	protected void setPreparedInsert() throws SQLException {
		preparedInsert.setString(1, name);
	}

	@Override
	protected void setRelated() {
		throw new UnsupportedOperationException("Not supported yet.");
	}
}

و هنا getRegions هي التي أريد تصميمها ك Common Behavior

و عن طريق تسميتها getList عوضا عن :

getRegions - getEmployees - getStudents

و لكن كيف يكون تصميمي OOP صحيح:

فبإعتمادي على أسلوب static أخسر ميزة CommonBehavior

و بأسلوب Commonbehavior و الذي هو بالإعتماد على abstract DBCommon

يجب علي أن أنشئ أبوجكت جديد في كل مرة أريد إستخدام getList و التي هي getRegions

كل ما كتب في الأعلى هو من تصميمي أتمنى أي تعديل ترونه مناسبا أو فكرة تحسين أكون شاكرا

و أرجو أن أستفيد من الخبرة الموجودة لإيجاد الحل الأنسب للتصميم الذي أسعى إليه

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة Final Heaven في 12 مارس 2009 في 21:55

و كن فتى في ذرى العلياء همّته

يسمو بغاياته حتى على زحل

موقع خاص بي

My Website

قمت بتصميم لعبة بسيطة بإستخدام اللغة الجميلة الجافا

Plane Fighter Game

برنامج جميل بلغة الجافا يساعد على تنظيم المشاكل

The TS Organizer

#5

على فكرة وجدي هذا التصميم قديم قليلاً

الآن حزم قواعد البيانات الكائنية O/R mapping مثل hibernate

تتكلف بموضوع قاعدة البيانات كلياً

على كل حال لحل مشكلتك استخد العموميات Generics

وستكون الدالة موجودة في الفئة Common على النحو التالي

	public abstract List <? extends Common> getList();

عند بناء كل فئة جديدة ترث Common سنقوم بتعريف (?) كما نريد

بالمناسبة أطلت الغياب علينا

لي فترة لم أراك في المنتدى

أتمنى أن يكون المانع خيراً

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#6

ألف شكر لكم يا إخوتي على الردود

و أعتذر عن عدم تواجدي في المنتدى

و سأحاول جاهدا العودة للنشاط من جديد

و كن فتى في ذرى العلياء همّته

يسمو بغاياته حتى على زحل

موقع خاص بي

My Website

قمت بتصميم لعبة بسيطة بإستخدام اللغة الجميلة الجافا

Plane Fighter Game

برنامج جميل بلغة الجافا يساعد على تنظيم المشاكل

The TS Organizer

مواضيع مشابهة